4747import java .util .Collection ;
4848import java .util .Collections ;
4949import java .util .Iterator ;
50+ import java .util .Objects ;
5051import java .util .Set ;
5152import java .util .concurrent .ConcurrentMap ;
5253import java .util .function .Supplier ;
5354
5455/**
5556 * The indices request cache allows to cache a shard level request stage responses, helping with improving
5657 * similar requests that are potentially expensive (because of aggs for example). The cache is fully coherent
57- * with the semantics of NRT (the index reader version is part of the cache key), and relies on size based
58+ * with the semantics of NRT (the index reader cache key is part of the cache key), and relies on size based
5859 * eviction to evict old reader associated cache entries as well as scheduler reaper to clean readers that
5960 * are no longer used or closed shards.
6061 * <p>
@@ -105,7 +106,7 @@ public void close() {
105106 }
106107
107108 void clear (CacheEntity entity ) {
108- keysToClean .add (new CleanupKey (entity , - 1 ));
109+ keysToClean .add (new CleanupKey (entity , null ));
109110 cleanCache ();
110111 }
111112
@@ -119,7 +120,8 @@ public void onRemoval(RemovalNotification<Key, BytesReference> notification) {
119120 // removed when this issue is solved
120121 BytesReference getOrCompute (CacheEntity cacheEntity , Supplier <BytesReference > loader ,
121122 DirectoryReader reader , BytesReference cacheKey , Supplier <String > cacheKeyRenderer ) throws Exception {
122- final Key key = new Key (cacheEntity , reader .getVersion (), cacheKey );
123+ assert reader .getReaderCacheHelper () != null ;
124+ final Key key = new Key (cacheEntity , reader .getReaderCacheHelper ().getKey (), cacheKey );
123125 Loader cacheLoader = new Loader (cacheEntity , loader );
124126 BytesReference value = cache .computeIfAbsent (key , cacheLoader );
125127 if (cacheLoader .isLoaded ()) {
@@ -128,7 +130,7 @@ BytesReference getOrCompute(CacheEntity cacheEntity, Supplier<BytesReference> lo
128130 logger .trace ("Cache miss for reader version [{}] and request:\n {}" , reader .getVersion (), cacheKeyRenderer .get ());
129131 }
130132 // see if its the first time we see this reader, and make sure to register a cleanup key
131- CleanupKey cleanupKey = new CleanupKey (cacheEntity , reader .getVersion ());
133+ CleanupKey cleanupKey = new CleanupKey (cacheEntity , reader .getReaderCacheHelper (). getKey ());
132134 if (!registeredClosedListeners .containsKey (cleanupKey )) {
133135 Boolean previous = registeredClosedListeners .putIfAbsent (cleanupKey , Boolean .TRUE );
134136 if (previous == null ) {
@@ -151,7 +153,8 @@ BytesReference getOrCompute(CacheEntity cacheEntity, Supplier<BytesReference> lo
151153 * @param cacheKey the cache key to invalidate
152154 */
153155 void invalidate (CacheEntity cacheEntity , DirectoryReader reader , BytesReference cacheKey ) {
154- cache .invalidate (new Key (cacheEntity , reader .getVersion (), cacheKey ));
156+ assert reader .getReaderCacheHelper () != null ;
157+ cache .invalidate (new Key (cacheEntity , reader .getReaderCacheHelper ().getKey (), cacheKey ));
155158 }
156159
157160 private static class Loader implements CacheLoader <Key , BytesReference > {
@@ -220,12 +223,12 @@ static class Key implements Accountable {
220223 private static final long BASE_RAM_BYTES_USED = RamUsageEstimator .shallowSizeOfInstance (Key .class );
221224
222225 public final CacheEntity entity ; // use as identity equality
223- public final long readerVersion ; // use the reader version to now keep a reference to a "short" lived reader until its reaped
226+ public final IndexReader . CacheKey readerCacheKey ;
224227 public final BytesReference value ;
225228
226- Key (CacheEntity entity , long readerVersion , BytesReference value ) {
229+ Key (CacheEntity entity , IndexReader . CacheKey readerCacheKey , BytesReference value ) {
227230 this .entity = entity ;
228- this .readerVersion = readerVersion ;
231+ this .readerCacheKey = Objects . requireNonNull ( readerCacheKey ) ;
229232 this .value = value ;
230233 }
231234
@@ -245,7 +248,7 @@ public boolean equals(Object o) {
245248 if (this == o ) return true ;
246249 if (o == null || getClass () != o .getClass ()) return false ;
247250 Key key = (Key ) o ;
248- if (readerVersion != key .readerVersion ) return false ;
251+ if (Objects . equals ( readerCacheKey , key .readerCacheKey ) == false ) return false ;
249252 if (!entity .getCacheIdentity ().equals (key .entity .getCacheIdentity ())) return false ;
250253 if (!value .equals (key .value )) return false ;
251254 return true ;
@@ -254,19 +257,19 @@ public boolean equals(Object o) {
254257 @ Override
255258 public int hashCode () {
256259 int result = entity .getCacheIdentity ().hashCode ();
257- result = 31 * result + Long .hashCode (readerVersion );
260+ result = 31 * result + readerCacheKey .hashCode ();
258261 result = 31 * result + value .hashCode ();
259262 return result ;
260263 }
261264 }
262265
263266 private class CleanupKey implements IndexReader .ClosedListener {
264267 final CacheEntity entity ;
265- final long readerVersion ; // use the reader version to now keep a reference to a "short" lived reader until its reaped
268+ final IndexReader . CacheKey readerCacheKey ;
266269
267- private CleanupKey (CacheEntity entity , long readerVersion ) {
270+ private CleanupKey (CacheEntity entity , IndexReader . CacheKey readerCacheKey ) {
268271 this .entity = entity ;
269- this .readerVersion = readerVersion ;
272+ this .readerCacheKey = readerCacheKey ;
270273 }
271274
272275 @ Override
@@ -284,15 +287,15 @@ public boolean equals(Object o) {
284287 return false ;
285288 }
286289 CleanupKey that = (CleanupKey ) o ;
287- if (readerVersion != that .readerVersion ) return false ;
290+ if (Objects . equals ( readerCacheKey , that .readerCacheKey ) == false ) return false ;
288291 if (!entity .getCacheIdentity ().equals (that .entity .getCacheIdentity ())) return false ;
289292 return true ;
290293 }
291294
292295 @ Override
293296 public int hashCode () {
294297 int result = entity .getCacheIdentity ().hashCode ();
295- result = 31 * result + Long .hashCode (readerVersion );
298+ result = 31 * result + Objects .hashCode (readerCacheKey );
296299 return result ;
297300 }
298301 }
@@ -307,7 +310,7 @@ synchronized void cleanCache() {
307310 for (Iterator <CleanupKey > iterator = keysToClean .iterator (); iterator .hasNext (); ) {
308311 CleanupKey cleanupKey = iterator .next ();
309312 iterator .remove ();
310- if (cleanupKey .readerVersion == - 1 || cleanupKey .entity .isOpen () == false ) {
313+ if (cleanupKey .readerCacheKey == null || cleanupKey .entity .isOpen () == false ) {
311314 // -1 indicates full cleanup, as does a closed shard
312315 currentFullClean .add (cleanupKey .entity .getCacheIdentity ());
313316 } else {
@@ -320,7 +323,7 @@ synchronized void cleanCache() {
320323 if (currentFullClean .contains (key .entity .getCacheIdentity ())) {
321324 iterator .remove ();
322325 } else {
323- if (currentKeysToClean .contains (new CleanupKey (key .entity , key .readerVersion ))) {
326+ if (currentKeysToClean .contains (new CleanupKey (key .entity , key .readerCacheKey ))) {
324327 iterator .remove ();
325328 }
326329 }
0 commit comments