/** * Skips to the first match (including the current) whose entity, tuple and cell numbers are * greater than or equal to the given targets. <br> * When this method is used the {@link #explain(int)} method should not be used. <br> * The implementation uses the skipTo() method on the subscorers. * * @param entityID The target entity number. * @param tupleID The target tuple number. * @param cellID The target cell number. * @return true iff there is such a match. */ @Override public int advance(final int entityID, final int tupleID, final int cellID) throws IOException { if (scorerCellQueue == null) { this.initScorerCellQueue(); } if (entityID < entity || (entityID == entity && tupleID <= tuple) || (entityID == entity && tupleID == tuple && cellID <= cell)) { return entity; } while (queueSize > 0) { if (scorerCellQueue.topEntity() > entityID || (scorerCellQueue.topEntity() == entityID && (scorerCellQueue.topTuple() != Integer.MAX_VALUE && scorerCellQueue.topTuple() >= tupleID)) || (scorerCellQueue.topEntity() == entityID && scorerCellQueue.topTuple() == tupleID && (scorerCellQueue.topCell() != Integer.MAX_VALUE && scorerCellQueue.topCell() >= cellID))) { entity = scorerCellQueue.topEntity(); this.nextPosition(); return entity; } else if (!scorerCellQueue.topSkipToAndAdjustElsePop(entityID, tupleID, cellID)) { if (--queueSize == 0) { return NO_MORE_DOCS; } } } return NO_MORE_DOCS; }
/** * Advance to the next position.<br> * Set the cell and tuple information.<br> * Iterate over the queue, and count how many matchers there are. Increment the score * consequently. */ @Override public int nextPosition() throws IOException { // if tuple or cell have been set to sentinel value, there is no more position if (scorerCellQueue.topTuple() == Integer.MAX_VALUE || scorerCellQueue.topCell() == Integer.MAX_VALUE) { return NO_MORE_POS; } tuple = scorerCellQueue.topTuple(); cell = scorerCellQueue.topCell(); currentScore = 0; nrMatchers = 0; // Count how many matchers there are, and increment current score while (scorerCellQueue.topEntity() == entity && scorerCellQueue.topTuple() == tuple && scorerCellQueue.topCell() == cell) { // while top is a match, advance currentScore += scorerCellQueue.topScore(); if (scorerCellQueue.topIncMatchers()) nrMatchers++; if (!scorerCellQueue.topNextPositionAndAdjust()) { return 0; // stop, no more position. position is invalid in this scorer, // return 0. // All positions in the queue are consumed. If nextPosition // is called another time, we will return NO_MORE_POS. } } return 0; // position is invalid in this scorer, return 0. }
/** * Advance all subscorers after the current document determined by the top of the <code> * scorerCellQueue</code> if all the subscorers are not exhausted. <br> * At least the top scorer with the minimum entity number will be advanced. * * @return true iff there is a match. <br> * In case there is a match, </code>entity</code>, </code>currentScore</code>, and </code> * nrMatchers</code> describe the match. */ protected int advanceAfterCurrent() throws IOException { if (scorerCellQueue.size() > 0) { if ((queueSize -= scorerCellQueue.nextAndAdjustElsePop()) == 0) { return NO_MORE_DOCS; } entity = scorerCellQueue.topEntity(); this.nextPosition(); // advance to the first position [SRN-24] return entity; } return NO_MORE_DOCS; }
@Override public int nextDoc() throws IOException { if (scorerCellQueue == null) { this.initScorerCellQueue(); if ((nrMatchers = scorerCellQueue.nrMatches()) > 0) { entity = scorerCellQueue.topEntity(); this.nextPosition(); // advance to the first position [SRN-24] return entity; } return NO_MORE_DOCS; } return this.advanceAfterCurrent(); }
/** * Skips to the first match (including the current) whose document number is greater than or equal * to a given target. <br> * When this method is used the {@link #explain(int)} method should not be used. <br> * The implementation uses the skipTo() method on the subscorers. * * @param entityID The target entity number. * @return true iff there is such a match. */ @Override public int advance(final int entityID) throws IOException { if (scorerCellQueue == null) { this.initScorerCellQueue(); } if (entityID <= entity) { return entity; } while (queueSize > 0) { if (scorerCellQueue.topEntity() >= entityID) { entity = scorerCellQueue.topEntity(); this.nextPosition(); // advance to the first position [SRN-24] return entity; } else if (!scorerCellQueue.topSkipToAndAdjustElsePop(entityID)) { if (--queueSize == 0) { return NO_MORE_DOCS; } } } return NO_MORE_DOCS; }
/** * Called the first time next() or skipTo() is called to initialize <code>scorerCellQueue</code>. */ private void initScorerCellQueue() throws IOException { final Iterator<SirenPrimitiveScorer> si = scorers.iterator(); scorerCellQueue = new ScorerCellQueue(nrScorers); queueSize = 0; while (si.hasNext()) { final SirenPrimitiveScorer se = si.next(); if (se.nextDoc() != NO_MORE_DOCS) { // entity(), tuple() and cell () method will be used in scorerDocQueue. if (scorerCellQueue.insert(se)) { queueSize++; } } } }