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
This commit is contained in:
Simon Willnauer 2010-12-08 02:02:02 +00:00
parent 6c9052d231
commit 064e8dc60a
3 changed files with 46 additions and 6 deletions

View File

@ -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) =======================

View File

@ -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);
}
}

View File

@ -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
*