*/
private void rowAtOrBeforeFromMapFile(MapFile.Reader map, Text row,
SortedMap<HStoreKey, Long> candidateKeys)
throws IOException {
HStoreKey searchKey = null;
ImmutableBytesWritable readval = new ImmutableBytesWritable();
HStoreKey readkey = new HStoreKey();
synchronized(map) {
// don't bother with the rest of this if the file is empty
map.reset();
if (!map.next(readkey, readval)) {
return;
}
// if there aren't any candidate keys yet, we'll do some things slightly
// different
if (candidateKeys.isEmpty()) {
searchKey = new HStoreKey(row);
// if the row we're looking for is past the end of this mapfile, just
// save time and add the last key to the candidates.
HStoreKey finalKey = new HStoreKey();
map.finalKey(finalKey);
if (finalKey.getRow().compareTo(row) < 0) {
candidateKeys.put(stripTimestamp(finalKey),
new Long(finalKey.getTimestamp()));
return;
}
// seek to the exact row, or the one that would be immediately before it
readkey = (HStoreKey)map.getClosest(searchKey, readval, true);
if (readkey == null) {
// didn't find anything that would match, so return
return;
}
do {
// if we have an exact match on row, and it's not a delete, save this
// as a candidate key
if (readkey.getRow().equals(row)) {
if (!HLogEdit.isDeleted(readval.get())) {
candidateKeys.put(stripTimestamp(readkey),
new Long(readkey.getTimestamp()));
}
} else if (readkey.getRow().compareTo(row) > 0 ) {
// if the row key we just read is beyond the key we're searching for,
// then we're done. return.
return;
} else {
// so, the row key doesn't match, but we haven't gone past the row
// we're seeking yet, so this row is a candidate for closest
// (assuming that it isn't a delete).
if (!HLogEdit.isDeleted(readval.get())) {
candidateKeys.put(stripTimestamp(readkey),
new Long(readkey.getTimestamp()));
}
}
} while(map.next(readkey, readval));
// arriving here just means that we consumed the whole rest of the map
// without going "past" the key we're searching for. we can just fall
// through here.
} else {
// if there are already candidate keys, we need to start our search
// at the earliest possible key so that we can discover any possible
// deletes for keys between the start and the search key.
searchKey = new HStoreKey(candidateKeys.firstKey().getRow());
HStoreKey strippedKey = null;
// if the row we're looking for is past the end of this mapfile, just
// save time and add the last key to the candidates.
HStoreKey finalKey = new HStoreKey();
map.finalKey(finalKey);
if (finalKey.getRow().compareTo(searchKey.getRow()) < 0) {
strippedKey = stripTimestamp(finalKey);
// if the candidate keys has a cell like this one already,
// then we might want to update the timestamp we're using on it
if (candidateKeys.containsKey(strippedKey)) {
long bestCandidateTs =
candidateKeys.get(strippedKey).longValue();
if (bestCandidateTs < finalKey.getTimestamp()) {
candidateKeys.put(strippedKey, new Long(finalKey.getTimestamp()));
}
} else {
// otherwise, this is a new key, so put it up as a candidate
candidateKeys.put(strippedKey, new Long(finalKey.getTimestamp()));
}
return;
}
// seek to the exact row, or the one that would be immediately before it
readkey = (HStoreKey)map.getClosest(searchKey, readval, true);
if (readkey == null) {
// didn't find anything that would match, so return
return;
}
do {
// if we have an exact match on row, and it's not a delete, save this
// as a candidate key
if (readkey.getRow().equals(row)) {
strippedKey = stripTimestamp(readkey);
if (!HLogEdit.isDeleted(readval.get())) {
candidateKeys.put(strippedKey, new Long(readkey.getTimestamp()));
} else {
// if the candidate keys contain any that might match by timestamp,
// then check for a match and remove it if it's too young to
// survive the delete
if (candidateKeys.containsKey(strippedKey)) {
long bestCandidateTs =
candidateKeys.get(strippedKey).longValue();
if (bestCandidateTs <= readkey.getTimestamp()) {
candidateKeys.remove(strippedKey);
}
}
}
} else if (readkey.getRow().compareTo(row) > 0 ) {
// if the row key we just read is beyond the key we're searching for,
// then we're done. return.
return;
} else {
strippedKey = stripTimestamp(readkey);
// so, the row key doesn't match, but we haven't gone past the row
// we're seeking yet, so this row is a candidate for closest
// (assuming that it isn't a delete).
if (!HLogEdit.isDeleted(readval.get())) {
candidateKeys.put(strippedKey, readkey.getTimestamp());
} else {
// if the candidate keys contain any that might match by timestamp,
// then check for a match and remove it if it's too young to
// survive the delete