LUCENE-2834: don't use MD5 to make lock id for foreign lock file (it spawns thread on OS X)

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1128844 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-05-29 09:21:08 +00:00
parent 3867d1572f
commit f02bbe00b5
8 changed files with 80 additions and 49 deletions

View File

@ -434,7 +434,12 @@ Bug fixes
======================= Lucene 3.x (not yet released) ================ ======================= Lucene 3.x (not yet released) ================
(No changes) Changes in runtime behavior
* LUCENE-2834: the hash used to compute the lock file name when the
lock file is not stored in the index has changed. This means you
will see a different lucene-XXX-write.lock in your lock directory.
(Robert Muir, Uwe Schindler, Mike McCandless)
======================= Lucene 3.2.0 ======================= ======================= Lucene 3.2.0 =======================

View File

@ -22,8 +22,6 @@ import java.io.FileNotFoundException;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection; import java.util.Collection;
import static java.util.Collections.synchronizedSet; import static java.util.Collections.synchronizedSet;
@ -111,15 +109,6 @@ import org.apache.lucene.util.Constants;
* @see Directory * @see Directory
*/ */
public abstract class FSDirectory extends Directory { public abstract class FSDirectory extends Directory {
private final static MessageDigest DIGESTER;
static {
try {
DIGESTER = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.toString(), e);
}
}
/** /**
* Default read chunk size. This is a conditional default: on 32bit JVMs, it defaults to 100 MB. On 64bit JVMs, it's * Default read chunk size. This is a conditional default: on 32bit JVMs, it defaults to 100 MB. On 64bit JVMs, it's
@ -337,12 +326,6 @@ public abstract class FSDirectory extends Directory {
return openInput(name, BufferedIndexInput.BUFFER_SIZE); return openInput(name, BufferedIndexInput.BUFFER_SIZE);
} }
/**
* So we can do some byte-to-hexchar conversion below
*/
private static final char[] HEX_DIGITS =
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
@Override @Override
public String getLockID() { public String getLockID() {
ensureOpen(); ensureOpen();
@ -353,19 +336,12 @@ public abstract class FSDirectory extends Directory {
throw new RuntimeException(e.toString(), e); throw new RuntimeException(e.toString(), e);
} }
byte digest[]; int digest = 0;
synchronized (DIGESTER) { for(int charIDX=0;charIDX<dirName.length();charIDX++) {
digest = DIGESTER.digest(dirName.getBytes()); final char ch = dirName.charAt(charIDX);
digest = 31 * digest + ch;
} }
StringBuilder buf = new StringBuilder(); return "lucene-" + Integer.toHexString(digest);
buf.append("lucene-");
for (int i = 0; i < digest.length; i++) {
int b = digest[i];
buf.append(HEX_DIGITS[(b >> 4) & 0xf]);
buf.append(HEX_DIGITS[b & 0xf]);
}
return buf.toString();
} }
/** Closes the store to future operations. */ /** Closes the store to future operations. */

View File

@ -43,6 +43,8 @@ public final class Constants {
public static final boolean WINDOWS = OS_NAME.startsWith("Windows"); public static final boolean WINDOWS = OS_NAME.startsWith("Windows");
/** True iff running on SunOS. */ /** True iff running on SunOS. */
public static final boolean SUN_OS = OS_NAME.startsWith("SunOS"); public static final boolean SUN_OS = OS_NAME.startsWith("SunOS");
/** True iff running on Mac OS X */
public static final boolean MAC_OS_X = OS_NAME.startsWith("Mac OS X");
public static final String OS_ARCH = System.getProperty("os.arch"); public static final String OS_ARCH = System.getProperty("os.arch");
public static final String OS_VERSION = System.getProperty("os.version"); public static final String OS_VERSION = System.getProperty("os.version");

View File

@ -1,8 +1,24 @@
package org.apache.lucene.search; package org.apache.lucene.search;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException; import java.io.IOException;
import java.util.Random; import java.util.Random;
import java.lang.reflect.Method;
import junit.framework.Assert; import junit.framework.Assert;
@ -23,21 +39,6 @@ import org.apache.lucene.util._TestUtil;
import static org.apache.lucene.util.LuceneTestCase.TEST_VERSION_CURRENT; import static org.apache.lucene.util.LuceneTestCase.TEST_VERSION_CURRENT;
/**
* Copyright 2005 Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

View File

@ -1137,7 +1137,7 @@ public abstract class LuceneTestCase extends Assert {
final Class<? extends Directory> clazz = Class.forName(clazzName).asSubclass(Directory.class); final Class<? extends Directory> clazz = Class.forName(clazzName).asSubclass(Directory.class);
// If it is a FSDirectory type, try its ctor(File) // If it is a FSDirectory type, try its ctor(File)
if (FSDirectory.class.isAssignableFrom(clazz)) { if (FSDirectory.class.isAssignableFrom(clazz)) {
final File tmpFile = File.createTempFile("test", "tmp", TEMP_DIR); final File tmpFile = _TestUtil.createTempFile("test", "tmp", TEMP_DIR);
tmpFile.delete(); tmpFile.delete();
tmpFile.mkdir(); tmpFile.mkdir();
registerTempFile(tmpFile); registerTempFile(tmpFile);

View File

@ -373,4 +373,51 @@ public class _TestUtil {
field.isStoreOffsetWithTermVector(), field.getOmitNorms(), false, field.getOmitTermFreqAndPositions()); field.isStoreOffsetWithTermVector(), field.getOmitNorms(), false, field.getOmitTermFreqAndPositions());
} }
} }
/**
* insecure, fast version of File.createTempFile
* uses Random instead of SecureRandom.
*/
public static File createTempFile(String prefix, String suffix, File directory)
throws IOException {
// Force a prefix null check first
if (prefix.length() < 3) {
throw new IllegalArgumentException("prefix must be 3");
}
String newSuffix = suffix == null ? ".tmp" : suffix;
File result;
do {
result = genTempFile(prefix, newSuffix, directory);
} while (!result.createNewFile());
return result;
}
/* Temp file counter */
private static int counter = 0;
/* identify for differnt VM processes */
private static int counterBase = 0;
private static class TempFileLocker {};
private static TempFileLocker tempFileLocker = new TempFileLocker();
private static File genTempFile(String prefix, String suffix, File directory) {
int identify = 0;
synchronized (tempFileLocker) {
if (counter == 0) {
int newInt = new Random().nextInt();
counter = ((newInt / 65535) & 0xFFFF) + 0x2710;
counterBase = counter;
}
identify = counter++;
}
StringBuilder newName = new StringBuilder();
newName.append(prefix);
newName.append(counterBase);
newName.append(identify);
newName.append(suffix);
return new File(directory, newName.toString());
}
} }

View File

@ -87,7 +87,7 @@ public class TestBufferedIndexInput extends LuceneTestCase {
// NOTE: this does only test the chunked reads and NOT if the Bug is triggered. // NOTE: this does only test the chunked reads and NOT if the Bug is triggered.
//final int tmpFileSize = 1024 * 1024 * 5; //final int tmpFileSize = 1024 * 1024 * 5;
final int inputBufferSize = 128; final int inputBufferSize = 128;
File tmpInputFile = File.createTempFile("IndexInput", "tmpFile"); File tmpInputFile = _TestUtil.createTempFile("IndexInput", "tmpFile", TEMP_DIR);
tmpInputFile.deleteOnExit(); tmpInputFile.deleteOnExit();
writeBytes(tmpInputFile, TEST_FILE_LENGTH); writeBytes(tmpInputFile, TEST_FILE_LENGTH);

View File

@ -51,7 +51,7 @@ public class TestMultiMMap extends LuceneTestCase {
} }
private void assertChunking(Random random, int chunkSize) throws Exception { private void assertChunking(Random random, int chunkSize) throws Exception {
File path = File.createTempFile("mmap" + chunkSize, "tmp", workDir); File path = _TestUtil.createTempFile("mmap" + chunkSize, "tmp", workDir);
path.delete(); path.delete();
path.mkdirs(); path.mkdirs();
MMapDirectory dir = new MMapDirectory(path); MMapDirectory dir = new MMapDirectory(path);