*/
private Deferred<TreeMap<byte[], Span>> findSpans() throws HBaseException {
final short metric_width = tsdb.metrics.width();
final TreeMap<byte[], Span> spans = // The key is a row key from HBase.
new TreeMap<byte[], Span>(new SpanCmp(metric_width));
final Scanner scanner = getScanner();
final Deferred<TreeMap<byte[], Span>> results =
new Deferred<TreeMap<byte[], Span>>();
/**
* Scanner callback executed recursively each time we get a set of data
* from storage. This is responsible for determining what columns are
* returned and issuing requests to load leaf objects.
* When the scanner returns a null set of rows, the method initiates the
* final callback.
*/
final class ScannerCB implements Callback<Object,
ArrayList<ArrayList<KeyValue>>> {
int nrows = 0;
int hbase_time = 0; // milliseconds.
long starttime = System.nanoTime();
/**
* Starts the scanner and is called recursively to fetch the next set of
* rows from the scanner.
* @return The map of spans if loaded successfully, null if no data was
* found
*/
public Object scan() {
starttime = System.nanoTime();
return scanner.nextRows().addCallback(this);
}
/**
* Loops through each row of the scanner results and parses out data
* points and optional meta data
* @return null if no rows were found, otherwise the TreeMap with spans
*/
@Override
public Object call(final ArrayList<ArrayList<KeyValue>> rows)
throws Exception {
hbase_time += (System.nanoTime() - starttime) / 1000000;
try {
if (rows == null) {
hbase_time += (System.nanoTime() - starttime) / 1000000;
scanlatency.add(hbase_time);
LOG.info(TsdbQuery.this + " matched " + nrows + " rows in " +
spans.size() + " spans in " + hbase_time + "ms");
if (nrows < 1) {
results.callback(null);
} else {
results.callback(spans);
}
scanner.close();
return null;
}
for (final ArrayList<KeyValue> row : rows) {
final byte[] key = row.get(0).key();
if (Bytes.memcmp(metric, key, 0, metric_width) != 0) {
scanner.close();
throw new IllegalDataException(
"HBase returned a row that doesn't match"
+ " our scanner (" + scanner + ")! " + row + " does not start"
+ " with " + Arrays.toString(metric));
}
Span datapoints = spans.get(key);
if (datapoints == null) {
datapoints = new Span(tsdb);
spans.put(key, datapoints);
}
final KeyValue compacted =
tsdb.compact(row, datapoints.getAnnotations());
if (compacted != null) { // Can be null if we ignored all KVs.
datapoints.addRow(compacted);
nrows++;
}
}
return scan();
} catch (Exception e) {
scanner.close();
results.callback(e);
return null;
}
}
}