You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2015/05/18 18:27:09 UTC
svn commit: r1680053 - in /lucene/dev/branches/branch_5x: ./ lucene/
lucene/core/ lucene/core/src/java/org/apache/lucene/index/
lucene/core/src/test/org/apache/lucene/index/ lucene/test-framework/
lucene/test-framework/src/java/org/apache/lucene/index/
Author: jpountz
Date: Mon May 18 16:27:08 2015
New Revision: 1680053
URL: http://svn.apache.org/r1680053
Log:
LUCENE-6483: Ensure core closed listeners are called on the same cache key as the reader which has been used to register the listener.
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/lucene/ (props changed)
lucene/dev/branches/branch_5x/lucene/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/lucene/core/ (props changed)
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java
lucene/dev/branches/branch_5x/lucene/test-framework/ (props changed)
lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
Modified: lucene/dev/branches/branch_5x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/CHANGES.txt?rev=1680053&r1=1680052&r2=1680053&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/lucene/CHANGES.txt Mon May 18 16:27:08 2015
@@ -141,6 +141,9 @@ Bug Fixes
* LUCENE-6468: Fixed NPE with empty Kuromoji user dictionary.
(Jun Ohtani via Christian Moen)
+* LUCENE-6483: Ensure core closed listeners are called on the same cache key as
+ the reader which has been used to register the listener. (Adrien Grand)
+
API Changes
* LUCENE-6377: SearcherFactory#newSearcher now accepts the previous reader
Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java?rev=1680053&r1=1680052&r2=1680053&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java Mon May 18 16:27:08 2015
@@ -19,6 +19,7 @@ package org.apache.lucene.index;
import java.io.IOException;
import java.util.Iterator;
+import java.util.Objects;
import org.apache.lucene.search.CachingWrapperQuery;
import org.apache.lucene.util.AttributeSource;
@@ -305,14 +306,67 @@ public class FilterLeafReader extends Le
in.registerParentReader(this);
}
+ /**
+ * A CoreClosedListener wrapper that adjusts the core cache key that
+ * the wrapper is called with. This is useful if the core cache key
+ * of a reader is different from the key of the wrapped reader.
+ */
+ private static class CoreClosedListenerWrapper implements CoreClosedListener {
+
+ public static CoreClosedListener wrap(CoreClosedListener listener, Object thisCoreKey, Object inCoreKey) {
+ if (thisCoreKey == inCoreKey) {
+ // this reader has the same core cache key as its parent, nothing to do
+ return listener;
+ } else {
+ // we don't have the same cache key as the wrapped reader, we need to wrap
+ // the listener to call it with the correct cache key
+ return new CoreClosedListenerWrapper(listener, thisCoreKey, inCoreKey);
+ }
+ }
+
+ private final CoreClosedListener in;
+ private final Object thisCoreKey;
+ private final Object inCoreKey;
+
+ private CoreClosedListenerWrapper(CoreClosedListener in, Object thisCoreKey, Object inCoreKey) {
+ this.in = in;
+ this.thisCoreKey = thisCoreKey;
+ this.inCoreKey = inCoreKey;
+ }
+
+ @Override
+ public void onClose(Object ownerCoreCacheKey) throws IOException {
+ assert inCoreKey == ownerCoreCacheKey;
+ in.onClose(thisCoreKey);
+ }
+
+ // NOTE: equals/hashcore are important for removeCoreClosedListener to work
+ // correctly
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null || obj.getClass() != CoreClosedListenerWrapper.class) {
+ return false;
+ }
+ CoreClosedListenerWrapper that = (CoreClosedListenerWrapper) obj;
+ return in.equals(that.in) && thisCoreKey == that.thisCoreKey;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getClass(), in, thisCoreKey);
+ }
+
+ }
+
@Override
- public void addCoreClosedListener(CoreClosedListener listener) {
- in.addCoreClosedListener(listener);
+ public void addCoreClosedListener(final CoreClosedListener listener) {
+ in.addCoreClosedListener(CoreClosedListenerWrapper.wrap(listener, getCoreCacheKey(), in.getCoreCacheKey()));
}
@Override
public void removeCoreClosedListener(CoreClosedListener listener) {
- in.removeCoreClosedListener(listener);
+ in.removeCoreClosedListener(CoreClosedListenerWrapper.wrap(listener, getCoreCacheKey(), in.getCoreCacheKey()));
}
@Override
Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java?rev=1680053&r1=1680052&r2=1680053&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java Mon May 18 16:27:08 2015
@@ -79,7 +79,9 @@ public abstract class LeafReader extends
*/
public static interface CoreClosedListener {
/** Invoked when the shared core of the original {@code
- * SegmentReader} has closed. */
+ * SegmentReader} has closed. The provided {@code
+ * ownerCoreCacheKey} will be the same key as the one
+ * returned by {@link LeafReader#getCoreCacheKey()}. */
public void onClose(Object ownerCoreCacheKey) throws IOException;
}
Modified: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java?rev=1680053&r1=1680052&r2=1680053&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestIndexReaderClose.java Mon May 18 16:27:08 2015
@@ -94,7 +94,7 @@ public class TestIndexReaderClose extend
dir.close();
}
- public void testCoreListenerOnWrapper() throws IOException {
+ public void testCoreListenerOnSlowCompositeReaderWrapper() throws IOException {
RandomIndexWriter w = new RandomIndexWriter(random(), newDirectory());
final int numDocs = TestUtil.nextInt(random(), 1, 5);
for (int i = 0; i < numDocs; ++i) {
@@ -114,7 +114,57 @@ public class TestIndexReaderClose extend
AtomicInteger counter = new AtomicInteger(numListeners);
for (int i = 0; i < numListeners; ++i) {
- CountCoreListener listener = new CountCoreListener(counter);
+ CountCoreListener listener = new CountCoreListener(counter, leafReader.getCoreCacheKey());
+ listeners.add(listener);
+ leafReader.addCoreClosedListener(listener);
+ }
+ for (int i = 0; i < 100; ++i) {
+ leafReader.addCoreClosedListener(listeners.get(random().nextInt(listeners.size())));
+ }
+ final int removed = random().nextInt(numListeners);
+ Collections.shuffle(listeners, random());
+ for (int i = 0; i < removed; ++i) {
+ leafReader.removeCoreClosedListener(listeners.get(i));
+ }
+ assertEquals(numListeners, counter.get());
+ // make sure listeners are registered on the wrapped reader and that closing any of them has the same effect
+ if (random().nextBoolean()) {
+ reader.close();
+ } else {
+ leafReader.close();
+ }
+ assertEquals(removed, counter.get());
+ w.w.getDirectory().close();
+ }
+
+ public void testCoreListenerOnWrapperWithDifferentCacheKey() throws IOException {
+ RandomIndexWriter w = new RandomIndexWriter(random(), newDirectory());
+ final int numDocs = TestUtil.nextInt(random(), 1, 5);
+ for (int i = 0; i < numDocs; ++i) {
+ w.addDocument(new Document());
+ if (random().nextBoolean()) {
+ w.commit();
+ }
+ }
+ w.commit();
+ w.close();
+
+ final IndexReader reader = DirectoryReader.open(w.w.getDirectory());
+ // We explicitly define a different cache key
+ final Object coreCacheKey = new Object();
+ final LeafReader leafReader = new FilterLeafReader(SlowCompositeReaderWrapper.wrap(reader)) {
+ @Override
+ public Object getCoreCacheKey() {
+ return coreCacheKey;
+ }
+ };
+
+ final int numListeners = TestUtil.nextInt(random(), 1, 10);
+ final List<LeafReader.CoreClosedListener> listeners = new ArrayList<>();
+ AtomicInteger counter = new AtomicInteger(numListeners);
+
+ for (int i = 0; i < numListeners; ++i) {
+ CountCoreListener listener = new CountCoreListener(counter, coreCacheKey);
listeners.add(listener);
leafReader.addCoreClosedListener(listener);
}
@@ -140,13 +190,16 @@ public class TestIndexReaderClose extend
private static final class CountCoreListener implements LeafReader.CoreClosedListener {
private final AtomicInteger count;
+ private final Object coreCacheKey;
- public CountCoreListener(AtomicInteger count) {
+ public CountCoreListener(AtomicInteger count, Object coreCacheKey) {
this.count = count;
+ this.coreCacheKey = coreCacheKey;
}
@Override
public void onClose(Object coreCacheKey) {
+ assertSame(this.coreCacheKey, coreCacheKey);
count.decrementAndGet();
}
Modified: lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java?rev=1680053&r1=1680052&r2=1680053&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java Mon May 18 16:27:08 2015
@@ -47,6 +47,15 @@ public class AssertingLeafReader extends
assert in.numDocs() <= in.maxDoc();
assert in.numDeletedDocs() + in.numDocs() == in.maxDoc();
assert !in.hasDeletions() || in.numDeletedDocs() > 0 && in.numDocs() < in.maxDoc();
+
+ addCoreClosedListener(new CoreClosedListener() {
+ @Override
+ public void onClose(Object ownerCoreCacheKey) throws IOException {
+ final Object expectedKey = getCoreCacheKey();
+ assert expectedKey == ownerCoreCacheKey
+ : "Core closed listener called on a different key " + expectedKey + " <> " + ownerCoreCacheKey;
+ }
+ });
}
@Override