Index: lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java --- lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/contrib/misc/src/test/org/apache/lucene/index/codecs/appending/TestAppendingCodec.java Sun Nov 14 19:37:18 2010 -0500 @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.util.Random; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; @@ -118,8 +119,8 @@ @SuppressWarnings("serial") private static class AppendingRAMDirectory extends MockDirectoryWrapper { - public AppendingRAMDirectory(Directory delegate) { - super(delegate); + public AppendingRAMDirectory(Random random, Directory delegate) { + super(random, delegate); } @Override @@ -132,7 +133,7 @@ private static final String text = "the quick brown fox jumped over the lazy dog"; public void testCodec() throws Exception { - Directory dir = new AppendingRAMDirectory(new RAMDirectory()); + Directory dir = new AppendingRAMDirectory(random, new RAMDirectory()); IndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer()); cfg.setCodecProvider(new AppendingCodecProvider()); Index: lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java --- lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/SingleFieldTestDb.java Sun Nov 14 19:37:18 2010 -0500 @@ -17,6 +17,8 @@ * limitations under the License. */ +import java.util.Random; + import org.apache.lucene.store.Directory; import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.store.RAMDirectory; @@ -32,9 +34,9 @@ private String[] docs; private String fieldName; - public SingleFieldTestDb(String[] documents, String fName) { + public SingleFieldTestDb(Random random, String[] documents, String fName) { try { - db = new MockDirectoryWrapper(new RAMDirectory()); + db = new MockDirectoryWrapper(random, new RAMDirectory()); docs = documents; fieldName = fName; IndexWriter writer = new IndexWriter(db, new IndexWriterConfig( Index: lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java --- lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test02Boolean.java Sun Nov 14 19:37:18 2010 -0500 @@ -39,7 +39,7 @@ "a c e a b c" }; - SingleFieldTestDb db1 = new SingleFieldTestDb(docs1, fieldName); + SingleFieldTestDb db1 = new SingleFieldTestDb(random, docs1, fieldName); public void normalTest1(String query, int[] expdnrs) throws Exception { BooleanQueryTst bqt = new BooleanQueryTst( query, expdnrs, db1, fieldName, this, Index: lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java --- lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/Test03Distance.java Sun Nov 14 19:37:18 2010 -0500 @@ -58,7 +58,7 @@ "a c e a b c" }; - SingleFieldTestDb db1 = new SingleFieldTestDb(docs1, fieldName); + SingleFieldTestDb db1 = new SingleFieldTestDb(random, docs1, fieldName); private void distanceTst(String query, int[] expdnrs, SingleFieldTestDb db) throws Exception { BooleanQueryTst bqt = new BooleanQueryTst( query, expdnrs, db, fieldName, this, @@ -179,7 +179,7 @@ "" }; - SingleFieldTestDb db2 = new SingleFieldTestDb(docs2, fieldName); + SingleFieldTestDb db2 = new SingleFieldTestDb(random, docs2, fieldName); public void distanceTest2(String query, int[] expdnrs) throws Exception { distanceTst(query, expdnrs, db2); @@ -227,7 +227,7 @@ "" }; - SingleFieldTestDb db3 = new SingleFieldTestDb(docs3, fieldName); + SingleFieldTestDb db3 = new SingleFieldTestDb(random, docs3, fieldName); public void distanceTest3(String query, int[] expdnrs) throws Exception { distanceTst(query, expdnrs, db3); Index: lucene/src/java/org/apache/lucene/index/IndexWriter.java --- lucene/src/java/org/apache/lucene/index/IndexWriter.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/java/org/apache/lucene/index/IndexWriter.java Sun Nov 14 19:37:18 2010 -0500 @@ -286,6 +286,7 @@ private IndexFileDeleter deleter; private Set segmentsToOptimize = new HashSet(); // used by optimize to note those needing optimization + private int optimizeMaxNumSegments; private Lock writeLock; @@ -2379,6 +2380,7 @@ synchronized(this) { resetMergeExceptions(); segmentsToOptimize = new HashSet(segmentInfos); + optimizeMaxNumSegments = maxNumSegments; // Now mark all pending & running merges as optimize // merge: @@ -2579,8 +2581,9 @@ throws CorruptIndexException, IOException { assert !optimize || maxNumSegmentsOptimize > 0; - if (stopMerges) + if (stopMerges) { return; + } // Do not start new merges if we've hit OOME if (hitOOM) { @@ -2594,19 +2597,21 @@ if (spec != null) { final int numMerges = spec.merges.size(); for(int i=0;i(); } - public MockDirectoryWrapper(Directory delegate) { + public MockDirectoryWrapper(Random random, Directory delegate) { this.delegate = delegate; + this.randomState = random; init(); } @@ -96,6 +97,7 @@ @Deprecated @Override public void sync(String name) throws IOException { + maybeYield(); maybeThrowDeterministicException(); if (crashed) throw new IOException("cannot sync after crash"); @@ -105,6 +107,7 @@ @Override public synchronized void sync(Collection names) throws IOException { + maybeYield(); for (String name : names) maybeThrowDeterministicException(); if (crashed) @@ -115,6 +118,7 @@ @Override public String toString() { + maybeYield(); return "MockDirWrapper(" + delegate + ")"; } @@ -213,10 +217,8 @@ * IOException on the first write to an OutputStream based * on this probability. */ - public void setRandomIOExceptionRate(double rate, long seed) { + public void setRandomIOExceptionRate(double rate) { randomIOExceptionRate = rate; - // seed so we have deterministic behaviour: - randomState = new Random(seed); } public double getRandomIOExceptionRate() { return randomIOExceptionRate; @@ -233,6 +235,7 @@ @Override public synchronized void deleteFile(String name) throws IOException { + maybeYield(); deleteFile(name, false); } @@ -251,7 +254,14 @@ return ioe; } + private void maybeYield() { + if (randomState.nextBoolean()) { + Thread.yield(); + } + } + private synchronized void deleteFile(String name, boolean forced) throws IOException { + maybeYield(); maybeThrowDeterministicException(); @@ -277,6 +287,7 @@ @Override public synchronized IndexOutput createOutput(String name) throws IOException { + maybeYield(); if (crashed) throw new IOException("cannot createOutput after crash"); init(); @@ -317,6 +328,7 @@ @Override public synchronized IndexInput openInput(String name) throws IOException { + maybeYield(); if (!delegate.fileExists(name)) throw new FileNotFoundException(name); @@ -367,6 +379,7 @@ @Override public synchronized void close() throws IOException { + maybeYield(); if (openFiles == null) { openFiles = new HashMap(); openFilesDeleted = new HashSet(); @@ -456,56 +469,67 @@ @Override public synchronized String[] listAll() throws IOException { + maybeYield(); return delegate.listAll(); } @Override public synchronized boolean fileExists(String name) throws IOException { + maybeYield(); return delegate.fileExists(name); } @Override public synchronized long fileModified(String name) throws IOException { + maybeYield(); return delegate.fileModified(name); } @Override public synchronized void touchFile(String name) throws IOException { + maybeYield(); delegate.touchFile(name); } @Override public synchronized long fileLength(String name) throws IOException { + maybeYield(); return delegate.fileLength(name); } @Override public synchronized Lock makeLock(String name) { + maybeYield(); return delegate.makeLock(name); } @Override public synchronized void clearLock(String name) throws IOException { + maybeYield(); delegate.clearLock(name); } @Override public synchronized void setLockFactory(LockFactory lockFactory) { + maybeYield(); delegate.setLockFactory(lockFactory); } @Override public synchronized LockFactory getLockFactory() { + maybeYield(); return delegate.getLockFactory(); } @Override public synchronized String getLockID() { + maybeYield(); return delegate.getLockID(); } @Override public synchronized void copy(Directory to, String src, String dest) throws IOException { + maybeYield(); delegate.copy(to, src, dest); } } Index: lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java --- lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java Sun Nov 14 19:37:18 2010 -0500 @@ -40,8 +40,8 @@ fileExtensions.add(IndexFileNames.FIELDS_EXTENSION); fileExtensions.add(IndexFileNames.FIELDS_INDEX_EXTENSION); - Directory primaryDir = new MockDirectoryWrapper(new RAMDirectory()); - Directory secondaryDir = new MockDirectoryWrapper(new RAMDirectory()); + Directory primaryDir = new MockDirectoryWrapper(random, new RAMDirectory()); + Directory secondaryDir = new MockDirectoryWrapper(random, new RAMDirectory()); FileSwitchDirectory fsd = new FileSwitchDirectory(fileExtensions, primaryDir, secondaryDir, true); IndexWriter writer = new IndexWriter(fsd, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer())); Index: lucene/src/test/org/apache/lucene/store/TestLockFactory.java --- lucene/src/test/org/apache/lucene/store/TestLockFactory.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/test/org/apache/lucene/store/TestLockFactory.java Sun Nov 14 19:37:18 2010 -0500 @@ -42,7 +42,7 @@ // methods are called at the right time, locks are created, etc. public void testCustomLockFactory() throws IOException { - Directory dir = new MockDirectoryWrapper(new RAMDirectory()); + Directory dir = new MockDirectoryWrapper(random, new RAMDirectory()); MockLockFactory lf = new MockLockFactory(); dir.setLockFactory(lf); @@ -75,7 +75,7 @@ // exceptions raised: // Verify: NoLockFactory allows two IndexWriters public void testRAMDirectoryNoLocking() throws IOException { - Directory dir = new MockDirectoryWrapper(new RAMDirectory()); + Directory dir = new MockDirectoryWrapper(random, new RAMDirectory()); dir.setLockFactory(NoLockFactory.getNoLockFactory()); assertTrue("RAMDirectory.setLockFactory did not take", Index: lucene/src/test/org/apache/lucene/store/TestRAMDirectory.java --- lucene/src/test/org/apache/lucene/store/TestRAMDirectory.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/test/org/apache/lucene/store/TestRAMDirectory.java Sun Nov 14 19:37:18 2010 -0500 @@ -69,7 +69,7 @@ public void testRAMDirectory () throws IOException { Directory dir = FSDirectory.open(indexDir); - MockDirectoryWrapper ramDir = new MockDirectoryWrapper(new RAMDirectory(dir)); + MockDirectoryWrapper ramDir = new MockDirectoryWrapper(random, new RAMDirectory(dir)); // close the underlaying directory dir.close(); @@ -101,7 +101,7 @@ public void testRAMDirectorySize() throws IOException, InterruptedException { Directory dir = FSDirectory.open(indexDir); - final MockDirectoryWrapper ramDir = new MockDirectoryWrapper(new RAMDirectory(dir)); + final MockDirectoryWrapper ramDir = new MockDirectoryWrapper(random, new RAMDirectory(dir)); dir.close(); final IndexWriter writer = new IndexWriter(ramDir, new IndexWriterConfig( Index: lucene/src/test/org/apache/lucene/util/LuceneTestCase.java --- lucene/src/test/org/apache/lucene/util/LuceneTestCase.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/test/org/apache/lucene/util/LuceneTestCase.java Sun Nov 14 19:37:18 2010 -0500 @@ -659,7 +659,7 @@ public static MockDirectoryWrapper newDirectory(Random r) throws IOException { StackTraceElement[] stack = new Exception().getStackTrace(); Directory impl = newDirectoryImpl(r, TEST_DIRECTORY); - MockDirectoryWrapper dir = new MockDirectoryWrapper(impl); + MockDirectoryWrapper dir = new MockDirectoryWrapper(r, impl); stores.put(dir, stack); return dir; } @@ -679,7 +679,7 @@ for (String file : d.listAll()) { d.copy(impl, file, file); } - MockDirectoryWrapper dir = new MockDirectoryWrapper(impl); + MockDirectoryWrapper dir = new MockDirectoryWrapper(r, impl); stores.put(dir, stack); return dir; } Index: lucene/src/test/org/apache/lucene/util/TestBitVector.java --- lucene/src/test/org/apache/lucene/util/TestBitVector.java Sun Nov 14 12:06:21 2010 -0500 +++ lucene/src/test/org/apache/lucene/util/TestBitVector.java Sun Nov 14 19:37:18 2010 -0500 @@ -19,7 +19,6 @@ import java.io.IOException; -import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.store.RAMDirectory; @@ -137,7 +136,7 @@ } private void doTestWriteRead(int n) throws Exception { - MockDirectoryWrapper d = new MockDirectoryWrapper(new RAMDirectory()); + MockDirectoryWrapper d = new MockDirectoryWrapper(random, new RAMDirectory()); d.setPreventDoubleWrite(false); BitVector bv = new BitVector(n); // test count when incrementally setting bits @@ -168,7 +167,7 @@ } private void doTestDgaps(int size, int count1, int count2) throws IOException { - MockDirectoryWrapper d = new MockDirectoryWrapper(new RAMDirectory()); + MockDirectoryWrapper d = new MockDirectoryWrapper(random, new RAMDirectory()); d.setPreventDoubleWrite(false); BitVector bv = new BitVector(size); for (int i=0; i