You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2020/05/30 01:44:58 UTC

[lucene-solr] branch master updated: SOLR-14494: Refactor BlockJoin to not use Filter (#1523)

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

dsmiley pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/master by this push:
     new a6a02ac  SOLR-14494: Refactor BlockJoin to not use Filter (#1523)
a6a02ac is described below

commit a6a02ac0e5116f4cf061fd3afeb930c3cc379f5a
Author: David Smiley <ds...@apache.org>
AuthorDate: Fri May 29 21:44:44 2020 -0400

    SOLR-14494: Refactor BlockJoin to not use Filter (#1523)
    
    Note: henceforth the perSegFilter cache will internally have values of type BitSetProducer instead of Filter.
---
 .../solr/search/facet/UniqueBlockQueryAgg.java     |   4 +-
 .../solr/search/join/BlockJoinChildQParser.java    |   7 +-
 .../solr/search/join/BlockJoinParentQParser.java   | 105 ++++++++++-----------
 .../search/join/ChildFieldValueSourceParser.java   |   4 +-
 .../join/another/BJQFilterAccessibleTest.java      |   2 +-
 5 files changed, 56 insertions(+), 66 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/search/facet/UniqueBlockQueryAgg.java b/solr/core/src/java/org/apache/solr/search/facet/UniqueBlockQueryAgg.java
index 885725d..0df743d 100644
--- a/solr/core/src/java/org/apache/solr/search/facet/UniqueBlockQueryAgg.java
+++ b/solr/core/src/java/org/apache/solr/search/facet/UniqueBlockQueryAgg.java
@@ -25,7 +25,7 @@ import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BitSet;
 
-import static org.apache.solr.search.join.BlockJoinParentQParser.getCachedFilter;
+import static org.apache.solr.search.join.BlockJoinParentQParser.getCachedBitSetProducer;
 
 public class UniqueBlockQueryAgg extends UniqueBlockAgg {
 
@@ -42,7 +42,7 @@ public class UniqueBlockQueryAgg extends UniqueBlockAgg {
 
     @Override
     public void setNextReader(LeafReaderContext readerContext) throws IOException {
-      this.parentBitSet = getCachedFilter(fcontext.req, query).getFilter().getBitSet(readerContext);
+      this.parentBitSet = getCachedBitSetProducer(fcontext.req, query).getBitSet(readerContext);
     }
 
     @Override
diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinChildQParser.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinChildQParser.java
index 2c005ac..b24e3e4 100644
--- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinChildQParser.java
+++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinChildQParser.java
@@ -23,7 +23,6 @@ import org.apache.lucene.search.Query;
 import org.apache.lucene.search.join.ToChildBlockJoinQuery;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SyntaxError;
 
 public class BlockJoinChildQParser extends BlockJoinParentQParser {
@@ -34,7 +33,7 @@ public class BlockJoinChildQParser extends BlockJoinParentQParser {
 
   @Override
   protected Query createQuery(Query parentListQuery, Query query, String scoreMode) {
-    return new ToChildBlockJoinQuery(query, getFilter(parentListQuery).getFilter());
+    return new ToChildBlockJoinQuery(query, getBitSetProducer(parentListQuery));
   }
 
   @Override
@@ -49,8 +48,6 @@ public class BlockJoinChildQParser extends BlockJoinParentQParser {
         .add(new MatchAllDocsQuery(), Occur.MUST)
         .add(parents, Occur.MUST_NOT)
       .build();
-    SolrConstantScoreQuery wrapped = new SolrConstantScoreQuery(getFilter(notParents));
-    wrapped.setCache(false);
-    return wrapped;
+    return new BitSetProducerQuery(getBitSetProducer(notParents));
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java
index 416c9f3..151062f 100644
--- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java
+++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinParentQParser.java
@@ -20,22 +20,25 @@ import java.io.IOException;
 import java.util.Objects;
 
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.ConstantScoreScorer;
+import org.apache.lucene.search.ConstantScoreWeight;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.join.BitSetProducer;
 import org.apache.lucene.search.join.QueryBitSetProducer;
 import org.apache.lucene.search.join.ScoreMode;
 import org.apache.lucene.search.join.ToParentBlockJoinQuery;
-import org.apache.lucene.util.BitDocIdSet;
 import org.apache.lucene.util.BitSet;
-import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BitSetIterator;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.search.BitsFilteredDocIdSet;
-import org.apache.solr.search.Filter;
+import org.apache.solr.search.ExtendedQueryBase;
 import org.apache.solr.search.QParser;
 import org.apache.solr.search.SolrCache;
-import org.apache.solr.search.SolrConstantScoreQuery;
 import org.apache.solr.search.SyntaxError;
 
 public class BlockJoinParentQParser extends FiltersQParser {
@@ -71,42 +74,26 @@ public class BlockJoinParentQParser extends FiltersQParser {
 
   @Override
   protected Query noClausesQuery() throws SyntaxError {
-    SolrConstantScoreQuery wrapped = new SolrConstantScoreQuery(getFilter(parseParentFilter()));
-    wrapped.setCache(false);
-    return wrapped;
+    return new BitSetProducerQuery(getBitSetProducer(parseParentFilter()));
   }
 
   protected Query createQuery(final Query parentList, Query query, String scoreMode) throws SyntaxError {
-    return new AllParentsAware(query, getFilter(parentList).filter, ScoreModeParser.parse(scoreMode), parentList);
+    return new AllParentsAware(query, getBitSetProducer(parentList), ScoreModeParser.parse(scoreMode), parentList);
   }
 
-  BitDocIdSetFilterWrapper getFilter(Query parentList) {
-    return getCachedFilter(req, parentList);
+  BitSetProducer getBitSetProducer(Query query) {
+    return getCachedBitSetProducer(req, query);
   }
 
-  public static BitDocIdSetFilterWrapper getCachedFilter(final SolrQueryRequest request, Query parentList) {
+  public static BitSetProducer getCachedBitSetProducer(final SolrQueryRequest request, Query query) {
     @SuppressWarnings("unchecked")
-    SolrCache<Query, Filter> parentCache = request.getSearcher().getCache(CACHE_NAME);
+    SolrCache<Query, BitSetProducer> parentCache = request.getSearcher().getCache(CACHE_NAME);
     // lazily retrieve from solr cache
-    BitDocIdSetFilterWrapper result;
     if (parentCache != null) {
-      Filter filter = parentCache.computeIfAbsent(parentList,
-          query -> new BitDocIdSetFilterWrapper(createParentFilter(query)));
-      if (filter instanceof BitDocIdSetFilterWrapper) {
-        result = (BitDocIdSetFilterWrapper) filter;
-      } else {
-        result = new BitDocIdSetFilterWrapper(createParentFilter(parentList));
-        // non-atomic update of existing entry to ensure strong-typing
-        parentCache.put(parentList, result);
-      }
+      return parentCache.computeIfAbsent(query, QueryBitSetProducer::new);
     } else {
-      result = new BitDocIdSetFilterWrapper(createParentFilter(parentList));
+      return new QueryBitSetProducer(query);
     }
-    return result;
-  }
-
-  private static BitSetProducer createParentFilter(Query parentQ) {
-    return new QueryBitSetProducer(parentQ);
   }
 
   static final class AllParentsAware extends ToParentBlockJoinQuery {
@@ -123,49 +110,55 @@ public class BlockJoinParentQParser extends FiltersQParser {
     }
   }
 
-  // We need this wrapper since BitDocIdSetFilter does not extend Filter
-  public static class BitDocIdSetFilterWrapper extends Filter {
+  /** A constant score query based on a {@link BitSetProducer}. */
+  static class BitSetProducerQuery extends ExtendedQueryBase {
 
-    private final BitSetProducer filter;
+    final BitSetProducer bitSetProducer;
 
-    BitDocIdSetFilterWrapper(BitSetProducer filter) {
-      this.filter = filter;
+    public BitSetProducerQuery(BitSetProducer bitSetProducer) {
+      this.bitSetProducer = bitSetProducer;
+      setCache(false); // because we assume the bitSetProducer is itself cached
     }
 
     @Override
-    public DocIdSet getDocIdSet(LeafReaderContext context, Bits acceptDocs) throws IOException {
-      BitSet set = filter.getBitSet(context);
-      if (set == null) {
-        return null;
-      }
-      return BitsFilteredDocIdSet.wrap(new BitDocIdSet(set), acceptDocs);
+    public String toString(String field) {
+      return getClass().getSimpleName() + "(" + bitSetProducer + ")";
     }
 
-    public BitSetProducer getFilter() {
-      return filter;
+    @Override
+    public boolean equals(Object other) {
+      return sameClassAs(other) && Objects.equals(bitSetProducer, getClass().cast(other).bitSetProducer);
     }
 
     @Override
-    public String toString(String field) {
-      return getClass().getSimpleName() + "(" + filter + ")";
+    public int hashCode() {
+      return classHash() + bitSetProducer.hashCode();
     }
 
     @Override
-    public boolean equals(Object other) {
-      return sameClassAs(other) &&
-             Objects.equals(filter, getClass().cast(other).getFilter());
+    public void visit(QueryVisitor visitor) {
+      visitor.visitLeaf(this);
     }
 
     @Override
-    public int hashCode() {
-      return classHash() + filter.hashCode();
+    public Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode scoreMode, float boost) throws IOException {
+      return new ConstantScoreWeight(BitSetProducerQuery.this, boost) {
+        @Override
+        public Scorer scorer(LeafReaderContext context) throws IOException {
+          BitSet bitSet = bitSetProducer.getBitSet(context);
+          if (bitSet == null) {
+            return null;
+          }
+          DocIdSetIterator disi = new BitSetIterator(bitSet, bitSet.approximateCardinality());
+          return new ConstantScoreScorer(this, boost, scoreMode, disi);
+        }
+
+        @Override
+        public boolean isCacheable(LeafReaderContext ctx) {
+          return getCache();
+        }
+      };
     }
   }
 
 }
-
-
-
-
-
-
diff --git a/solr/core/src/java/org/apache/solr/search/join/ChildFieldValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/join/ChildFieldValueSourceParser.java
index 768c7e3..30be3a3 100644
--- a/solr/core/src/java/org/apache/solr/search/join/ChildFieldValueSourceParser.java
+++ b/solr/core/src/java/org/apache/solr/search/join/ChildFieldValueSourceParser.java
@@ -180,8 +180,8 @@ public class ChildFieldValueSourceParser extends ValueSourceParser {
       }
       bjQ = (AllParentsAware) query;
       
-      parentFilter = BlockJoinParentQParser.getCachedFilter(fp.getReq(), bjQ.getParentQuery()).getFilter();
-      childFilter = BlockJoinParentQParser.getCachedFilter(fp.getReq(), bjQ.getChildQuery()).getFilter();
+      parentFilter = BlockJoinParentQParser.getCachedBitSetProducer(fp.getReq(), bjQ.getParentQuery());
+      childFilter = BlockJoinParentQParser.getCachedBitSetProducer(fp.getReq(), bjQ.getChildQuery());
 
       if (sortFieldName==null || sortFieldName.equals("")) {
         throw new SyntaxError ("field is omitted in "+fp.getString());
diff --git a/solr/core/src/test/org/apache/solr/search/join/another/BJQFilterAccessibleTest.java b/solr/core/src/test/org/apache/solr/search/join/another/BJQFilterAccessibleTest.java
index 96ac205..d5044e6 100644
--- a/solr/core/src/test/org/apache/solr/search/join/another/BJQFilterAccessibleTest.java
+++ b/solr/core/src/test/org/apache/solr/search/join/another/BJQFilterAccessibleTest.java
@@ -46,7 +46,7 @@ public class BJQFilterAccessibleTest  extends SolrTestCaseJ4 {
       TermQuery childQuery = new TermQuery(new Term("child_s", "l"));
       Query parentQuery = new WildcardQuery(new Term("parent_s", "*"));
       ToParentBlockJoinQuery tpbjq = new ToParentBlockJoinQuery(childQuery,
-          BlockJoinParentQParser.getCachedFilter(req,parentQuery).getFilter(), ScoreMode.Max);
+          BlockJoinParentQParser.getCachedBitSetProducer(req,parentQuery), ScoreMode.Max);
       Assert.assertEquals(6, req.getSearcher().search(tpbjq,10).totalHits.value);
     }
   }