public boolean next() throws IOException { if (firstTime) { initList(true); listToQueue(); // initialize queue firstTime = false; } else if (more) { more = min().next(); // trigger further scanning if (more) queue.adjustTop(); // maintain queue } while (more) { boolean queueStale = false; if (min().doc() != max.doc()) { // maintain list queueToList(); queueStale = true; } // skip to doc w/ all clauses while (more && first.doc() < last.doc()) { more = first.skipTo(last.doc()); // skip first upto last firstToLast(); // and move it to the end queueStale = true; } if (!more) return false; // found doc w/ all clauses if (queueStale) { // maintain the queue listToQueue(); queueStale = false; } if (atMatch()) return true; // trigger further scanning if (inOrder && checkSlop()) { /* There is a non ordered match within slop and an ordered match is needed. */ more = firstNonOrderedNextToPartialList(); if (more) { partialListToQueue(); } } else { more = min().next(); if (more) { queue.adjustTop(); // maintain queue } } } return false; // no more matches }
public boolean skipTo(int target) throws IOException { if (firstTime) { // initialize initList(false); for (SpansCell cell = first; more && cell != null; cell = cell.next) { more = cell.skipTo(target); // skip all } if (more) { listToQueue(); } firstTime = false; } else { // normal case while (more && min().doc() < target) { // skip as needed more = min().skipTo(target); if (more) queue.adjustTop(); } } if (more) { if (atMatch()) // at a match? return true; return next(); // no, scan } return false; }
private boolean firstNonOrderedNextToPartialList() throws IOException { /* Creates a partial list consisting of first non ordered and earlier. * Returns first non ordered .next(). */ last = first = null; int orderedIndex = 0; while (queue.top() != null) { SpansCell cell = (SpansCell) queue.pop(); addToList(cell); if (cell.index == orderedIndex) { orderedIndex++; } else { return cell.next(); // FIXME: continue here, rename to eg. checkOrderedMatch(): // when checkSlop() and not ordered, repeat cell.next(). // when checkSlop() and ordered, add to list and repeat queue.pop() // without checkSlop(): no match, rebuild the queue from the partial list. // When queue is empty and checkSlop() and ordered there is a match. } } throw new RuntimeException("Unexpected: ordered"); }
private void partialListToQueue() { for (SpansCell cell = first; cell != null; cell = cell.next) { queue.put(cell); // add to queue from list } }
private void listToQueue() { queue.clear(); // rebuild queue partialListToQueue(); }
private void queueToList() { last = first = null; while (queue.top() != null) { addToList((SpansCell) queue.pop()); } }
private SpansCell min() { return (SpansCell) queue.top(); }