use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class MultiGetQuery method prepareRequests.
/**
* Generates a map of TSUIDs per salt to get requests given the tag permutations.
* If all salts is enabled, each TSUID will have Const.SALT_BUCKETS() number
* of entries. Otherwise each TSUID will have one row key.
* @param tagv_compounds The cardinality of tag key and value combinations to
* search for.
* @param base_time_list The list of base timestamps.
* @return A non-null map of TSUIDs to lists of get requests to send to HBase.
*/
@VisibleForTesting
ByteMap<ByteMap<List<GetRequest>>> prepareRequests(final List<Long> base_time_list, List<ByteMap<byte[][]>> tags) {
final ByteMap<ByteMap<List<GetRequest>>> tsuid_rows = new ByteMap<ByteMap<List<GetRequest>>>();
// copy tagks and tagvs to the row key
for (ByteMap<byte[][]> each_row_key : tags) {
final int row_size = (Const.SALT_WIDTH() + tsdb.metrics.width() + Const.TIMESTAMP_BYTES + (tsdb.tag_names.width() * each_row_key.size()) + (tsdb.tag_values.width() * each_row_key.size()));
byte[] tsuid = new byte[tsdb.metrics.width() + (each_row_key.size() * tsdb.tag_names.width()) + each_row_key.size() * tsdb.tag_values.width()];
byte[] row_key = new byte[row_size];
int row_key_copy_offset = Const.SALT_WIDTH() + tsdb.metrics.width() + Const.TIMESTAMP_BYTES;
int tsuid_copy_offset = tsdb.metrics.width();
// metric
System.arraycopy(metric, 0, row_key, Const.SALT_WIDTH(), tsdb.metrics.width());
System.arraycopy(metric, 0, tsuid, 0, tsdb.metrics.width());
final List<GetRequest> rows = new ArrayList<GetRequest>(base_time_list.size());
for (Map.Entry<byte[], byte[][]> tag_arr : each_row_key.entrySet()) {
byte[] tagv = tag_arr.getValue()[0];
// tagk
byte[] tagk = tag_arr.getKey();
System.arraycopy(tagk, 0, row_key, row_key_copy_offset, tsdb.tag_names.width());
System.arraycopy(tagk, 0, tsuid, tsuid_copy_offset, tsdb.tag_names.width());
row_key_copy_offset += tsdb.tag_names.width();
tsuid_copy_offset += tsdb.tag_names.width();
// tagv
System.arraycopy(tagv, 0, row_key, row_key_copy_offset, tsdb.tag_values.width());
System.arraycopy(tagv, 0, tsuid, tsuid_copy_offset, tsdb.tag_values.width());
row_key_copy_offset += tsdb.tag_values.width();
tsuid_copy_offset += tsdb.tag_values.width();
}
// timestamp.
for (final long row_base_time : base_time_list) {
final byte[] key_copy = Arrays.copyOf(row_key, row_key.length);
// base time
Internal.setBaseTime(key_copy, (int) row_base_time);
if (get_all_salts) {
for (int i = 0; i < Const.SALT_BUCKETS(); i++) {
byte[] salt = RowKey.getSaltBytes(i);
final byte[] copy = Arrays.copyOf(key_copy, key_copy.length);
System.arraycopy(salt, 0, copy, 0, Const.SALT_WIDTH());
rows.add(new GetRequest(table_to_fetch, copy, TSDB.FAMILY));
}
} else {
// salt
RowKey.prefixKeyWithSalt(key_copy);
rows.add(new GetRequest(table_to_fetch, key_copy, TSDB.FAMILY));
}
}
// end for
for (GetRequest request : rows) {
byte[] salt = new byte[Const.SALT_WIDTH()];
System.arraycopy(request.key(), 0, salt, 0, Const.SALT_WIDTH());
if (tsuid_rows.containsKey(salt)) {
ByteMap<List<GetRequest>> map = tsuid_rows.get(salt);
if (map.containsKey(tsuid)) {
List<GetRequest> list = map.get(tsuid);
list.add(request);
} else {
List<GetRequest> list = new ArrayList<GetRequest>();
list.add(request);
map.put(tsuid, list);
}
} else {
ByteMap<List<GetRequest>> map = new ByteMap<List<GetRequest>>();
List<GetRequest> list = new ArrayList<GetRequest>();
list.add(request);
map.put(tsuid, list);
tsuid_rows.put(salt, map);
}
}
}
return tsuid_rows;
}
use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class Tree method fetchTree.
/**
* Attempts to fetch the given tree from storage, loading the rule set at
* the same time.
* @param tsdb The TSDB to use for access
* @param tree_id The Tree to fetch
* @return A tree object if found, null if the tree did not exist
* @throws IllegalArgumentException if the tree ID was invalid
* @throws HBaseException if a storage exception occurred
* @throws JSONException if the object could not be deserialized
*/
public static Deferred<Tree> fetchTree(final TSDB tsdb, final int tree_id) {
if (tree_id < 1 || tree_id > 65535) {
throw new IllegalArgumentException("Invalid Tree ID");
}
// fetch the whole row
final GetRequest get = new GetRequest(tsdb.treeTable(), idToBytes(tree_id));
get.family(TREE_FAMILY);
/**
* Called from the GetRequest with results from storage. Loops through the
* columns and loads the tree definition and rules
*/
final class FetchTreeCB implements Callback<Deferred<Tree>, ArrayList<KeyValue>> {
@Override
public Deferred<Tree> call(ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
return Deferred.fromResult(null);
}
final Tree tree = new Tree();
// WARNING: Since the JSON in storage doesn't store the tree ID, we need
// to loadi t from the row key.
tree.setTreeId(bytesToId(row.get(0).key()));
for (KeyValue column : row) {
if (Bytes.memcmp(TREE_QUALIFIER, column.qualifier()) == 0) {
// it's *this* tree. We deserialize to a new object and copy
// since the columns could be in any order and we may get a rule
// before the tree object
final Tree local_tree = JSON.parseToObject(column.value(), Tree.class);
tree.created = local_tree.created;
tree.description = local_tree.description;
tree.name = local_tree.name;
tree.notes = local_tree.notes;
tree.strict_match = local_tree.strict_match;
tree.enabled = local_tree.enabled;
tree.store_failures = local_tree.store_failures;
// Tree rule
} else if (Bytes.memcmp(TreeRule.RULE_PREFIX(), column.qualifier(), 0, TreeRule.RULE_PREFIX().length) == 0) {
final TreeRule rule = TreeRule.parseFromStorage(column);
tree.addRule(rule);
}
}
return Deferred.fromResult(tree);
}
}
// issue the get request
return tsdb.getClient().get(get).addCallbackDeferring(new FetchTreeCB());
}
use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class TreeRule method fetchRule.
/**
* Attempts to retrieve the specified tree rule from storage.
* @param tsdb The TSDB to use for storage access
* @param tree_id ID of the tree the rule belongs to
* @param level Level where the rule resides
* @param order Order where the rule resides
* @return A TreeRule object if found, null if it does not exist
* @throws HBaseException if there was an issue
* @throws IllegalArgumentException if the one of the required parameters was
* missing
* @throws JSONException if the object could not be serialized
*/
public static Deferred<TreeRule> fetchRule(final TSDB tsdb, final int tree_id, final int level, final int order) {
if (tree_id < 1 || tree_id > 65535) {
throw new IllegalArgumentException("Invalid Tree ID");
}
if (level < 0) {
throw new IllegalArgumentException("Invalid rule level");
}
if (order < 0) {
throw new IllegalArgumentException("Invalid rule order");
}
// fetch the whole row
final GetRequest get = new GetRequest(tsdb.treeTable(), Tree.idToBytes(tree_id));
get.family(Tree.TREE_FAMILY());
get.qualifier(getQualifier(level, order));
/**
* Called after fetching to parse the results
*/
final class FetchCB implements Callback<Deferred<TreeRule>, ArrayList<KeyValue>> {
@Override
public Deferred<TreeRule> call(final ArrayList<KeyValue> row) {
if (row == null || row.isEmpty()) {
return Deferred.fromResult(null);
}
return Deferred.fromResult(parseFromStorage(row.get(0)));
}
}
return tsdb.getClient().get(get).addCallbackDeferring(new FetchCB());
}
use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class TreeRule method deleteAllRules.
/**
* Attempts to delete all rules belonging to the given tree.
* @param tsdb The TSDB to use for storage access
* @param tree_id ID of the tree the rules belongs to
* @return A deferred to wait on for completion. The value has no meaning and
* may be null.
* @throws HBaseException if there was an issue
* @throws IllegalArgumentException if the one of the required parameters was
* missing
*/
public static Deferred<Object> deleteAllRules(final TSDB tsdb, final int tree_id) {
if (tree_id < 1 || tree_id > 65535) {
throw new IllegalArgumentException("Invalid Tree ID");
}
// fetch the whole row
final GetRequest get = new GetRequest(tsdb.treeTable(), Tree.idToBytes(tree_id));
get.family(Tree.TREE_FAMILY());
/**
* Called after fetching the requested row. If the row is empty, we just
* return, otherwise we compile a list of qualifiers to delete and submit
* a single delete request to storage.
*/
final class GetCB implements Callback<Deferred<Object>, ArrayList<KeyValue>> {
@Override
public Deferred<Object> call(final ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
return Deferred.fromResult(null);
}
final ArrayList<byte[]> qualifiers = new ArrayList<byte[]>(row.size());
for (KeyValue column : row) {
if (column.qualifier().length > RULE_PREFIX.length && Bytes.memcmp(RULE_PREFIX, column.qualifier(), 0, RULE_PREFIX.length) == 0) {
qualifiers.add(column.qualifier());
}
}
final DeleteRequest delete = new DeleteRequest(tsdb.treeTable(), Tree.idToBytes(tree_id), Tree.TREE_FAMILY(), qualifiers.toArray(new byte[qualifiers.size()][]));
return tsdb.getClient().delete(delete);
}
}
return tsdb.getClient().get(get).addCallbackDeferring(new GetCB());
}
use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class Tree method fetchCollisions.
/**
* Returns the collision set from storage for the given tree, optionally for
* only the list of TSUIDs provided.
* <b>Note:</b> This can potentially be a large list if the rule set was
* written poorly and there were many timeseries so only call this
* without a list of TSUIDs if you feel confident the number is small.
* @param tsdb TSDB to use for storage access
* @param tree_id ID of the tree to fetch collisions for
* @param tsuids An optional list of TSUIDs to fetch collisions for. This may
* be empty or null, in which case all collisions for the tree will be
* returned.
* @return A list of collisions or null if nothing was found
* @throws HBaseException if there was an issue
* @throws IllegalArgumentException if the tree ID was invalid
*/
public static Deferred<Map<String, String>> fetchCollisions(final TSDB tsdb, final int tree_id, final List<String> tsuids) {
if (tree_id < 1 || tree_id > 65535) {
throw new IllegalArgumentException("Invalid Tree ID");
}
final byte[] row_key = new byte[TREE_ID_WIDTH + 1];
System.arraycopy(idToBytes(tree_id), 0, row_key, 0, TREE_ID_WIDTH);
row_key[TREE_ID_WIDTH] = COLLISION_ROW_SUFFIX;
final GetRequest get = new GetRequest(tsdb.treeTable(), row_key);
get.family(TREE_FAMILY);
// of qualifiers so we only fetch those columns.
if (tsuids != null && !tsuids.isEmpty()) {
final byte[][] qualifiers = new byte[tsuids.size()][];
int index = 0;
for (String tsuid : tsuids) {
final byte[] qualifier = new byte[COLLISION_PREFIX.length + (tsuid.length() / 2)];
System.arraycopy(COLLISION_PREFIX, 0, qualifier, 0, COLLISION_PREFIX.length);
final byte[] tsuid_bytes = UniqueId.stringToUid(tsuid);
System.arraycopy(tsuid_bytes, 0, qualifier, COLLISION_PREFIX.length, tsuid_bytes.length);
qualifiers[index] = qualifier;
index++;
}
get.qualifiers(qualifiers);
}
/**
* Called after issuing the row get request to parse out the results and
* compile the list of collisions.
*/
final class GetCB implements Callback<Deferred<Map<String, String>>, ArrayList<KeyValue>> {
@Override
public Deferred<Map<String, String>> call(final ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
final Map<String, String> empty = new HashMap<String, String>(0);
return Deferred.fromResult(empty);
}
final Map<String, String> collisions = new HashMap<String, String>(row.size());
for (KeyValue column : row) {
if (column.qualifier().length > COLLISION_PREFIX.length && Bytes.memcmp(COLLISION_PREFIX, column.qualifier(), 0, COLLISION_PREFIX.length) == 0) {
final byte[] parsed_tsuid = Arrays.copyOfRange(column.qualifier(), COLLISION_PREFIX.length, column.qualifier().length);
collisions.put(UniqueId.uidToString(parsed_tsuid), new String(column.value(), CHARSET));
}
}
return Deferred.fromResult(collisions);
}
}
return tsdb.getClient().get(get).addCallbackDeferring(new GetCB());
}
Aggregations