From 064e8dc60ab6955caa692d7528ab7c85b8ed0bf8 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 8 Dec 2010 02:02:02 +0000 Subject: [PATCH] LUCENE-2802: NRT DirectoryReader returned incorrect values from getVersion, isOptimized, getCommitUserData, getIndexCommit and isCurrent due to a mutable reference to the IndexWriters SegmentInfos git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1043277 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 5 +++ .../apache/lucene/index/DirectoryReader.java | 9 ++--- .../lucene/index/TestIndexWriterReader.java | 38 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 49d9acd491b..17852b48009 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -348,6 +348,11 @@ Bug fixes 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) ======================= diff --git a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java index c4de527bd1c..d3949b4fe53 100644 --- a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java +++ b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java @@ -55,8 +55,7 @@ class DirectoryReader extends IndexReader implements Cloneable { 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 @@ class DirectoryReader extends IndexReader implements Cloneable { this.segmentInfos = sis; this.deletionPolicy = deletionPolicy; this.termInfosIndexDivisor = termInfosIndexDivisor; - if (codecs == null) { this.codecs = CodecProvider.getDefault(); } else { @@ -145,8 +143,7 @@ class DirectoryReader extends IndexReader implements Cloneable { 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 @@ class DirectoryReader extends IndexReader implements Cloneable { // we loaded SegmentInfos from the directory return SegmentInfos.readCurrentVersion(directory, codecs) == segmentInfos.getVersion(); } else { - return writer.nrtIsCurrent(segmentInfosStart); + return writer.nrtIsCurrent(segmentInfos); } } diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java b/lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java index 7704a599902..5c357927e33 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java @@ -175,6 +175,44 @@ public class TestIndexWriterReader extends LuceneTestCase { 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 *