use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.
the class Annotation method deleteRange.
/**
* Deletes global or TSUID associated annotiations for the given time range.
* @param tsdb The TSDB object to use for storage access
* @param tsuid An optional TSUID. If set to null, then global annotations for
* the given range will be deleted
* @param start_time A start timestamp in milliseconds
* @param end_time An end timestamp in millseconds
* @return The number of annotations deleted
* @throws IllegalArgumentException if the timestamps are invalid
* @since 2.1
*/
public static Deferred<Integer> deleteRange(final TSDB tsdb, final byte[] tsuid, final long start_time, final long end_time) {
if (end_time < 1) {
throw new IllegalArgumentException("The end timestamp has not been set");
}
if (end_time < start_time) {
throw new IllegalArgumentException("The end timestamp cannot be less than the start timestamp");
}
final List<Deferred<Object>> delete_requests = new ArrayList<Deferred<Object>>();
int width = tsuid != null ? Const.SALT_WIDTH() + tsuid.length + Const.TIMESTAMP_BYTES : Const.SALT_WIDTH() + TSDB.metrics_width() + Const.TIMESTAMP_BYTES;
final byte[] start_row = new byte[width];
final byte[] end_row = new byte[width];
// downsample to seconds for the row keys
final long start = start_time / 1000;
final long end = end_time / 1000;
final long normalized_start = (start - (start % Const.MAX_TIMESPAN));
final long normalized_end = (end - (end % Const.MAX_TIMESPAN) + Const.MAX_TIMESPAN);
Bytes.setInt(start_row, (int) normalized_start, Const.SALT_WIDTH() + TSDB.metrics_width());
Bytes.setInt(end_row, (int) normalized_end, Const.SALT_WIDTH() + TSDB.metrics_width());
if (tsuid != null) {
// first copy the metric UID then the tags
System.arraycopy(tsuid, 0, start_row, Const.SALT_WIDTH(), TSDB.metrics_width());
System.arraycopy(tsuid, 0, end_row, Const.SALT_WIDTH(), TSDB.metrics_width());
width = Const.SALT_WIDTH() + TSDB.metrics_width() + Const.TIMESTAMP_BYTES;
final int remainder = tsuid.length - TSDB.metrics_width();
System.arraycopy(tsuid, TSDB.metrics_width(), start_row, width, remainder);
System.arraycopy(tsuid, TSDB.metrics_width(), end_row, width, remainder);
}
/**
* Iterates through the scanner results in an asynchronous manner, returning
* once the scanner returns a null result set.
*/
final class ScannerCB implements Callback<Deferred<List<Deferred<Object>>>, ArrayList<ArrayList<KeyValue>>> {
final Scanner scanner;
public ScannerCB() {
scanner = tsdb.getClient().newScanner(tsdb.dataTable());
scanner.setStartKey(start_row);
scanner.setStopKey(end_row);
scanner.setFamily(FAMILY);
if (tsuid != null) {
final List<String> tsuids = new ArrayList<String>(1);
tsuids.add(UniqueId.uidToString(tsuid));
Internal.createAndSetTSUIDFilter(scanner, tsuids);
}
}
public Deferred<List<Deferred<Object>>> scan() {
return scanner.nextRows().addCallbackDeferring(this);
}
@Override
public Deferred<List<Deferred<Object>>> call(final ArrayList<ArrayList<KeyValue>> rows) throws Exception {
if (rows == null || rows.isEmpty()) {
return Deferred.fromResult(delete_requests);
}
for (final ArrayList<KeyValue> row : rows) {
final long base_time = Internal.baseTime(tsdb, row.get(0).key());
for (KeyValue column : row) {
if ((column.qualifier().length == 3 || column.qualifier().length == 5) && column.qualifier()[0] == PREFIX()) {
final long timestamp = timeFromQualifier(column.qualifier(), base_time);
if (timestamp < start_time || timestamp > end_time) {
continue;
}
final DeleteRequest delete = new DeleteRequest(tsdb.dataTable(), column.key(), FAMILY, column.qualifier());
delete_requests.add(tsdb.getClient().delete(delete));
}
}
}
return scan();
}
}
/** Called when the scanner is done. Delete requests may still be pending */
final class ScannerDoneCB implements Callback<Deferred<ArrayList<Object>>, List<Deferred<Object>>> {
@Override
public Deferred<ArrayList<Object>> call(final List<Deferred<Object>> deletes) throws Exception {
return Deferred.group(delete_requests);
}
}
/** Waits on the group of deferreds to complete before returning the count */
final class GroupCB implements Callback<Deferred<Integer>, ArrayList<Object>> {
@Override
public Deferred<Integer> call(final ArrayList<Object> deletes) throws Exception {
return Deferred.fromResult(deletes.size());
}
}
Deferred<ArrayList<Object>> scanner_done = new ScannerCB().scan().addCallbackDeferring(new ScannerDoneCB());
return scanner_done.addCallbackDeferring(new GroupCB());
}
use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.
the class Branch method fetchBranchOnly.
/**
* Attempts to fetch only the branch definition object from storage. This is
* much faster than scanning many rows for child branches as per the
* {@link #fetchBranch} call. Useful when building trees, particularly to
* fetch the root branch.
* @param tsdb The TSDB to use for access
* @param branch_id ID of the branch to retrieve
* @return A branch if found, null if it did not exist
* @throws JSONException if the object could not be deserialized
*/
public static Deferred<Branch> fetchBranchOnly(final TSDB tsdb, final byte[] branch_id) {
final GetRequest get = new GetRequest(tsdb.treeTable(), branch_id);
get.family(Tree.TREE_FAMILY());
get.qualifier(BRANCH_QUALIFIER);
/**
* Called after the get returns with or without data. If we have data, we'll
* parse the branch and return it.
*/
final class GetCB implements Callback<Deferred<Branch>, ArrayList<KeyValue>> {
@Override
public Deferred<Branch> call(ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
return Deferred.fromResult(null);
}
final Branch branch = JSON.parseToObject(row.get(0).value(), Branch.class);
// WARNING: Since the json doesn't store the tree ID, to cut down on
// space, we have to load it from the row key.
branch.tree_id = Tree.bytesToId(row.get(0).key());
return Deferred.fromResult(branch);
}
}
return tsdb.getClient().get(get).addCallbackDeferring(new GetCB());
}
use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.
the class Annotation method getAnnotation.
/**
* Attempts to fetch a global or local annotation from storage
* @param tsdb The TSDB to use for storage access
* @param tsuid The TSUID as a byte array. May be null if retrieving a global
* annotation
* @param start_time The start time as a Unix epoch timestamp
* @return A valid annotation object if found, null if not
*/
public static Deferred<Annotation> getAnnotation(final TSDB tsdb, final byte[] tsuid, final long start_time) {
/**
* Called after executing the GetRequest to parse the meta data.
*/
final class GetCB implements Callback<Deferred<Annotation>, ArrayList<KeyValue>> {
/**
* @return Null if the meta did not exist or a valid Annotation object if
* it did.
*/
@Override
public Deferred<Annotation> call(final ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
return Deferred.fromResult(null);
}
Annotation note = JSON.parseToObject(row.get(0).value(), Annotation.class);
return Deferred.fromResult(note);
}
}
final GetRequest get = new GetRequest(tsdb.dataTable(), getRowKey(start_time, tsuid));
get.family(FAMILY);
get.qualifier(getQualifier(start_time));
return tsdb.getClient().get(get).addCallbackDeferring(new GetCB());
}
use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.
the class TSMeta method counterExistsInStorage.
/**
* Determines if the counter column exists for the TSUID.
* This is used by the UID Manager tool to determine if we need to write a
* new TSUID entry or not. It will not attempt to verify if the stored data is
* valid, just checks to see if something is stored in the proper column.
* @param tsdb The TSDB to use for storage access
* @param tsuid The UID of the meta to verify
* @return True if data was found, false if not
* @throws HBaseException if there was an issue fetching
*/
public static Deferred<Boolean> counterExistsInStorage(final TSDB tsdb, final byte[] tsuid) {
final GetRequest get = new GetRequest(tsdb.metaTable(), tsuid);
get.family(FAMILY);
get.qualifier(COUNTER_QUALIFIER);
/**
* Callback from the GetRequest that simply determines if the row is empty
* or not
*/
final class ExistsCB implements Callback<Boolean, ArrayList<KeyValue>> {
@Override
public Boolean call(ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty() || row.get(0).value() == null) {
return false;
}
return true;
}
}
return tsdb.getClient().get(get).addCallback(new ExistsCB());
}
use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.
the class TSUIDQuery method tsuidFromMetric.
/**
* Converts the given metric and tags to a TSUID by resolving the strings to
* their UIDs. Note that the resulting TSUID may not exist if the combination
* was not written to TSDB
* @param tsdb The TSDB to use for storage access
* @param metric The metric name to resolve
* @param tags The tags to resolve. May not be empty.
* @return A deferred containing the TSUID when ready or an error such as
* a NoSuchUniqueName exception if the metric didn't exist or a
* DeferredGroupException if one of the tag keys or values did not exist.
* @throws IllegalArgumentException if the metric or tags were null or
* empty.
*/
public static Deferred<byte[]> tsuidFromMetric(final TSDB tsdb, final String metric, final Map<String, String> tags) {
if (metric == null || metric.isEmpty()) {
throw new IllegalArgumentException("The metric cannot be empty");
}
if (tags == null || tags.isEmpty()) {
throw new IllegalArgumentException("Tags cannot be null or empty " + "when getting a TSUID");
}
final byte[] metric_uid = new byte[TSDB.metrics_width()];
class TagsCB implements Callback<byte[], ArrayList<byte[]>> {
@Override
public byte[] call(final ArrayList<byte[]> tag_list) throws Exception {
final byte[] tsuid = new byte[metric_uid.length + ((TSDB.tagk_width() + TSDB.tagv_width()) * tag_list.size())];
int idx = 0;
System.arraycopy(metric_uid, 0, tsuid, 0, metric_uid.length);
idx += metric_uid.length;
for (final byte[] t : tag_list) {
System.arraycopy(t, 0, tsuid, idx, t.length);
idx += t.length;
}
return tsuid;
}
@Override
public String toString() {
return "Tag resolution callback";
}
}
class MetricCB implements Callback<Deferred<byte[]>, byte[]> {
@Override
public Deferred<byte[]> call(final byte[] uid) throws Exception {
System.arraycopy(uid, 0, metric_uid, 0, uid.length);
return Tags.resolveAllAsync(tsdb, tags).addCallback(new TagsCB());
}
@Override
public String toString() {
return "Metric resolution callback";
}
}
return tsdb.getUIDAsync(UniqueIdType.METRIC, metric).addCallbackDeferring(new MetricCB());
}
Aggregations