@Override public boolean nextNode() throws IOException { final boolean more = nodeScorerQueue.nextNodeAndAdjust(); currentNode = nodeScorerQueue.node(); return more; }
@Override public boolean skipToCandidate(final int target) throws IOException { final boolean more = nodeScorerQueue.skipToCandidateAndAdjustElsePop(target); currentDoc = nodeScorerQueue.doc(); currentNode = nodeScorerQueue.node(); return more; }
@Override public boolean nextCandidateDocument() throws IOException { boolean more = true; // The first time nextCandidateDocument is called, we must not advance the // underlying scorers as they have been already advanced during the queue init if (currentDoc != -1) { // if not called for the first time more = nodeScorerQueue.nextCandidateDocumentAndAdjustElsePop(); } currentDoc = nodeScorerQueue.doc(); currentNode = nodeScorerQueue.node(); return more; }
/** * Move all the scorers that have document equals to the top document to the * next node and adjust the heap. * * @return If the least scorer has no more nodes, returns false. */ public final boolean nextNodeAndAdjust() throws IOException { /* * TODO: stecam: I had a NPE in this method with topHSN. However, * I cannot reproduce it. Try to find the case it does occur. */ // count number of scorers having the same document and node // counting the number of scorers and then performing the iterations of // all the scorers allows to avoid a node array copy (i.e., current node cache) if (size > 0 && nrMatchersInNode < 0) { this.countAndSumMatchers(); } // Move the scorers to the next node for (int i = 0; i < nrMatchersInNode; i++) { topHSN.scorer.nextNode(); this.adjustTop(); } // reset nrMatchersInNode nrMatchersInNode = -1; // if top node has sentinel value, it means that there is no more nodes return this.node() != DocsAndNodesIterator.NO_MORE_NOD; }
assertEquals(node(0,0), q.node()); assertFalse(q.nextNodeAndAdjust()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); assertEquals(node(1,0), q.node()); assertFalse(q.nextNodeAndAdjust()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); assertEquals(node(0,1), q.node()); assertTrue(q.nextNodeAndAdjust()); assertEquals(node(1,0), q.node()); assertFalse(q.nextNodeAndAdjust()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node());
assertEquals(2, q.size()); // term2 should have been removed assertTrue(q.nextNodeAndAdjust()); assertEquals(node(0,0), q.node()); assertTrue(q.nextNodeAndAdjust()); assertEquals(node(1,0), q.node()); assertFalse(q.nextNodeAndAdjust()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); assertEquals(1, q.size()); // term1 should have been removed assertTrue(q.nextNodeAndAdjust()); assertEquals(node(0,0), q.node()); assertTrue(q.nextNodeAndAdjust()); assertEquals(node(1,0), q.node()); assertFalse(q.nextNodeAndAdjust()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node());
@Test public void testNextCandidateDocumentAndAdjustElsePop() throws IOException { this.addDocument("\"term1\" \"term2\" . \"term3\" . \"term4\" . "); this.addDocument("\"term5\" \"term2\" . \"term3\" . "); final NodeDisjunctionScorerQueue q = new NodeDisjunctionScorerQueue(4); q.put(this.getScorer(ntq("term2"))); q.put(this.getScorer(ntq("term3"))); q.put(this.getScorer(ntq("term4"))); q.put(this.getScorer(ntq("term5"))); assertEquals(0, q.doc()); assertEquals(4, q.size()); assertTrue(q.nextCandidateDocumentAndAdjustElsePop()); assertEquals(1, q.doc()); assertEquals(3, q.size()); // term4 scorer should have been removed assertFalse(q.nextCandidateDocumentAndAdjustElsePop()); assertEquals(DocsAndNodesIterator.NO_MORE_DOC, q.doc()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, q.node()); }