Index: lucene/src/java/org/apache/lucene/index/FilterIndexReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/FilterIndexReader.java (revision 1214545)
+++ lucene/src/java/org/apache/lucene/index/FilterIndexReader.java (working copy)
@@ -388,16 +388,25 @@
return in.fields();
}
- /** If the subclass of FilteredIndexReader modifies the
- * contents of the FieldCache, you must override this
- * method to provide a different key */
+ /** {@inheritDoc}
+ *
If the subclass of FilteredIndexReader modifies the
+ * contents (but not liveDocs) of the index, you must override this
+ * method to provide a different key. */
@Override
public Object getCoreCacheKey() {
return in.getCoreCacheKey();
}
- /** {@inheritDoc} */
+ /** {@inheritDoc}
+ *
If the subclass of FilteredIndexReader modifies the
+ * liveDocs, you must override this
+ * method to provide a different key. */
@Override
+ public Object getCombinedCoreAndDeletesKey() {
+ return in.getCombinedCoreAndDeletesKey();
+ }
+
+ @Override
public String toString() {
final StringBuilder buffer = new StringBuilder("FilterReader(");
buffer.append(in);
Index: lucene/src/java/org/apache/lucene/index/IndexReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexReader.java (revision 1214545)
+++ lucene/src/java/org/apache/lucene/index/IndexReader.java (working copy)
@@ -1100,13 +1100,24 @@
*/
public abstract ReaderContext getTopReaderContext();
- /** Expert */
+ /** Expert: Returns a key for this IndexReader, so FieldCache/CachingWrapperFilter can find
+ * it again.
+ * This key must not have equals()/hashCode() methods, so "equals" means "identical". */
public Object getCoreCacheKey() {
// Don't can ensureOpen since FC calls this (to evict)
// on close
return this;
}
+ /** Expert: Returns a key for this IndexReader that also includes deletions,
+ * so FieldCache/CachingWrapperFilter can find it again.
+ * This key must not have equals()/hashCode() methods, so "equals" means "identical". */
+ public Object getCombinedCoreAndDeletesKey() {
+ // Don't can ensureOpen since FC calls this (to evict)
+ // on close
+ return this;
+ }
+
/** Returns the number of unique terms (across all fields)
* in this reader.
*
Index: lucene/src/java/org/apache/lucene/index/SegmentReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentReader.java (revision 1214545)
+++ lucene/src/java/org/apache/lucene/index/SegmentReader.java (working copy)
@@ -47,7 +47,8 @@
final CloseableThreadLocal fieldsReaderLocal = new FieldsReaderLocal();
final CloseableThreadLocal termVectorsLocal = new CloseableThreadLocal();
- volatile BitVector liveDocs;
+ volatile BitVector liveDocs = null;
+ volatile Object combinedCoreAndDeletesKey;
AtomicInteger liveDocsRef = null;
boolean hasChanges = false;
private boolean liveDocsDirty = false;
@@ -159,8 +160,11 @@
if (liveDocs.size() != si.docCount) {
throw new CorruptIndexException("document count mismatch: deleted docs count " + liveDocs.size() + " vs segment doc count " + si.docCount + " segment=" + si.name);
}
- } else
+ } else {
assert si.getDelCount() == 0;
+ }
+ // we need a key reflecting actual deletes (if existent or not):
+ combinedCoreAndDeletesKey = new Object();
}
@Override
@@ -411,6 +415,11 @@
}
@Override
+ public Object getCombinedCoreAndDeletesKey() {
+ return combinedCoreAndDeletesKey;
+ }
+
+ @Override
public int getTermInfosIndexDivisor() {
return core.termsIndexDivisor;
}
@@ -465,6 +474,7 @@
core.incRef();
clone.core = core;
clone.pendingDeleteCount = pendingDeleteCount;
+ clone.combinedCoreAndDeletesKey = combinedCoreAndDeletesKey;
if (!openReadOnly && hasChanges) {
// My pending changes transfer to the new reader
@@ -592,6 +602,9 @@
liveDocsRef = new AtomicInteger(1);
oldRef.decrementAndGet();
}
+ // we need a key reflecting actual deletes (if existent or not):
+ combinedCoreAndDeletesKey = new Object();
+ // liveDocs are now dirty:
liveDocsDirty = true;
if (liveDocs.getAndClear(docNum)) {
pendingDeleteCount++;
Index: lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java
===================================================================
--- lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java (revision 1214545)
+++ lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java (working copy)
@@ -18,17 +18,17 @@
*/
import java.io.IOException;
-import java.lang.ref.SoftReference;
+import java.util.Collections;
+import java.util.Map;
import java.util.WeakHashMap;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.WeakIdentityHashMap;
/**
- * Wraps another filter's result and caches it. The purpose is to allow
+ * Wraps another {@link Filter}'s result and caches it. The purpose is to allow
* filters to simply filter, and then wrap with this class
* to add caching.
*/
@@ -37,43 +37,33 @@
// specify the actual readers key or something similar to indicate on which
// level of the readers hierarchy it should be cached.
private final Filter filter;
- private final FilterCache cache = new FilterCache();
+ private final Map