@@ -151,8 +151,8 @@ public DocumentSubsetBitsetCache(Settings settings, ThreadPool threadPool) {
151151 }
152152
153153 @ Override
154- public void onClose (IndexReader .CacheKey ownerCoreCacheKey ) {
155- final Set <BitsetCacheKey > keys = keysByIndex .remove (ownerCoreCacheKey );
154+ public void onClose (IndexReader .CacheKey indexKey ) {
155+ final Set <BitsetCacheKey > keys = keysByIndex .remove (indexKey );
156156 if (keys != null ) {
157157 // Because this Set has been removed from the map, and the only update to the set is performed in a
158158 // Map#compute call, it should not be possible to get a concurrent modification here.
@@ -164,10 +164,10 @@ public void onClose(IndexReader.CacheKey ownerCoreCacheKey) {
164164 * Cleanup (synchronize) the internal state when an object is removed from the primary cache
165165 */
166166 private void onCacheEviction (RemovalNotification <BitsetCacheKey , BitSet > notification ) {
167- final BitsetCacheKey bitsetKey = notification .getKey ();
168- final IndexReader .CacheKey indexKey = bitsetKey . index ;
169- if (keysByIndex .getOrDefault (indexKey , Set .of ()).contains (bitsetKey ) == false ) {
170- // If the bitsetKey isn't in the lookup map, then there's nothing to synchronize
167+ final BitsetCacheKey cacheKey = notification .getKey ();
168+ final IndexReader .CacheKey indexKey = cacheKey . indexKey ;
169+ if (keysByIndex .getOrDefault (indexKey , Set .of ()).contains (cacheKey ) == false ) {
170+ // If the cacheKey isn't in the lookup map, then there's nothing to synchronize
171171 return ;
172172 }
173173 // We push this to a background thread, so that it reduces the risk of blocking searches, but also so that the lock management is
@@ -177,9 +177,9 @@ private void onCacheEviction(RemovalNotification<BitsetCacheKey, BitSet> notific
177177 cleanupExecutor .submit (() -> {
178178 try (ReleasableLock ignored = cacheEvictionLock .acquire ()) {
179179 // it's possible for the key to be back in the cache if it was immediately repopulated after it was evicted, so check
180- if (bitsetCache .get (bitsetKey ) == null ) {
180+ if (bitsetCache .get (cacheKey ) == null ) {
181181 // key is no longer in the cache, make sure it is no longer in the lookup map either.
182- Optional .ofNullable (keysByIndex .get (indexKey )).ifPresent (set -> set .remove (bitsetKey ));
182+ Optional .ofNullable (keysByIndex .get (indexKey )).ifPresent (set -> set .remove (cacheKey ));
183183 }
184184 }
185185 });
@@ -325,12 +325,17 @@ public Map<String, Object> usageStats() {
325325
326326 private static final class BitsetCacheKey {
327327
328- final IndexReader .CacheKey index ;
328+ final IndexReader .CacheKey indexKey ;
329329 final Query query ;
330+ final int hashCode ;
330331
331- private BitsetCacheKey (IndexReader .CacheKey index , Query query ) {
332- this .index = index ;
332+ private BitsetCacheKey (IndexReader .CacheKey indexKey , Query query ) {
333+ this .indexKey = indexKey ;
333334 this .query = query ;
335+ // compute the hashCode eagerly, since it's used multiple times in the cache implementation anyway -- the query here will
336+ // be a ConstantScoreQuery around a BooleanQuery, and BooleanQuery already *lazily* caches the hashCode, so this isn't
337+ // altogether that much faster in reality, but it makes it more explicit here that we're doing this
338+ this .hashCode = computeHashCode ();
334339 }
335340
336341 @ Override
@@ -342,17 +347,23 @@ public boolean equals(Object other) {
342347 return false ;
343348 }
344349 final BitsetCacheKey that = (BitsetCacheKey ) other ;
345- return Objects .equals (this .index , that .index ) && Objects .equals (this .query , that .query );
350+ return Objects .equals (this .indexKey , that .indexKey ) && Objects .equals (this .query , that .query );
351+ }
352+
353+ private int computeHashCode () {
354+ int result = indexKey .hashCode ();
355+ result = 31 * result + query .hashCode ();
356+ return result ;
346357 }
347358
348359 @ Override
349360 public int hashCode () {
350- return Objects . hash ( index , query ) ;
361+ return hashCode ;
351362 }
352363
353364 @ Override
354365 public String toString () {
355- return getClass ().getSimpleName () + "(" + index + "," + query + ")" ;
366+ return getClass ().getSimpleName () + "(" + indexKey + "," + query + ")" ;
356367 }
357368 }
358369
@@ -362,15 +373,15 @@ public String toString() {
362373 */
363374 void verifyInternalConsistency () {
364375 this .bitsetCache .keys ().forEach (bck -> {
365- final Set <BitsetCacheKey > set = this .keysByIndex .get (bck .index );
376+ final Set <BitsetCacheKey > set = this .keysByIndex .get (bck .indexKey );
366377 if (set == null ) {
367378 throw new IllegalStateException (
368- "Key [" + bck + "] is in the cache, but there is no entry for [" + bck .index + "] in the lookup map"
379+ "Key [" + bck + "] is in the cache, but there is no entry for [" + bck .indexKey + "] in the lookup map"
369380 );
370381 }
371382 if (set .contains (bck ) == false ) {
372383 throw new IllegalStateException (
373- "Key [" + bck + "] is in the cache, but the lookup entry for [" + bck .index + "] does not contain that key"
384+ "Key [" + bck + "] is in the cache, but the lookup entry for [" + bck .indexKey + "] does not contain that key"
374385 );
375386 }
376387 });
0 commit comments