/** * Count the number of subscorers that provide the match in the current node, * and sum their score. * <p> * Counting the number of matchers within a node during node iteration is not * possible as it will require to cache the latest top node. This would have * required a copy of the array node since array node are reused in the * {@link DocsNodesAndPositionsEnum}. * <p> * Iterating over the elements of the queue enables us to save such a array * copy. * * @see #nrMatchersInNode() * @see #scoreInNode() */ protected void countAndSumMatchers() throws IOException { if (nrMatchersInNode < 0) { // count and sum not done nrMatchersInNode = 1; // init counter at 1 to include the top scoreInNode = topHSN.scorer.scoreInNode(); // perform recursive traversal of the heap this.computeSumRecursive(1); } }
/** * Perform a traversal of the heap binary tree using recursion. Given a node, * visit its children and check if their subscorer is equivalent to the least * subscorer. If the subscorer is equivalent, it increments the number of * matchers, sum its score with the current score, and recursively visit its * two children. */ private final void computeSumRecursive(final int root) throws IOException { final int i1 = (root << 1); // index of first child node final int i2 = (root << 1) + 1; // index of second child node if (i1 <= size) { final HeapedScorerNode child1 = heap[i1]; if (topHSN.doc == child1.doc && topHSN.node.intsEquals(child1.node)) { nrMatchersInNode++; scoreInNode += child1.scorer.scoreInNode(); this.computeSumRecursive(i1); } } if (i2 <= size) { final HeapedScorerNode child2 = heap[i2]; if (topHSN.doc == child2.doc && topHSN.node.intsEquals(child2.node)) { nrMatchersInNode++; scoreInNode += child2.scorer.scoreInNode(); this.computeSumRecursive(i2); } } }