You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by at...@apache.org on 2019/10/02 08:26:05 UTC

[lucene-solr] branch revert-815-LUCENE-8213 created (now cd09808)

This is an automated email from the ASF dual-hosted git repository.

atri pushed a change to branch revert-815-LUCENE-8213
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git.


      at cd09808  Revert "LUCENE-8213: Introduce Asynchronous Caching in LRUQueryCache (#815)"

This branch includes the following new commits:

     new cd09808  Revert "LUCENE-8213: Introduce Asynchronous Caching in LRUQueryCache (#815)"

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[lucene-solr] 01/01: Revert "LUCENE-8213: Introduce Asynchronous Caching in LRUQueryCache (#815)"

Posted by at...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

atri pushed a commit to branch revert-815-LUCENE-8213
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit cd09808f6b54b33e350a0739dccb602cb270abad
Author: Atri Sharma <at...@gmail.com>
AuthorDate: Wed Oct 2 13:55:53 2019 +0530

    Revert "LUCENE-8213: Introduce Asynchronous Caching in LRUQueryCache (#815)"
    
    This reverts commit 0dfbf557bae67acaf9c920cb51a04b7c7341d621.
---
 lucene/CHANGES.txt                                 |   3 -
 .../org/apache/lucene/search/IndexSearcher.java    |  17 +-
 .../org/apache/lucene/search/LRUQueryCache.java    | 121 +--------
 .../java/org/apache/lucene/search/QueryCache.java  |   8 -
 .../apache/lucene/search/TestIndexSearcher.java    |   6 -
 .../apache/lucene/search/TestLRUQueryCache.java    | 299 +++++----------------
 6 files changed, 71 insertions(+), 383 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index a49a77a..5bfec58 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -55,9 +55,6 @@ Improvements
   
 * LUCENE-8984: MoreLikeThis MLT is biased for uncommon fields (Andy Hind via Anshum Gupta)
 
-* LUCENE-8213: LRUQueryCache#doCache now uses IndexSearcher's Executor (if present)
-  to asynchronously cache heavy queries (Atri Sharma)
-
 Bug fixes
 
 * LUCENE-8663: NRTCachingDirectory.slowFileExists may open a file while 
diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
index 3be9d34..e0f0cdf 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -181,16 +181,7 @@ public class IndexSearcher {
   }
 
   /** Runs searches for each segment separately, using the
-   *  provided Executor. The passed in Executor will also be
-   *  used by LRUQueryCache (if enabled) to perform asynchronous
-   *  query caching.
-   *  If a task is rejected by the host Executor, the failed task
-   *  will then be executed on the caller thread. This is done to
-   *  ensure that a query succeeds, albeit with a higher latency.
-   *  If a user wishes to modify the said behaviour, they can either
-   *  handle the exception in the provided Executor, or override
-   *  the said method in a custom extension of IndexSearcher.
-   *  NOTE:
+   *  provided Executor. NOTE:
    *  if you are using {@link NIOFSDirectory}, do not use
    *  the shutdownNow method of ExecutorService as this uses
    *  Thread.interrupt under-the-hood which can silently
@@ -850,11 +841,7 @@ public class IndexSearcher {
     final QueryCache queryCache = this.queryCache;
     Weight weight = query.createWeight(this, scoreMode, boost);
     if (scoreMode.needsScores() == false && queryCache != null) {
-      if (executor != null) {
-        weight = queryCache.doCache(weight, queryCachingPolicy, executor);
-      } else {
-        weight = queryCache.doCache(weight, queryCachingPolicy);
-      }
+      weight = queryCache.doCache(weight, queryCachingPolicy);
     }
     return weight;
   }
diff --git a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
index 24c5e98..ea3c158 100644
--- a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
+++ b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
@@ -22,16 +22,12 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
-import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Predicate;
@@ -99,11 +95,6 @@ public class LRUQueryCache implements QueryCache, Accountable {
   // maps queries that are contained in the cache to a singleton so that this
   // cache does not store several copies of the same query
   private final Map<Query, Query> uniqueQueries;
-  // Marks the inflight queries that are being asynchronously loaded into the cache
-  // This is used to ensure that multiple threads do not trigger loading
-  // of the same query in the same cache. We use a set because it is an invariant that
-  // the entries of this data structure be unique.
-  private final Set<Query> inFlightAsyncLoadQueries = new HashSet<>();
   // The contract between this set and the per-leaf caches is that per-leaf caches
   // are only allowed to store sub-sets of the queries that are contained in
   // mostRecentlyUsedQueries. This is why write operations are performed under a lock
@@ -271,7 +262,6 @@ public class LRUQueryCache implements QueryCache, Accountable {
     assert lock.isHeldByCurrentThread();
     assert key instanceof BoostQuery == false;
     assert key instanceof ConstantScoreQuery == false;
-
     final IndexReader.CacheKey readerKey = cacheHelper.getKey();
     final LeafCache leafCache = cache.get(readerKey);
     if (leafCache == null) {
@@ -378,7 +368,6 @@ public class LRUQueryCache implements QueryCache, Accountable {
         onEviction(singleton);
       }
     } finally {
-      inFlightAsyncLoadQueries.remove(query);
       lock.unlock();
     }
   }
@@ -400,7 +389,6 @@ public class LRUQueryCache implements QueryCache, Accountable {
       cache.clear();
       // Note that this also clears the uniqueQueries map since mostRecentlyUsedQueries is the uniqueQueries.keySet view:
       mostRecentlyUsedQueries.clear();
-      inFlightAsyncLoadQueries.clear();
       onClear();
     } finally {
       lock.unlock();
@@ -460,37 +448,13 @@ public class LRUQueryCache implements QueryCache, Accountable {
     }
   }
 
-  // pkg-private for testing
-  // return the list of queries being loaded asynchronously
-  List<Query> inFlightQueries() {
-    return new ArrayList<>(inFlightAsyncLoadQueries);
-  }
-
   @Override
   public Weight doCache(Weight weight, QueryCachingPolicy policy) {
-    Weight originalWeight = getOriginalWeight(weight);
-
-    return new CachingWrapperWeight(originalWeight, policy);
-  }
-
-  // Should be used only when the user wishes to trade throughput for latency
-  // This method was not merged in the method above as to not break the existing contract
-  // advertised by QueryCache
-  @Override
-  public Weight doCache(final Weight weight, QueryCachingPolicy policy, Executor executor) {
-    assert executor != null;
-    Weight originalWeight = getOriginalWeight(weight);
-
-    return new CachingWrapperWeight(originalWeight, policy, executor);
-  }
-
-  // Get original weight from the cached weight
-  private Weight getOriginalWeight(Weight weight) {
     while (weight instanceof CachingWrapperWeight) {
       weight = ((CachingWrapperWeight) weight).in;
     }
 
-    return weight;
+    return new CachingWrapperWeight(weight, policy);
   }
 
   @Override
@@ -692,21 +656,10 @@ public class LRUQueryCache implements QueryCache, Accountable {
     // threads when IndexSearcher is created with threads
     private final AtomicBoolean used;
 
-    private final Executor executor;
-
     CachingWrapperWeight(Weight in, QueryCachingPolicy policy) {
       super(in.getQuery(), 1f);
       this.in = in;
       this.policy = policy;
-      this.executor = null;
-      used = new AtomicBoolean(false);
-    }
-
-    CachingWrapperWeight(Weight in, QueryCachingPolicy policy, Executor executor) {
-      super(in.getQuery(), 1f);
-      this.in = in;
-      this.policy = policy;
-      this.executor = executor;
       used = new AtomicBoolean(false);
     }
 
@@ -779,24 +732,8 @@ public class LRUQueryCache implements QueryCache, Accountable {
 
       if (docIdSet == null) {
         if (policy.shouldCache(in.getQuery())) {
-          boolean cacheSynchronously = executor == null;
-
-          // If asynchronous caching is requested, perform the same and return
-          // the uncached iterator
-          if (cacheSynchronously == false) {
-            cacheSynchronously = cacheAsynchronously(context, cacheHelper);
-
-            // If async caching failed, synchronous caching will
-            // be performed, hence do not return the uncached value
-            if (cacheSynchronously == false) {
-              return in.scorerSupplier(context);
-            }
-          }
-
-          if (cacheSynchronously) {
-            docIdSet = cache(context);
-            putIfAbsent(in.getQuery(), docIdSet, cacheHelper);
-          }
+          docIdSet = cache(context);
+          putIfAbsent(in.getQuery(), docIdSet, cacheHelper);
         } else {
           return in.scorerSupplier(context);
         }
@@ -876,23 +813,8 @@ public class LRUQueryCache implements QueryCache, Accountable {
 
       if (docIdSet == null) {
         if (policy.shouldCache(in.getQuery())) {
-          boolean cacheSynchronously = executor == null;
-          // If asynchronous caching is requested, perform the same and return
-          // the uncached iterator
-          if (cacheSynchronously == false) {
-            cacheSynchronously = cacheAsynchronously(context, cacheHelper);
-
-            // If async caching failed, we will perform synchronous caching
-            // hence do not return the uncached value here
-            if (cacheSynchronously == false) {
-              return in.bulkScorer(context);
-            }
-          }
-
-          if (cacheSynchronously) {
-            docIdSet = cache(context);
-            putIfAbsent(in.getQuery(), docIdSet, cacheHelper);
-          }
+          docIdSet = cache(context);
+          putIfAbsent(in.getQuery(), docIdSet, cacheHelper);
         } else {
           return in.bulkScorer(context);
         }
@@ -910,38 +832,5 @@ public class LRUQueryCache implements QueryCache, Accountable {
       return new DefaultBulkScorer(new ConstantScoreScorer(this, 0f, ScoreMode.COMPLETE_NO_SCORES, disi));
     }
 
-    // Perform a cache load asynchronously
-    // @return true if synchronous caching is needed, false otherwise
-    private boolean cacheAsynchronously(LeafReaderContext context, IndexReader.CacheHelper cacheHelper) {
-      /*
-       * If the current query is already being asynchronously cached,
-       * do not trigger another cache operation
-       */
-      if (inFlightAsyncLoadQueries.add(in.getQuery()) == false) {
-        return false;
-      }
-
-      FutureTask<Void> task = new FutureTask<>(() -> {
-        DocIdSet localDocIdSet = cache(context);
-        putIfAbsent(in.getQuery(), localDocIdSet, cacheHelper);
-
-        // Remove the key from inflight -- the key is loaded now
-        Object retValue = inFlightAsyncLoadQueries.remove(in.getQuery());
-
-        // The query should have been present in the inflight queries set before
-        // we actually loaded it -- hence the removal of the key should be successful
-        assert retValue != null;
-
-        return null;
-      });
-      try {
-        executor.execute(task);
-      } catch (RejectedExecutionException e) {
-        // Trigger synchronous caching
-        return true;
-      }
-
-      return false;
-    }
   }
 }
diff --git a/lucene/core/src/java/org/apache/lucene/search/QueryCache.java b/lucene/core/src/java/org/apache/lucene/search/QueryCache.java
index 9b829ec..94e34ee 100644
--- a/lucene/core/src/java/org/apache/lucene/search/QueryCache.java
+++ b/lucene/core/src/java/org/apache/lucene/search/QueryCache.java
@@ -17,8 +17,6 @@
 package org.apache.lucene.search;
 
 
-import java.util.concurrent.Executor;
-
 /**
  * A cache for queries.
  *
@@ -35,10 +33,4 @@ public interface QueryCache {
    */
   Weight doCache(Weight weight, QueryCachingPolicy policy);
 
-  /**
-   * Same as above, but allows passing in an Executor to perform caching
-   * asynchronously
-   */
-  Weight doCache(Weight weight, QueryCachingPolicy policy, Executor executor);
-
 }
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java b/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
index f5c58a5..6617c60 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestIndexSearcher.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -190,11 +189,6 @@ public class TestIndexSearcher extends LuceneTestCase {
     QueryCache dummyCache = new QueryCache() {
       @Override
       public Weight doCache(Weight weight, QueryCachingPolicy policy) {
-        return doCache(weight, policy, null);
-      }
-
-      @Override
-      public Weight doCache(Weight weight, QueryCachingPolicy policy, Executor executor) {
         return weight;
       }
     };
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
index 55e0fd9..41ebf1b 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
@@ -30,11 +30,6 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
@@ -64,7 +59,6 @@ import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.Constants;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.NamedThreadFactory;
 import org.apache.lucene.util.RamUsageTester;
 import org.apache.lucene.util.TestUtil;
 
@@ -102,9 +96,6 @@ public class TestLRUQueryCache extends LuceneTestCase {
     final LRUQueryCache queryCache = new LRUQueryCache(1 + random().nextInt(20), 1 + random().nextInt(10000), context -> random().nextBoolean());
     Directory dir = newDirectory();
     final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
-    ExecutorService service = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS,
-        new LinkedBlockingQueue<Runnable>(),
-        new NamedThreadFactory("TestLRUQueryCache"));
     final SearcherFactory searcherFactory = new SearcherFactory() {
       @Override
       public IndexSearcher newSearcher(IndexReader reader, IndexReader previous) throws IOException {
@@ -114,103 +105,87 @@ public class TestLRUQueryCache extends LuceneTestCase {
         return searcher;
       }
     };
-    final SearcherFactory concurrentSearcherFactory = new SearcherFactory() {
-      @Override
-      public IndexSearcher newSearcher(IndexReader reader, IndexReader previous) throws IOException {
-        IndexSearcher searcher = new IndexSearcher(reader, service);
-        searcher.setQueryCachingPolicy(MAYBE_CACHE_POLICY);
-        searcher.setQueryCache(queryCache);
-        return searcher;
+    final boolean applyDeletes = random().nextBoolean();
+    final SearcherManager mgr = new SearcherManager(w.w, applyDeletes, false, searcherFactory);
+    final AtomicBoolean indexing = new AtomicBoolean(true);
+    final AtomicReference<Throwable> error = new AtomicReference<>();
+    final int numDocs = atLeast(10000);
+    Thread[] threads = new Thread[3];
+    threads[0] = new Thread() {
+      public void run() {
+        Document doc = new Document();
+        StringField f = new StringField("color", "", Store.NO);
+        doc.add(f);
+        for (int i = 0; indexing.get() && i < numDocs; ++i) {
+          f.setStringValue(RandomPicks.randomFrom(random(), new String[] {"blue", "red", "yellow"}));
+          try {
+            w.addDocument(doc);
+            if ((i & 63) == 0) {
+              mgr.maybeRefresh();
+              if (rarely()) {
+                queryCache.clear();
+              }
+              if (rarely()) {
+                final String color = RandomPicks.randomFrom(random(), new String[] {"blue", "red", "yellow"});
+                w.deleteDocuments(new Term("color", color));
+              }
+            }
+          } catch (Throwable t) {
+            error.compareAndSet(null, t);
+            break;
+          }
+        }
+        indexing.set(false);
       }
     };
-
-    final SearcherFactory[] searcherFactories = {searcherFactory, concurrentSearcherFactory};
-
-    for (SearcherFactory currentSearcherFactory : searcherFactories) {
-      final boolean applyDeletes = random().nextBoolean();
-      final SearcherManager mgr = new SearcherManager(w.w, applyDeletes, false, currentSearcherFactory);
-      final AtomicBoolean indexing = new AtomicBoolean(true);
-      final AtomicReference<Throwable> error = new AtomicReference<>();
-      final int numDocs = atLeast(10000);
-      Thread[] threads = new Thread[3];
-      threads[0] = new Thread() {
+    for (int i = 1; i < threads.length; ++i) {
+      threads[i] = new Thread() {
+        @Override
         public void run() {
-          Document doc = new Document();
-          StringField f = new StringField("color", "", Store.NO);
-          doc.add(f);
-          for (int i = 0; indexing.get() && i < numDocs; ++i) {
-            f.setStringValue(RandomPicks.randomFrom(random(), new String[]{"blue", "red", "yellow"}));
+          while (indexing.get()) {
             try {
-              w.addDocument(doc);
-              if ((i & 63) == 0) {
-                mgr.maybeRefresh();
-                if (rarely()) {
-                  queryCache.clear();
-                }
-                if (rarely()) {
-                  final String color = RandomPicks.randomFrom(random(), new String[]{"blue", "red", "yellow"});
-                  w.deleteDocuments(new Term("color", color));
-                }
+              final IndexSearcher searcher = mgr.acquire();
+              try {
+                final String value = RandomPicks.randomFrom(random(), new String[] {"blue", "red", "yellow", "green"});
+                final Query q = new TermQuery(new Term("color", value));
+                TotalHitCountCollector collector = new TotalHitCountCollector();
+                searcher.search(q, collector); // will use the cache
+                final int totalHits1 = collector.getTotalHits();
+                TotalHitCountCollector collector2 = new TotalHitCountCollector();
+                searcher.search(q, new FilterCollector(collector2) {
+                  public ScoreMode scoreMode() {
+                    return ScoreMode.COMPLETE; // will not use the cache because of scores
+                  }
+                });
+                final long totalHits2 = collector2.getTotalHits();
+                assertEquals(totalHits2, totalHits1);
+              } finally {
+                mgr.release(searcher);
               }
             } catch (Throwable t) {
               error.compareAndSet(null, t);
-              break;
             }
           }
-          indexing.set(false);
         }
       };
-      for (int i = 1; i < threads.length; ++i) {
-        threads[i] = new Thread() {
-          @Override
-          public void run() {
-            while (indexing.get()) {
-              try {
-                final IndexSearcher searcher = mgr.acquire();
-                try {
-                  final String value = RandomPicks.randomFrom(random(), new String[]{"blue", "red", "yellow", "green"});
-                  final Query q = new TermQuery(new Term("color", value));
-                  TotalHitCountCollector collector = new TotalHitCountCollector();
-                  searcher.search(q, collector); // will use the cache
-                  final int totalHits1 = collector.getTotalHits();
-                  TotalHitCountCollector collector2 = new TotalHitCountCollector();
-                  searcher.search(q, new FilterCollector(collector2) {
-                    public ScoreMode scoreMode() {
-                      return ScoreMode.COMPLETE; // will not use the cache because of scores
-                    }
-                  });
-                  final long totalHits2 = collector2.getTotalHits();
-                  assertEquals(totalHits2, totalHits1);
-                } finally {
-                  mgr.release(searcher);
-                }
-              } catch (Throwable t) {
-                error.compareAndSet(null, t);
-              }
-            }
-          }
-        };
-      }
-
-      for (Thread thread : threads) {
-        thread.start();
-      }
+    }
 
-      for (Thread thread : threads) {
-        thread.join();
-      }
+    for (Thread thread : threads) {
+      thread.start();
+    }
 
-      if (error.get() != null) {
-        throw error.get();
-      }
-      queryCache.assertConsistent();
-      mgr.close();
+    for (Thread thread : threads) {
+      thread.join();
     }
 
+    if (error.get() != null) {
+      throw error.get();
+    }
+    queryCache.assertConsistent();
+    mgr.close();
     w.close();
     dir.close();
     queryCache.assertConsistent();
-    service.shutdown();
   }
 
   public void testLRUEviction() throws Exception {
@@ -226,9 +201,7 @@ public class TestLRUQueryCache extends LuceneTestCase {
     f.setStringValue("green");
     w.addDocument(doc);
     final DirectoryReader reader = w.getReader();
-
-    IndexSearcher searcher = newSearcher(reader);
-
+    final IndexSearcher searcher = newSearcher(reader);
     final LRUQueryCache queryCache = new LRUQueryCache(2, 100000, context -> true);
 
     final Query blue = new TermQuery(new Term("color", "blue"));
@@ -299,150 +272,6 @@ public class TestLRUQueryCache extends LuceneTestCase {
     dir.close();
   }
 
-  public void testLRUConcurrentLoadAndEviction() throws Exception {
-    Directory dir = newDirectory();
-    final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
-
-    Document doc = new Document();
-    StringField f = new StringField("color", "blue", Store.NO);
-    doc.add(f);
-    w.addDocument(doc);
-    f.setStringValue("red");
-    w.addDocument(doc);
-    f.setStringValue("green");
-    w.addDocument(doc);
-    final DirectoryReader reader = w.getReader();
-    ExecutorService service = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS,
-        new LinkedBlockingQueue<Runnable>(),
-        new NamedThreadFactory("TestLRUQueryCache"));
-
-    IndexSearcher searcher = new IndexSearcher(reader, service);
-
-    final LRUQueryCache queryCache = new LRUQueryCache(2, 100000, context -> true);
-
-    final Query blue = new TermQuery(new Term("color", "blue"));
-    final Query red = new TermQuery(new Term("color", "red"));
-    final Query green = new TermQuery(new Term("color", "green"));
-
-    assertEquals(Collections.emptyList(), queryCache.cachedQueries());
-
-    searcher.setQueryCache(queryCache);
-    // the filter is not cached on any segment: no changes
-    searcher.setQueryCachingPolicy(NEVER_CACHE);
-    searcher.search(new ConstantScoreQuery(green), 1);
-    assertEquals(Collections.emptyList(), queryCache.cachedQueries());
-
-    searcher.setQueryCachingPolicy(ALWAYS_CACHE);
-    // First read should miss
-    searcher.search(new ConstantScoreQuery(red), 1);
-
-    if (!(queryCache.cachedQueries().equals(Collections.emptyList()))) {
-      searcher.search(new ConstantScoreQuery(red), 1);
-    } else {
-      // Let the cache load be completed
-      Thread.sleep(200);
-      searcher.search(new ConstantScoreQuery(red), 1);
-    }
-
-    // Second read should hit
-    searcher.search(new ConstantScoreQuery(red), 1);
-    assertEquals(Collections.singletonList(red), queryCache.cachedQueries());
-
-    searcher.search(new ConstantScoreQuery(green), 1);
-    if (!(queryCache.cachedQueries().equals(Arrays.asList(red)))) {
-      assertEquals(Arrays.asList(red, green), queryCache.cachedQueries());
-    } else {
-      // Let the cache load be completed
-      Thread.sleep(200);
-      assertEquals(Arrays.asList(red, green), queryCache.cachedQueries());
-    }
-
-    searcher.search(new ConstantScoreQuery(red), 1);
-    assertEquals(Arrays.asList(green, red), queryCache.cachedQueries());
-
-    searcher.search(new ConstantScoreQuery(blue), 1);
-    if (!(queryCache.cachedQueries().equals(Arrays.asList(green, red)))) {
-      assertEquals(Arrays.asList(red, blue), queryCache.cachedQueries());
-    } else {
-      // Let the cache load be completed
-      Thread.sleep(200);
-      assertEquals(Arrays.asList(red, blue), queryCache.cachedQueries());
-    }
-
-    searcher.search(new ConstantScoreQuery(blue), 1);
-    assertEquals(Arrays.asList(red, blue), queryCache.cachedQueries());
-
-    searcher.search(new ConstantScoreQuery(green), 1);
-    if (!(queryCache.cachedQueries().equals(Arrays.asList(red, blue)))) {
-      assertEquals(Arrays.asList(blue, green), queryCache.cachedQueries());
-    } else {
-      // Let the cache load be completed
-      Thread.sleep(200);
-      assertEquals(Arrays.asList(blue, green), queryCache.cachedQueries());
-    }
-
-    searcher.setQueryCachingPolicy(NEVER_CACHE);
-    searcher.search(new ConstantScoreQuery(red), 1);
-    assertEquals(Arrays.asList(blue, green), queryCache.cachedQueries());
-
-    reader.close();
-    w.close();
-    dir.close();
-    service.shutdown();
-  }
-
-  public void testLRUConcurrentLoadsOfSameQuery() throws Exception {
-    Directory dir = newDirectory();
-    final RandomIndexWriter w = new RandomIndexWriter(random(), dir);
-
-    Document doc = new Document();
-    StringField f = new StringField("color", "blue", Store.NO);
-    doc.add(f);
-    w.addDocument(doc);
-    f.setStringValue("red");
-    w.addDocument(doc);
-    f.setStringValue("green");
-    w.addDocument(doc);
-    final DirectoryReader reader = w.getReader();
-    ExecutorService service = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS,
-        new LinkedBlockingQueue<Runnable>(),
-        new NamedThreadFactory("TestLRUQueryCache"));
-
-    ExecutorService stressService = new ThreadPoolExecutor(15, 15, 0L, TimeUnit.MILLISECONDS,
-        new LinkedBlockingQueue<Runnable>(),
-        new NamedThreadFactory("TestLRUQueryCache2"));
-
-    IndexSearcher searcher = new IndexSearcher(reader, service);
-
-    final LRUQueryCache queryCache = new LRUQueryCache(2, 100000, context -> true);
-
-    final Query green = new TermQuery(new Term("color", "green"));
-
-    assertEquals(Collections.emptyList(), queryCache.cachedQueries());
-
-    searcher.setQueryCache(queryCache);
-    searcher.setQueryCachingPolicy(ALWAYS_CACHE);
-
-    FutureTask<Void> task = new FutureTask<>(() -> {
-      searcher.search(new ConstantScoreQuery(green), 1);
-      assertEquals(1, queryCache.inFlightQueries().size());
-      return null;
-    });
-
-    for (int i = 0; i < 5; i++) {
-      stressService.submit(task);
-    }
-
-    Thread.sleep(3000);
-    assertEquals(Arrays.asList(green), queryCache.cachedQueries());
-
-    reader.close();
-    w.close();
-    dir.close();
-    service.shutdown();
-    stressService.shutdown();
-  }
-
   public void testClearFilter() throws IOException {
     Directory dir = newDirectory();
     final RandomIndexWriter w = new RandomIndexWriter(random(), dir);