Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1127587) +++ lucene/CHANGES.txt (working copy) @@ -450,6 +450,11 @@ APIs not covered by the strict backwards compatibility policy. (Uwe Schindler, Mike McCandless) +* 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) + Changes in runtime behavior * LUCENE-3065: When a NumericField is retrieved from a Document loaded Index: lucene/src/test/org/apache/lucene/store/TestMultiMMap.java =================================================================== --- lucene/src/test/org/apache/lucene/store/TestMultiMMap.java (revision 1127587) +++ lucene/src/test/org/apache/lucene/store/TestMultiMMap.java (working copy) @@ -51,7 +51,7 @@ } 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.mkdirs(); MMapDirectory dir = new MMapDirectory(path); Index: lucene/src/test/org/apache/lucene/store/TestBufferedIndexInput.java =================================================================== --- lucene/src/test/org/apache/lucene/store/TestBufferedIndexInput.java (revision 1127587) +++ lucene/src/test/org/apache/lucene/store/TestBufferedIndexInput.java (working copy) @@ -87,7 +87,7 @@ // NOTE: this does only test the chunked reads and NOT if the Bug is triggered. //final int tmpFileSize = 1024 * 1024 * 5; final int inputBufferSize = 128; - File tmpInputFile = File.createTempFile("IndexInput", "tmpFile"); + File tmpInputFile = _TestUtil.createTempFile("IndexInput", "tmpFile", TEMP_DIR); tmpInputFile.deleteOnExit(); writeBytes(tmpInputFile, TEST_FILE_LENGTH); Index: lucene/src/java/org/apache/lucene/store/FSDirectory.java =================================================================== --- lucene/src/java/org/apache/lucene/store/FSDirectory.java (revision 1127587) +++ lucene/src/java/org/apache/lucene/store/FSDirectory.java (working copy) @@ -22,8 +22,6 @@ import java.io.FilenameFilter; import java.io.IOException; import java.io.RandomAccessFile; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.util.Collection; import static java.util.Collections.synchronizedSet; @@ -111,16 +109,7 @@ * @see 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 * Integer.MAX_VALUE. @@ -337,12 +326,6 @@ 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 public String getLockID() { ensureOpen(); @@ -353,19 +336,12 @@ throw new RuntimeException(e.toString(), e); } - byte digest[]; - synchronized (DIGESTER) { - digest = DIGESTER.digest(dirName.getBytes()); + int digest = 0; + for(int charIDX=0;charIDX> 4) & 0xf]); - buf.append(HEX_DIGITS[b & 0xf]); - } - - return buf.toString(); + return "lucene-" + Integer.toHexString(digest); } /** Closes the store to future operations. */ Index: lucene/src/java/org/apache/lucene/util/Constants.java =================================================================== --- lucene/src/java/org/apache/lucene/util/Constants.java (revision 1127587) +++ lucene/src/java/org/apache/lucene/util/Constants.java (working copy) @@ -43,6 +43,8 @@ public static final boolean WINDOWS = OS_NAME.startsWith("Windows"); /** True iff running on 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_VERSION = System.getProperty("os.version"); Index: lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java (revision 1127587) +++ lucene/src/test-framework/org/apache/lucene/search/QueryUtils.java (working copy) @@ -1,8 +1,24 @@ 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.util.Random; -import java.lang.reflect.Method; import junit.framework.Assert; @@ -23,21 +39,6 @@ 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. - */ Index: lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java (revision 1127587) +++ lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -1136,7 +1136,7 @@ final Class clazz = Class.forName(clazzName).asSubclass(Directory.class); // If it is a FSDirectory type, try its ctor(File) 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.mkdir(); registerTempFile(tmpFile); Index: lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java =================================================================== --- lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java (revision 1127587) +++ lucene/src/test-framework/org/apache/lucene/util/_TestUtil.java (working copy) @@ -373,4 +373,51 @@ 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()); + } }