From 7c071d5c8ea8ae40c38c91e972c31aff0e0612df Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Thu, 21 May 2009 11:45:21 +0000 Subject: [PATCH] LUCENE-1648: carry over hasChanges/deletionsDirty/normsDirty/pendingDeleteCount when a SegmentReader w/ pending changes is cloned git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@777080 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/index/DirectoryIndexReader.java | 4 +- .../apache/lucene/index/SegmentReader.java | 10 +++++ .../lucene/index/TestIndexReaderClone.java | 38 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/lucene/index/DirectoryIndexReader.java b/src/java/org/apache/lucene/index/DirectoryIndexReader.java index 52237f2f620..183e7b04d4b 100644 --- a/src/java/org/apache/lucene/index/DirectoryIndexReader.java +++ b/src/java/org/apache/lucene/index/DirectoryIndexReader.java @@ -330,7 +330,9 @@ abstract class DirectoryIndexReader extends IndexReader implements Cloneable { /** Returns the directory this index resides in. */ public Directory directory() { - ensureOpen(); + // Don't ensureOpen here -- in certain cases, when a + // cloned/reopened reader needs to commit, it may call + // this method on the closed original reader return directory; } diff --git a/src/java/org/apache/lucene/index/SegmentReader.java b/src/java/org/apache/lucene/index/SegmentReader.java index 179faa82adf..6027ec2615e 100644 --- a/src/java/org/apache/lucene/index/SegmentReader.java +++ b/src/java/org/apache/lucene/index/SegmentReader.java @@ -691,6 +691,15 @@ class SegmentReader extends DirectoryIndexReader { clone.termVectorsReaderOrig = termVectorsReaderOrig; clone.fieldsReaderOrig = fieldsReaderOrig; + if (!openReadOnly && hasChanges) { + // My pending changes transfer to the new reader + clone.pendingDeleteCount = pendingDeleteCount; + clone.deletedDocsDirty = deletedDocsDirty; + clone.normsDirty = normsDirty; + clone.hasChanges = hasChanges; + hasChanges = false; + } + if (doClone) { if (deletedDocs != null) { deletedDocsRef.incRef(); @@ -752,6 +761,7 @@ class SegmentReader extends DirectoryIndexReader { si.setDelCount(si.getDelCount()+pendingDeleteCount); pendingDeleteCount = 0; + assert deletedDocs.count() == si.getDelCount(): "delete count mismatch during commit: info=" + si.getDelCount() + " vs BitVector=" + deletedDocs.count(); } if (undeleteAll && si.hasDeletions()) { si.clearDelGen(); diff --git a/src/test/org/apache/lucene/index/TestIndexReaderClone.java b/src/test/org/apache/lucene/index/TestIndexReaderClone.java index 97dbbd3b513..9cc0ed16dac 100644 --- a/src/test/org/apache/lucene/index/TestIndexReaderClone.java +++ b/src/test/org/apache/lucene/index/TestIndexReaderClone.java @@ -397,6 +397,44 @@ public class TestIndexReaderClone extends LuceneTestCase { dir1.close(); } + // LUCENE-1648 + public void testCloneWithDeletes() throws Throwable { + final Directory dir1 = new MockRAMDirectory(); + TestIndexReaderReopen.createIndex(dir1, false); + SegmentReader origSegmentReader = (SegmentReader) IndexReader.open(dir1); + origSegmentReader.deleteDocument(1); + + SegmentReader clonedSegmentReader = (SegmentReader) origSegmentReader.clone(); + origSegmentReader.close(); + clonedSegmentReader.close(); + + SegmentReader r = (SegmentReader) IndexReader.open(dir1); + assertTrue(r.isDeleted(1)); + r.close(); + dir1.close(); + } + + // LUCENE-1648 + public void testCloneWithSetNorm() throws Throwable { + final Directory dir1 = new MockRAMDirectory(); + TestIndexReaderReopen.createIndex(dir1, false); + SegmentReader orig = (SegmentReader) IndexReader.open(dir1); + orig.setNorm(1, "field1", 17.0f); + final byte encoded = Similarity.encodeNorm(17.0f); + assertEquals(encoded, orig.norms("field1")[1]); + + // the cloned segmentreader should have 2 references, 1 to itself, and 1 to + // the original segmentreader + SegmentReader clonedSegmentReader = (SegmentReader) orig.clone(); + orig.close(); + clonedSegmentReader.close(); + + SegmentReader r = (SegmentReader) IndexReader.open(dir1); + assertEquals(encoded, r.norms("field1")[1]); + r.close(); + dir1.close(); + } + private void assertDocDeleted(SegmentReader reader, SegmentReader reader2, int doc) { assertEquals(reader.isDeleted(doc), reader2.isDeleted(doc));