Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 1043148) +++ CHANGES.txt (working copy) @@ -348,6 +348,11 @@ with more document deletions is requested before a reader with fewer deletions, provided they share some segments. (yonik) +* LUCENE-2802: NRT DirectoryReader returned incorrect values from + getVersion, isOptimized, getCommitUserData, getIndexCommit and isCurrent due + to a mutable reference to the IndexWriters SegmentInfos. + (Simon Willnauer, Earwin Burrfoot) + ======================= Lucene 3.x (not yet released) ======================= Index: src/java/org/apache/lucene/index/DirectoryReader.java =================================================================== --- src/java/org/apache/lucene/index/DirectoryReader.java (revision 1043148) +++ src/java/org/apache/lucene/index/DirectoryReader.java (working copy) @@ -55,8 +55,7 @@ private IndexDeletionPolicy deletionPolicy; private Lock writeLock; - private SegmentInfos segmentInfos; - private SegmentInfos segmentInfosStart; + private final SegmentInfos segmentInfos; private boolean stale; private final int termInfosIndexDivisor; @@ -106,7 +105,6 @@ this.segmentInfos = sis; this.deletionPolicy = deletionPolicy; this.termInfosIndexDivisor = termInfosIndexDivisor; - if (codecs == null) { this.codecs = CodecProvider.getDefault(); } else { @@ -145,8 +143,7 @@ DirectoryReader(IndexWriter writer, SegmentInfos infos, int termInfosIndexDivisor, CodecProvider codecs) throws IOException { this.directory = writer.getDirectory(); this.readOnly = true; - segmentInfos = infos; - segmentInfosStart = (SegmentInfos) infos.clone(); + segmentInfos = (SegmentInfos) infos.clone();// make sure we clone otherwise we share mutable state with IW this.termInfosIndexDivisor = termInfosIndexDivisor; if (codecs == null) { this.codecs = CodecProvider.getDefault(); @@ -860,7 +857,7 @@ // we loaded SegmentInfos from the directory return SegmentInfos.readCurrentVersion(directory, codecs) == segmentInfos.getVersion(); } else { - return writer.nrtIsCurrent(segmentInfosStart); + return writer.nrtIsCurrent(segmentInfos); } } Index: src/test/org/apache/lucene/index/TestIndexWriterReader.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriterReader.java (revision 1043148) +++ src/test/org/apache/lucene/index/TestIndexWriterReader.java (working copy) @@ -175,6 +175,44 @@ dir1.close(); } + public void testIsCurrent() throws IOException { + Directory dir = newDirectory(); + IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()); + + IndexWriter writer = new IndexWriter(dir, iwc); + Document doc = new Document(); + doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + writer.addDocument(doc); + writer.close(); + + iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()); + writer = new IndexWriter(dir, iwc); + doc = new Document(); + doc.add(newField("field", "a b c", Field.Store.NO, Field.Index.ANALYZED)); + IndexReader nrtReader = writer.getReader(); + assertTrue(nrtReader.isCurrent()); + writer.addDocument(doc); + assertFalse(nrtReader.isCurrent()); // should see the changes + writer.optimize(); // make sure we don't have a merge going on + assertFalse(nrtReader.isCurrent()); + nrtReader.close(); + + IndexReader dirReader = IndexReader.open(dir); + nrtReader = writer.getReader(); + + assertTrue(dirReader.isCurrent()); + assertTrue(nrtReader.isCurrent()); // nothing was committed yet so we are still current + assertEquals(2, nrtReader.maxDoc()); // sees the actual document added + assertEquals(1, dirReader.maxDoc()); + writer.close(); // close is actually a commit both should see the changes + assertTrue(nrtReader.isCurrent()); + assertFalse(dirReader.isCurrent()); // this reader has been opened before the writer was closed / committed + + dirReader.close(); + nrtReader.close(); + dir.close(); + } + /** * Test using IW.addIndexes *