Index: lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java (revision 1140228) +++ lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java (working copy) @@ -26,8 +26,8 @@ import org.apache.lucene.index.IndexWriterConfig.OpenMode; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.Version; /** @@ -178,27 +178,17 @@ * Instead, deletions are buffered in a bitset and overlaid with the original * list of deletions. */ - public static class FakeDeleteIndexReader extends FilterIndexReader { - OpenBitSet dels; - OpenBitSet oldDels = null; + public static final class FakeDeleteIndexReader extends FilterIndexReader { + OpenBitSet liveDocs; public FakeDeleteIndexReader(IndexReader in) { super(new SlowMultiReaderWrapper(in)); - dels = new OpenBitSet(in.maxDoc()); - if (in.hasDeletions()) { - oldDels = new OpenBitSet(in.maxDoc()); - final Bits oldDelBits = MultiFields.getDeletedDocs(in); - assert oldDelBits != null; - for (int i = 0; i < in.maxDoc(); i++) { - if (oldDelBits.get(i)) oldDels.set(i); - } - dels.or(oldDels); - } + doUndeleteAll(); // initialize main bitset } @Override public int numDocs() { - return in.maxDoc() - (int)dels.cardinality(); + return (int) liveDocs.cardinality(); } /** @@ -206,26 +196,35 @@ * deletions. */ @Override - protected void doUndeleteAll() throws CorruptIndexException, IOException { - dels = new OpenBitSet(in.maxDoc()); - if (oldDels != null) { - dels.or(oldDels); + protected void doUndeleteAll() { + final int maxDoc = in.maxDoc(); + liveDocs = new OpenBitSet(maxDoc); + if (in.hasDeletions()) { + final Bits oldLiveDocs = in.getLiveDocs(); + assert oldLiveDocs != null; + // this loop is a little bit ineffective, as Bits has no nextSetBit(): + for (int i = 0; i < maxDoc; i++) { + if (oldLiveDocs.get(i)) liveDocs.fastSet(i); + } + } else { + // mark all docs as valid + liveDocs.set(0, maxDoc); } } @Override - protected void doDelete(int n) throws CorruptIndexException, IOException { - dels.set(n); + protected void doDelete(int n) { + liveDocs.clear(n); } @Override public boolean hasDeletions() { - return !dels.isEmpty(); + return (in.maxDoc() != this.numDocs()); } @Override - public Bits getDeletedDocs() { - return dels; + public Bits getLiveDocs() { + return liveDocs; } } } Index: lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java (revision 1140228) +++ lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java (working copy) @@ -19,16 +19,16 @@ import java.io.IOException; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriterConfig.OpenMode; -import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.store.Directory; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; import org.apache.lucene.search.TermRangeFilter; +import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.OpenBitSetDISI; -import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.Version; /** @@ -87,13 +87,14 @@ } public static class DocumentFilteredIndexReader extends FilterIndexReader { - final Bits readerDels; + final Bits liveDocs; final int numDocs; public DocumentFilteredIndexReader(IndexReader reader, Filter preserveFilter, boolean negateFilter) throws IOException { super(new SlowMultiReaderWrapper(reader)); - final OpenBitSetDISI bits = new OpenBitSetDISI(in.maxDoc()); + final int maxDoc = in.maxDoc(); + final OpenBitSetDISI bits = new OpenBitSetDISI(maxDoc); final DocIdSet docs = preserveFilter.getDocIdSet((AtomicReaderContext) in.getTopReaderContext()); if (docs != null) { final DocIdSetIterator it = docs.iterator(); @@ -101,23 +102,24 @@ bits.inPlaceOr(it); } } - // this is somehow inverse, if we negate the filter, we delete all documents it matches! - if (!negateFilter) { - bits.flip(0, in.maxDoc()); + if (negateFilter) { + bits.flip(0, maxDoc); } if (in.hasDeletions()) { - final Bits oldDelBits = in.getDeletedDocs(); - assert oldDelBits != null; - for (int i = 0; i < in.maxDoc(); i++) { - if (oldDelBits.get(i)) { - bits.set(i); + final Bits oldLiveDocs = in.getLiveDocs(); + assert oldLiveDocs != null; + final DocIdSetIterator it = bits.iterator(); + for (int i = it.nextDoc(); i < maxDoc; i = it.nextDoc()) { + if (!oldLiveDocs.get(i)) { + // we can safely modify the current bit, as the iterator already stepped over it: + bits.fastClear(i); } } } - this.readerDels = bits; - this.numDocs = in.maxDoc() - (int) bits.cardinality(); + this.liveDocs = bits; + this.numDocs = (int) bits.cardinality(); } @Override @@ -131,8 +133,8 @@ } @Override - public Bits getDeletedDocs() { - return readerDels; + public Bits getLiveDocs() { + return liveDocs; } } }