Index: lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java =================================================================== --- lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java (revision 1213973) +++ lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java (working copy) @@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.IdentityKeyWrapper; /** * Wraps another filter's result and caches it. The purpose is to allow @@ -37,29 +38,26 @@ // level of the readers hierarchy it should be cached. Filter filter; - protected final FilterCache cache; + protected final FilterCache cache = new FilterCache(); private final boolean recacheDeletes; - private static class FilterCache { + private static class FilterCache { + private final Map,DocIdSet>> cache = new WeakHashMap,DocIdSet>>(); - /** - * A transient Filter cache (package private because of test) - */ - private final Map> cache = new WeakHashMap>(); - - public synchronized T get(IndexReader reader, Object coreKey, Object coreSubKey) throws IOException { - Map innerCache = cache.get(coreKey); + public synchronized DocIdSet get(IndexReader reader, Object coreKey, Bits coreSubKey) throws IOException { + Map,DocIdSet> innerCache = cache.get(coreKey); if (innerCache == null) { - innerCache = new WeakHashMap(); + innerCache = new WeakHashMap,DocIdSet>(); cache.put(coreKey, innerCache); } - return innerCache.get(coreSubKey); + return innerCache.get(new IdentityKeyWrapper(coreSubKey)); } - public synchronized void put(Object coreKey, Object coreSubKey, T value) { - cache.get(coreKey).put(coreSubKey, value); + public synchronized void put(Object coreKey, Bits coreSubKey, DocIdSet value) { + cache.get(coreKey).put(new IdentityKeyWrapper(coreSubKey), value); } + } /** Wraps another filter's result and caches it. @@ -79,7 +77,6 @@ public CachingWrapperFilter(Filter filter, boolean recacheDeletes) { this.filter = filter; this.recacheDeletes = recacheDeletes; - cache = new FilterCache(); } /** Provide the DocIdSet to be cached, using the DocIdSet provided Index: lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java =================================================================== --- lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java (revision 0) +++ lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java (working copy) @@ -0,0 +1,65 @@ +package org.apache.lucene.util; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Helper class to wrap a key for a {@link java.util.Map} to be an identity key. + * You have to wrap the key on both puts and gets from the map. + * The map then behaves like {@link java.util.IdentityHashMap} + * (returns only the value if the wrapped key is identical to the one + * stored in the map (in contrast to equal). The {@code null} key + * is supported and is identical to itsself. + * It is generally used, if the user needs another map implementation than + * a simple hashed map, e.g. a {@link java.util.WeakHashMap}: + *
+ *  WeakHashMap<IdentityKeyWrapper<String>,String> map = ...
+ *  String key1 = "foo".intern();
+ *  String key2 = new String("foo");
+ *  String key3 = new String("foo");
+ *  assert key1 != key2;
+ *  assert key2 != key3;
+ *  map.put(new IdentityKeyWrapper<String>(key1), "bar1");
+ *  map.put(new IdentityKeyWrapper<String>(key2), "bar2");
+ *  assert "bar1".equals(map.get(new IdentityKeyWrapper<String>(key1)));
+ *  assert "bar2".equals(map.get(new IdentityKeyWrapper<String>(key2)));
+ *  assert map.get(new IdentityKeyWrapper<String>(key3)) == null;
+ * 
+ * @lucene.internal + */ +public final class IdentityKeyWrapper { + public final K key; + + public IdentityKeyWrapper(K key) { + this.key = key; + } + + public int hashCode() { + return System.identityHashCode(key); + } + + @SuppressWarnings("unchecked") + public boolean equals(Object o) { + if (o == this) return true; + if (o instanceof IdentityKeyWrapper) { + return ((IdentityKeyWrapper) o).key == this.key; + } + return false; + } + +} + Index: lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java =================================================================== --- lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java (revision 0) +++ lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java (working copy) Property changes on: lucene/src/java/org/apache/lucene/util/IdentityKeyWrapper.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL Added: svn:eol-style ## -0,0 +1 ## +native Index: lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java =================================================================== --- lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java (revision 0) +++ lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java (working copy) @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.util; + +import java.util.Map; +import java.util.WeakHashMap; + +public class TestIdentityKeyWrapper extends LuceneTestCase { + + public void test() { + final Map,String> map = + new WeakHashMap,String>(); + // we keep strong values of the keys, so WeakHashMap will loose them + String key1 = "foo".intern(); + String key2 = new String("foo"); + String key3 = new String("foo"); + assertNotSame(key1, key2); + assertNotSame(key1, key3); + assertNotSame(key2, key3); + + assertEquals(new IdentityKeyWrapper(key1), new IdentityKeyWrapper(key1)); + assertEquals(new IdentityKeyWrapper(key2), new IdentityKeyWrapper(key2)); + assertEquals(new IdentityKeyWrapper(key3), new IdentityKeyWrapper(key3)); + assertEquals(new IdentityKeyWrapper(key1).hashCode(), new IdentityKeyWrapper(key1).hashCode()); + assertEquals(new IdentityKeyWrapper(key2).hashCode(), new IdentityKeyWrapper(key2).hashCode()); + assertEquals(new IdentityKeyWrapper(key3).hashCode(), new IdentityKeyWrapper(key3).hashCode()); + + assertFalse(new IdentityKeyWrapper(key1).equals(new IdentityKeyWrapper(key2))); + assertFalse(new IdentityKeyWrapper(key1).equals(new IdentityKeyWrapper(key3))); + assertFalse(new IdentityKeyWrapper(key2).equals(new IdentityKeyWrapper(key3))); + assertTrue(new IdentityKeyWrapper(key1).hashCode() != new IdentityKeyWrapper(key2).hashCode()); + assertTrue(new IdentityKeyWrapper(key1).hashCode() != new IdentityKeyWrapper(key3).hashCode()); + assertTrue(new IdentityKeyWrapper(key2).hashCode() != new IdentityKeyWrapper(key3).hashCode()); + + map.put(new IdentityKeyWrapper(key1), "bar1"); + map.put(new IdentityKeyWrapper(key2), "bar2"); + assertEquals("bar1", map.get(new IdentityKeyWrapper(key1))); + assertEquals("bar2", map.get(new IdentityKeyWrapper(key2))); + assertFalse(map.containsKey(new IdentityKeyWrapper(key3))); + } + +} Index: lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java =================================================================== --- lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java (revision 0) +++ lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java (working copy) Property changes on: lucene/src/test/org/apache/lucene/util/TestIdentityKeyWrapper.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL Added: svn:eol-style ## -0,0 +1 ## +native