in core/src/main/java/org/apache/accumulo/core/iterators/user/IntersectingIterator.java [171:369]
private boolean seekOneSource(int sourceID) throws IOException {
// find the next key in the appropriate column family that is at or beyond the cursor
// (currentRow, currentCQ)
// advance the cursor if this source goes beyond it
// return whether we advanced the cursor
// within this loop progress must be made in one of the following forms:
// - currentRow or currentCQ must be increased
// - the given source must advance its iterator
// this loop will end when any of the following criteria are met
// - the iterator for the given source is pointing to the key (currentRow,
// columnFamilies[sourceID], currentCQ)
// - the given source is out of data and currentRow is set to null
// - the given source has advanced beyond the endRow and currentRow is set to null
boolean advancedCursor = false;
if (sources[sourceID].notFlag) {
while (true) {
if (!sources[sourceID].iter.hasTop()) {
// an empty column that you are negating is a valid condition
break;
}
// check if we're past the end key
int endCompare = -1;
// we should compare the row to the end of the range
if (overallRange.getEndKey() != null) {
endCompare = overallRange.getEndKey().getRow()
.compareTo(sources[sourceID].iter.getTopKey().getRow());
if ((!overallRange.isEndKeyInclusive() && endCompare <= 0) || endCompare < 0) {
// an empty column that you are negating is a valid condition
break;
}
}
int partitionCompare =
currentPartition.compareTo(getPartition(sources[sourceID].iter.getTopKey()));
// check if this source is already at or beyond currentRow
// if not, then seek to at least the current row
if (partitionCompare > 0) {
// seek to at least the currentRow
Key seekKey = buildKey(currentPartition, sources[sourceID].term);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
// check if this source has gone beyond currentRow
// if so, this is a valid condition for negation
if (partitionCompare < 0) {
break;
}
// we have verified that the current source is positioned in currentRow
// now we must make sure we're in the right columnFamily in the current row
// Note: Iterators are auto-magically set to the correct columnFamily
if (sources[sourceID].term != null) {
int termCompare =
sources[sourceID].term.compareTo(getTerm(sources[sourceID].iter.getTopKey()));
// check if this source is already on the right columnFamily
// if not, then seek forwards to the right columnFamily
if (termCompare > 0) {
Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
// check if this source is beyond the right columnFamily
// if so, then this is a valid condition for negating
if (termCompare < 0) {
break;
}
}
// we have verified that we are in currentRow and the correct column family
// make sure we are at or beyond columnQualifier
Text docID = getDocID(sources[sourceID].iter.getTopKey());
int docIDCompare = currentDocID.compareTo(docID);
// If we are past the target, this is a valid result
if (docIDCompare < 0) {
break;
} else if (docIDCompare > 0) {
// if this source is not yet at the currentCQ then advance in this source
// seek forwards
Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
} else {
// docIDCompare == 0
// if we are equal to the target, this is an invalid result.
// Force the entire process to go to the next row.
// We are advancing column 0 because we forced that column to not contain a !
// when we did the init()
sources[0].iter.next();
advancedCursor = true;
break;
}
}
} else {
while (true) {
if (!sources[sourceID].iter.hasTop()) {
currentPartition = null;
// setting currentRow to null counts as advancing the cursor
return true;
}
// check if we're past the end key
int endCompare = -1;
// we should compare the row to the end of the range
if (overallRange.getEndKey() != null) {
endCompare = overallRange.getEndKey().getRow()
.compareTo(sources[sourceID].iter.getTopKey().getRow());
if ((!overallRange.isEndKeyInclusive() && endCompare <= 0) || endCompare < 0) {
currentPartition = null;
// setting currentRow to null counts as advancing the cursor
return true;
}
}
int partitionCompare =
currentPartition.compareTo(getPartition(sources[sourceID].iter.getTopKey()));
// check if this source is already at or beyond currentRow
// if not, then seek to at least the current row
if (partitionCompare > 0) {
// seek to at least the currentRow
Key seekKey = buildKey(currentPartition, sources[sourceID].term);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
// check if this source has gone beyond currentRow
// if so, advance currentRow
if (partitionCompare < 0) {
currentPartition.set(getPartition(sources[sourceID].iter.getTopKey()));
currentDocID.set(emptyByteArray);
advancedCursor = true;
continue;
}
// we have verified that the current source is positioned in currentRow
// now we must make sure we're in the right columnFamily in the current row
// Note: Iterators are auto-magically set to the correct columnFamily
if (sources[sourceID].term != null) {
int termCompare =
sources[sourceID].term.compareTo(getTerm(sources[sourceID].iter.getTopKey()));
// check if this source is already on the right columnFamily
// if not, then seek forwards to the right columnFamily
if (termCompare > 0) {
Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
// check if this source is beyond the right columnFamily
// if so, then seek to the next row
if (termCompare < 0) {
// we're out of entries in the current row, so seek to the next one
// byte[] currentRowBytes = currentRow.getBytes();
// byte[] nextRow = new byte[currentRowBytes.length + 1];
// System.arraycopy(currentRowBytes, 0, nextRow, 0, currentRowBytes.length);
// nextRow[currentRowBytes.length] = (byte)0;
// // we should reuse text objects here
// sources[sourceID].seek(new Key(new Text(nextRow),columnFamilies[sourceID]));
if (endCompare == 0) {
// we're done
currentPartition = null;
// setting currentRow to null counts as advancing the cursor
return true;
}
Key seekKey = buildFollowingPartitionKey(sources[sourceID].iter.getTopKey());
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
}
// we have verified that we are in currentRow and the correct column family
// make sure we are at or beyond columnQualifier
Text docID = getDocID(sources[sourceID].iter.getTopKey());
int docIDCompare = currentDocID.compareTo(docID);
// if this source has advanced beyond the current column qualifier then advance currentCQ
// and return true
if (docIDCompare < 0) {
currentDocID.set(docID);
advancedCursor = true;
break;
}
// if this source is not yet at the currentCQ then seek in this source
if (docIDCompare > 0) {
// seek forwards
Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID);
sources[sourceID].iter.seek(new Range(seekKey, true, null, false),
sources[sourceID].seekColfams, true);
continue;
}
// this source is at the current row, in its column family, and at currentCQ
break;
}
}
return advancedCursor;
}