Mikep86 commented on code in PR #13697:
URL: https://github.com/apache/lucene/pull/13697#discussion_r1745751201


##########
lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java:
##########
@@ -440,6 +478,114 @@ private String formatScoreExplanation(int matches, int 
start, int end, ScoreMode
     }
   }
 
+  private abstract static class BatchAwareLeafCollector extends 
FilterLeafCollector {
+    public BatchAwareLeafCollector(LeafCollector in) {
+      super(in);
+    }
+
+    public void endBatch() throws IOException {}
+  }
+
+  private static class BlockJoinBulkScorer extends BulkScorer {
+    private final BulkScorer childBulkScorer;
+    private final ScoreMode scoreMode;
+    private final BitSet parents;
+    private final int parentsLength;
+
+    public BlockJoinBulkScorer(BulkScorer childBulkScorer, ScoreMode 
scoreMode, BitSet parents) {
+      this.childBulkScorer = childBulkScorer;
+      this.scoreMode = scoreMode;
+      this.parents = parents;
+      this.parentsLength = parents.length();
+    }
+
+    @Override
+    public int score(LeafCollector collector, Bits acceptDocs, int min, int 
max)
+        throws IOException {
+      // Subtract one because max is exclusive w.r.t. score but inclusive 
w.r.t prevSetBit
+      int lastParent = parents.prevSetBit(Math.min(parentsLength, max) - 1);
+      int prevParent = min == 0 ? -1 : parents.prevSetBit(min - 1);
+      if (lastParent == prevParent) {
+        // No parent docs in this range.
+        // If we've scored the last parent in the bit set, return NO_MORE_DOCS 
to indicate we are
+        // done scoring.
+        return max >= parentsLength ? NO_MORE_DOCS : max;
+      }
+
+      BatchAwareLeafCollector wrappedCollector = wrapCollector(collector);
+      childBulkScorer.score(wrappedCollector, acceptDocs, prevParent + 1, 
lastParent + 1);
+      wrappedCollector.endBatch();
+
+      // If we've scored the last parent in the bit set, return NO_MORE_DOCS 
to indicate we are done
+      // scoring
+      return lastParent + 1 >= parentsLength ? NO_MORE_DOCS : max;
+    }
+
+    @Override
+    public long cost() {
+      return childBulkScorer.cost();
+    }
+
+    private BatchAwareLeafCollector wrapCollector(LeafCollector collector) {
+      return new BatchAwareLeafCollector(collector) {
+        private final Score currentParentScore = new Score(scoreMode);
+        private int currentParent = -1;
+        private Scorable scorer = null;
+
+        @Override
+        public void setScorer(Scorable scorer) throws IOException {
+          assert scorer != null;
+          this.scorer = scorer;
+
+          super.setScorer(
+              new Scorable() {
+                @Override
+                public float score() {
+                  return currentParentScore.score();
+                }
+
+                @Override
+                public void setMinCompetitiveScore(float minScore) throws 
IOException {
+                  if (scoreMode == ScoreMode.None || scoreMode == 
ScoreMode.Max) {
+                    scorer.setMinCompetitiveScore(minScore);
+                  }
+                }
+              });

Review Comment:
   LMKWYT of this approach. I originally added the child scorer to 
`currentParentScore`'s constructor and created `currentParentScore` in 
`setScorer`, but that didn't work because `setScorer` is potentially called 
multiple times.
   
   I then tried creating `currentParentScore` once, on the first call to 
`setScorer`, and checking that the same child scorer is passed in subsequent 
calls in an assertion. At least in the tests, this didn't work because the 
child scorer is wrapped in a different `AssertingScorable` in each call.
   
   This approach seemed like the simplest that avoids the above problems. I 
could go back to them though if we can assume that subsequent calls to 
`setScorer` will pass the same child scorer without checking in an assertion.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org
For additional commands, e-mail: issues-h...@lucene.apache.org

Reply via email to