You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2011/04/14 14:41:19 UTC
svn commit: r1092194 - in /lucene/dev/branches/realtime_search/lucene/src:
java/org/apache/lucene/index/ test/org/apache/lucene/index/
Author: simonw
Date: Thu Apr 14 12:41:18 2011
New Revision: 1092194
URL: http://svn.apache.org/viewvc?rev=1092194&view=rev
Log:
LUCENE-3028: IW.getReader() returns inconsistent reader on RT Branch
Modified:
lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java
lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterDeleteQueue.java
lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java
lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/IndexWriter.java
lucene/dev/branches/realtime_search/lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java
Modified: lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java Thu Apr 14 12:41:18 2011
@@ -118,9 +118,8 @@ final class DocumentsWriter {
private AtomicInteger numDocsInRAM = new AtomicInteger(0);
- final BufferedDeletesStream bufferedDeletesStream;
// TODO: cut over to BytesRefHash in BufferedDeletes
- volatile DocumentsWriterDeleteQueue deleteQueue = new DocumentsWriterDeleteQueue(new BufferedDeletes(false));
+ volatile DocumentsWriterDeleteQueue deleteQueue = new DocumentsWriterDeleteQueue();
private final Queue<FlushTicket> ticketQueue = new LinkedList<DocumentsWriter.FlushTicket>();
private Collection<String> abortedFiles; // List of files that were written before last abort()
@@ -136,7 +135,6 @@ final class DocumentsWriter {
this.directory = directory;
this.indexWriter = writer;
this.similarityProvider = config.getSimilarityProvider();
- this.bufferedDeletesStream = bufferedDeletesStream;
this.perThreadPool = config.getIndexerThreadPool();
this.chain = config.getIndexingChain();
this.perThreadPool.initialize(this, globalFieldNumbers, config);
@@ -179,8 +177,6 @@ final class DocumentsWriter {
boolean deleteTerm(final Term term) throws IOException {
return deleteTerms(term);
}
-
-
DocumentsWriterDeleteQueue currentDeleteSession() {
return deleteQueue;
@@ -357,7 +353,12 @@ final class DocumentsWriter {
maybeMerge = true;
boolean success = false;
FlushTicket ticket = null;
+
try {
+ assert currentFullFlushDelQueue == null
+ || flushingDWPT.deleteQueue == currentFullFlushDelQueue : "expected: "
+ + currentFullFlushDelQueue + "but was: " + flushingDWPT.deleteQueue
+ + " " + flushControl.isFullFlush();
/*
* Since with DWPT the flush process is concurrent and several DWPT
* could flush at the same time we must maintain the order of the
@@ -391,8 +392,8 @@ final class DocumentsWriter {
indexWriter.flushCount.incrementAndGet();
if (!success && ticket != null) {
synchronized (ticketQueue) {
- // in the case of a failure make sure we are making progress and
- // apply all the deletes since the segment flush failed
+ // in the case of a failure make sure we are making progress and
+ // apply all the deletes since the segment flush failed
ticket.isSegmentFlush = false;
}
@@ -416,7 +417,7 @@ final class DocumentsWriter {
final FlushTicket head = ticketQueue.peek();
if (head != null && head.canPublish()) {
ticketQueue.poll();
- finishFlushedSegment(head.segment, head.frozenDeletes);
+ finishFlush(head.segment, head.frozenDeletes);
} else {
break;
}
@@ -425,16 +426,22 @@ final class DocumentsWriter {
}
- private void finishFlushedSegment(FlushedSegment newSegment, FrozenBufferedDeletes bufferedDeletes)
+ private void finishFlush(FlushedSegment newSegment, FrozenBufferedDeletes bufferedDeletes)
throws IOException {
// this is eventually finishing the flushed segment and publishing it to the IndexWriter
- if (bufferedDeletes != null && bufferedDeletes.any()) {
- bufferedDeletesStream.push(bufferedDeletes);
- if (infoStream != null) {
- message("flush: push buffered deletes: " + bufferedDeletes);
+ if (newSegment == null) {
+ assert bufferedDeletes != null;
+ if (bufferedDeletes != null && bufferedDeletes.any()) {
+ indexWriter.bufferedDeletesStream.push(bufferedDeletes);
+ if (infoStream != null) {
+ message("flush: push buffered deletes: " + bufferedDeletes);
+ }
}
+ } else {
+ publishFlushedSegment(newSegment, bufferedDeletes);
}
- publishFlushedSegment(newSegment);
+
+
}
@@ -445,74 +452,89 @@ final class DocumentsWriter {
}
}
- private void publishFlushedSegment(FlushedSegment newSegment)
+ /**
+ * publishes the flushed segment, segment private deletes if any and its
+ * associated global delete if present to the index writer. the actual
+ * publishing operation is synced on IW -> BDS so that the {@link SegmentInfo}
+ * 's delete generation is always GlobalPacket_deleteGeneration + 1
+ */
+ private void publishFlushedSegment(FlushedSegment newSegment, FrozenBufferedDeletes globalPacket)
throws IOException {
- if (newSegment != null) {
- final SegmentInfo segInfo = indexWriter.prepareFlushedSegment(newSegment);
- final BufferedDeletes deletes = newSegment.segmentDeletes;
- FrozenBufferedDeletes packet = null;
- if (deletes != null && deletes.any()) {
- // segment private delete
- packet = new FrozenBufferedDeletes(deletes, true);
- if (infoStream != null) {
- message("flush: push buffered seg private deletes: " + packet);
- }
+ assert newSegment != null;
+ final SegmentInfo segInfo = indexWriter.prepareFlushedSegment(newSegment);
+ final BufferedDeletes deletes = newSegment.segmentDeletes;
+ FrozenBufferedDeletes packet = null;
+ if (deletes != null && deletes.any()) {
+ // segment private delete
+ packet = new FrozenBufferedDeletes(deletes, true);
+ if (infoStream != null) {
+ message("flush: push buffered seg private deletes: " + packet);
}
- indexWriter.publishFlushedSegment(segInfo, packet);
}
+ // now publish!
+ indexWriter.publishFlushedSegment(segInfo, packet, globalPacket);
}
- private final Object flushAllLock = new Object();
// for asserts
- private volatile DocumentsWriterDeleteQueue currentFlusingSession = null;
- private boolean setFlushingDeleteQueue(DocumentsWriterDeleteQueue session) {
- currentFlusingSession = session;
+ private volatile DocumentsWriterDeleteQueue currentFullFlushDelQueue = null;
+ // for asserts
+ private synchronized boolean setFlushingDeleteQueue(DocumentsWriterDeleteQueue session) {
+ currentFullFlushDelQueue = session;
return true;
}
+ /*
+ * flushAllThreads is synced by IW fullFlushLock. Flushing all threads is a
+ * two stage operations, the caller must ensure that #finishFlush is called
+ * after this method to release the flush lock in DWFlushControl - use try /
+ * finally!
+ */
final boolean flushAllThreads(final boolean flushDeletes)
throws IOException {
- synchronized (flushAllLock) {
- final DocumentsWriterDeleteQueue flushingDeleteQueue;
- synchronized (this) {
- flushingDeleteQueue = deleteQueue;
- deleteQueue = new DocumentsWriterDeleteQueue(new BufferedDeletes(false));
- assert setFlushingDeleteQueue(flushingDeleteQueue);
+ final DocumentsWriterDeleteQueue flushingDeleteQueue;
+
+ synchronized (this) {
+ flushingDeleteQueue = deleteQueue;
+ /* sets a new delete queue - this must be synced on the flush control
+ * otherwise a new DWPT could sneak into the loop with an already flushing
+ * delete queue */
+ flushControl.markForFullFlush();
+ assert setFlushingDeleteQueue(flushingDeleteQueue);
+ }
+ assert currentFullFlushDelQueue != null;
+ assert currentFullFlushDelQueue != deleteQueue;
+
+ boolean anythingFlushed = false;
+ try {
+ DocumentsWriterPerThread flushingDWPT;
+ // now try help out with flushing
+ while ((flushingDWPT = flushControl.nextPendingFlush()) != null) {
+ anythingFlushed |= doFlush(flushingDWPT);
+ }
+ // if a concurrent flush is still in flight wait for it
+ while (!flushControl.allFlushesDue()) {
+ flushControl.waitForFlush();
}
- assert flushingDeleteQueue == currentFlusingSession;
- boolean anythingFlushed = false;
- boolean success = false;
- try {
- flushControl.markForFullFlush();
- DocumentsWriterPerThread flushingDWPT;
- // now try help out with flushing
- while ((flushingDWPT = flushControl.nextPendingFlush()) != null) {
- anythingFlushed |= doFlush(flushingDWPT);
- }
- // if a concurrent flush is still in flight wait for it
- while (!flushControl.allFlushesDue()) {
- flushControl.waitForFlush();
- }
- if (!anythingFlushed && flushDeletes) {
- synchronized (ticketQueue) {
- ticketQueue.add(new FlushTicket(flushingDeleteQueue.freezeGlobalBuffer(null), false));
- }
- applyFlushTickets(null, null);
- }
- success = true;
-
- } finally {
- assert flushingDeleteQueue == currentFlusingSession;
- assert setFlushingDeleteQueue(null);
- if (!success) {
- flushControl.abortFullFlushes();
- } else {
- // release the flush lock
- flushControl.finishFullFlush();
- }
+ if (!anythingFlushed && flushDeletes) {
+ synchronized (ticketQueue) {
+ ticketQueue.add(new FlushTicket(flushingDeleteQueue.freezeGlobalBuffer(null), false));
+ }
+ applyFlushTickets(null, null);
}
- return anythingFlushed;
+ } finally {
+ assert flushingDeleteQueue == currentFullFlushDelQueue;
+ }
+ return anythingFlushed;
+ }
+
+ final void finishFullFlush(boolean success) {
+ if (success) {
+ // release the flush lock
+ flushControl.finishFullFlush();
+ } else {
+ flushControl.abortFullFlushes();
}
+ assert setFlushingDeleteQueue(null);
}
static final class FlushTicket {
Modified: lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterDeleteQueue.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterDeleteQueue.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterDeleteQueue.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterDeleteQueue.java Thu Apr 14 12:41:18 2011
@@ -72,6 +72,10 @@ final class DocumentsWriterDeleteQueue {
private final BufferedDeletes globalBufferedDeletes;
/* only acquired to update the global deletes */
private final ReentrantLock globalBufferLock = new ReentrantLock();
+
+ DocumentsWriterDeleteQueue() {
+ this(new BufferedDeletes(false));
+ }
DocumentsWriterDeleteQueue(BufferedDeletes globalBufferedDeletes) {
this.globalBufferedDeletes = globalBufferedDeletes;
Modified: lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterFlushControl.java Thu Apr 14 12:41:18 2011
@@ -305,9 +305,14 @@ public final class DocumentsWriterFlushC
}
void markForFullFlush() {
+ final DocumentsWriterDeleteQueue flushingQueue;
synchronized (this) {
assert !fullFlush;
fullFlush = true;
+ flushingQueue = documentsWriter.deleteQueue;
+ // set a new delete queue - all subsequent DWPT will use this queue until
+ // we do another full flush
+ documentsWriter.deleteQueue = new DocumentsWriterDeleteQueue(new BufferedDeletes(false));
}
final Iterator<ThreadState> allActiveThreads = perThreadPool
.getActivePerThreadsIterator();
@@ -319,13 +324,18 @@ public final class DocumentsWriterFlushC
if (!next.isActive()) {
continue;
}
- if (next.perThread.getNumDocsInRAM() > 0) {
+ if (next.perThread.deleteQueue != flushingQueue) {
+ // this one is already a new DWPT
+ continue;
+ }
+ if (next.perThread.getNumDocsInRAM() > 0 ) {
final DocumentsWriterPerThread dwpt = next.perThread; // just for assert
final DocumentsWriterPerThread flushingDWPT = internalTryCheckOutForFlush(next, true);
assert flushingDWPT != null : "DWPT must never be null here since we hold the lock and it holds documents";
assert dwpt == flushingDWPT : "flushControl returned different DWPT";
toFlush.add(flushingDWPT);
} else {
+ // get the new delete queue from DW
next.perThread.initialize();
}
} finally {
@@ -337,7 +347,6 @@ public final class DocumentsWriterFlushC
blockedFlushes.clear();
flushQueue.addAll(toFlush);
}
-
}
synchronized void finishFullFlush() {
@@ -361,8 +370,15 @@ public final class DocumentsWriterFlushC
for (DocumentsWriterPerThread dwpt : blockedFlushes) {
doAfterFlush(dwpt);
}
+
} finally {
+ flushQueue.clear();
+ blockedFlushes.clear();
fullFlush = false;
}
}
+
+ synchronized boolean isFullFlush() {
+ return fullFlush;
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java Thu Apr 14 12:41:18 2011
@@ -195,7 +195,6 @@ public class DocumentsWriterPerThread {
assert numDocsInRAM == 0 : "num docs " + numDocsInRAM;
pendingDeletes.clear();
deleteSlice = null;
-
}
void setAborting() {
Modified: lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/IndexWriter.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/java/org/apache/lucene/index/IndexWriter.java Thu Apr 14 12:41:18 2011
@@ -347,25 +347,50 @@ public class IndexWriter implements Clos
if (infoStream != null) {
message("flush at getReader");
}
-
// Do this up front before flushing so that the readers
// obtained during this flush are pooled, the first time
// this method is called:
poolReaders = true;
-
- // Prevent segmentInfos from changing while opening the
- // reader; in theory we could do similar retry logic,
- // just like we do when loading segments_N
- IndexReader r;
- flush(false, applyAllDeletes); // don't sync on IW here DWPT will deadlock
- synchronized(this) {
- r = new DirectoryReader(this, segmentInfos, config.getReaderTermsIndexDivisor(), codecs, applyAllDeletes);
- if (infoStream != null) {
- message("return reader version=" + r.getVersion() + " reader=" + r);
+ final IndexReader r;
+ doBeforeFlush();
+ final boolean maybeMerge;
+ /*
+ * for releasing a NRT reader we must ensure that
+ * DW doesn't add any segments or deletes until we are
+ * done with creating the NRT DirectoryReader.
+ * We release the two stage full flush after we are done opening the
+ * directory reader!
+ */
+ synchronized (fullFlushLock) {
+ boolean success = false;
+ try {
+ maybeMerge = docWriter.flushAllThreads(applyAllDeletes);
+ if (!maybeMerge) {
+ flushCount.incrementAndGet();
+ }
+ success = true;
+ // Prevent segmentInfos from changing while opening the
+ // reader; in theory we could do similar retry logic,
+ // just like we do when loading segments_N
+ synchronized(this) {
+ maybeApplyDeletes(applyAllDeletes);
+ r = new DirectoryReader(this, segmentInfos, config.getReaderTermsIndexDivisor(), codecs, applyAllDeletes);
+ if (infoStream != null) {
+ message("return reader version=" + r.getVersion() + " reader=" + r);
+ }
+ }
+ } finally {
+ if (!success && infoStream != null) {
+ message("hit exception during while NRT reader");
+ }
+ // now we are done - finish the full flush!
+ docWriter.finishFullFlush(success);
+ doAfterFlush();
}
}
- maybeMerge();
-
+ if(maybeMerge) {
+ maybeMerge();
+ }
if (infoStream != null) {
message("getReader took " + (System.currentTimeMillis() - tStart) + " msec");
}
@@ -2120,9 +2145,12 @@ public class IndexWriter implements Clos
* @see #prepareFlushedSegment(FlushedSegment)
*/
synchronized void publishFlushedSegment(SegmentInfo newSegment,
- FrozenBufferedDeletes packet) throws IOException {
+ FrozenBufferedDeletes packet, FrozenBufferedDeletes globalPacket) throws IOException {
// lock order IW -> BDS
synchronized (bufferedDeletesStream) {
+ if (globalPacket != null && globalPacket.any()) {
+ bufferedDeletesStream.push(globalPacket);
+ }
// publishing the segment must be synched on IW -> BDS to make the sure
// that no merge prunes away the seg. private delete packet
final long nextGen;
@@ -2544,7 +2572,7 @@ public class IndexWriter implements Clos
message("commit: done");
}
}
-
+ private final Object fullFlushLock = new Object();
/**
* Flush all in-memory buffered updates (adds and deletes)
* to the Directory.
@@ -2576,7 +2604,6 @@ public class IndexWriter implements Clos
}
doBeforeFlush();
-
assert testPoint("startDoFlush");
boolean success = false;
try {
@@ -2585,43 +2612,26 @@ public class IndexWriter implements Clos
message(" start flush: applyAllDeletes=" + applyAllDeletes);
message(" index before flush " + segString());
}
-
- boolean maybeMerge = docWriter.flushAllThreads(applyAllDeletes);
-
- synchronized(this) {
- if (!applyAllDeletes) {
- // If deletes alone are consuming > 1/2 our RAM
- // buffer, force them all to apply now. This is to
- // prevent too-frequent flushing of a long tail of
- // tiny segments:
- if ((config.getRAMBufferSizeMB() != IndexWriterConfig.DISABLE_AUTO_FLUSH &&
- bufferedDeletesStream.bytesUsed() > (1024*1024*config.getRAMBufferSizeMB()/2))) {
- applyAllDeletes = true;
- if (infoStream != null) {
- message("force apply deletes bytesUsed=" + bufferedDeletesStream.bytesUsed() + " vs ramBuffer=" + (1024*1024*config.getRAMBufferSizeMB()));
- }
- }
- }
-
- if (applyAllDeletes) {
- if (infoStream != null) {
- message("apply all deletes during flush");
- }
- applyAllDeletes();
- } else if (infoStream != null) {
- message("don't apply deletes now delTermCount=" + bufferedDeletesStream.numTerms() + " bytesUsed=" + bufferedDeletesStream.bytesUsed());
+ final boolean maybeMerge;
+
+ synchronized (fullFlushLock) {
+ try {
+ maybeMerge = docWriter.flushAllThreads(applyAllDeletes);
+ success = true;
+ } finally {
+ docWriter.finishFullFlush(success);
}
-
+ }
+ success = false;
+ synchronized(this) {
+ maybeApplyDeletes(applyAllDeletes);
doAfterFlush();
if (!maybeMerge) {
// flushCount is incremented in flushAllThreads
flushCount.incrementAndGet();
}
-
success = true;
-
return maybeMerge;
-
}
} catch (OutOfMemoryError oom) {
handleOOM(oom, "doFlush");
@@ -2633,6 +2643,32 @@ public class IndexWriter implements Clos
}
}
+ final synchronized void maybeApplyDeletes(boolean applyAllDeletes) throws IOException {
+ if (!applyAllDeletes) {
+ // If deletes alone are consuming > 1/2 our RAM
+ // buffer, force them all to apply now. This is to
+ // prevent too-frequent flushing of a long tail of
+ // tiny segments:
+ if ((config.getRAMBufferSizeMB() != IndexWriterConfig.DISABLE_AUTO_FLUSH &&
+ bufferedDeletesStream.bytesUsed() > (1024*1024*config.getRAMBufferSizeMB()/2))) {
+ applyAllDeletes = true;
+ if (infoStream != null) {
+ message("force apply deletes bytesUsed=" + bufferedDeletesStream.bytesUsed() + " vs ramBuffer=" + (1024*1024*config.getRAMBufferSizeMB()));
+ }
+ }
+ }
+
+ if (applyAllDeletes) {
+ if (infoStream != null) {
+ message("apply all deletes during flush");
+ }
+ applyAllDeletes();
+ } else if (infoStream != null) {
+ message("don't apply deletes now delTermCount=" + bufferedDeletesStream.numTerms() + " bytesUsed=" + bufferedDeletesStream.bytesUsed());
+ }
+
+ }
+
final synchronized void applyAllDeletes() throws IOException {
flushDeletesCount.incrementAndGet();
final BufferedDeletesStream.ApplyDeletesResult result = bufferedDeletesStream
Modified: lucene/dev/branches/realtime_search/lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/realtime_search/lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java?rev=1092194&r1=1092193&r2=1092194&view=diff
==============================================================================
--- lucene/dev/branches/realtime_search/lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java (original)
+++ lucene/dev/branches/realtime_search/lucene/src/test/org/apache/lucene/index/TestRollingUpdates.java Thu Apr 14 12:41:18 2011
@@ -81,9 +81,7 @@ public class TestRollingUpdates extends
final LineFileDocs docs = new LineFileDocs(random);
for (int r = 0; r < 3; r++) {
final IndexWriter w = new IndexWriter(dir, newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(
- newLogMergePolicy()).setMaxBufferedDocs(2));
-
+ TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMaxBufferedDocs(2));
final int SIZE = 200 * RANDOM_MULTIPLIER;
final int numUpdates = (int) (SIZE * (2 + random.nextDouble()));
int numThreads = 3 + random.nextInt(Runtime.getRuntime().availableProcessors());
@@ -120,22 +118,23 @@ public class TestRollingUpdates extends
public void run() {
try {
-// IndexReader open = IndexReader.open(writer, true);
+ IndexReader open = null;
for (int i = 0; i < num; i++) {
Document doc = new Document();// docs.nextDoc();
doc.add(newField("id", "test", Index.NOT_ANALYZED));
writer.updateDocument(new Term("id", "test"), doc);
-// if (random.nextInt(10) == 0) {
-// IndexReader reader = open.reopen();
-// if (reader != open) {
-// open.close();
-// open = reader;
-// }
-// assertEquals("iter: " + i + " numDocs: "+ open.numDocs() + " del: " + open.numDeletedDocs() + " max: " + open.maxDoc(), 1, open.numDocs());
-//
-// }
+ if (random.nextInt(10) == 0) {
+ if (open == null)
+ open = IndexReader.open(writer, true);
+ IndexReader reader = open.reopen();
+ if (reader != open) {
+ open.close();
+ open = reader;
+ }
+ assertEquals("iter: " + i + " numDocs: "+ open.numDocs() + " del: " + open.numDeletedDocs() + " max: " + open.maxDoc(), 1, open.numDocs());
+ }
}
-// open.close();
+ open.close();
} catch (Exception e) {
fail(e.getMessage());
}