use of org.hbase.async.GetRequest in project YCSB by brianfrankcooper.
the class AsyncHBaseClient method read.
@Override
public Status read(String table, String key, Set<String> fields, HashMap<String, ByteIterator> result) {
setTable(table);
final GetRequest get = new GetRequest(lastTableBytes, key.getBytes(), columnFamilyBytes);
if (fields != null) {
get.qualifiers(getQualifierList(fields));
}
try {
if (debug) {
System.out.println("Doing read from HBase columnfamily " + Bytes.pretty(columnFamilyBytes));
System.out.println("Doing read for key: " + key);
}
final ArrayList<KeyValue> row = client.get(get).join(joinTimeout);
if (row == null || row.isEmpty()) {
return Status.NOT_FOUND;
}
// got something so populate the results
for (final KeyValue column : row) {
result.put(new String(column.qualifier()), // be GC'd.
new ByteArrayByteIterator(column.value()));
if (debug) {
System.out.println("Result for field: " + Bytes.pretty(column.qualifier()) + " is: " + Bytes.pretty(column.value()));
}
}
return Status.OK;
} catch (InterruptedException e) {
System.err.println("Thread interrupted");
Thread.currentThread().interrupt();
} catch (Exception e) {
System.err.println("Failure reading from row with key " + key + ": " + e.getMessage());
return Status.ERROR;
}
return Status.ERROR;
}
use of org.hbase.async.GetRequest in project YCSB by brianfrankcooper.
the class AsyncHBaseClient method read.
@Override
public Status read(String table, String key, Set<String> fields, Map<String, ByteIterator> result) {
setTable(table);
final GetRequest get = new GetRequest(lastTableBytes, key.getBytes(), columnFamilyBytes);
if (fields != null) {
get.qualifiers(getQualifierList(fields));
}
try {
if (debug) {
System.out.println("Doing read from HBase columnfamily " + Bytes.pretty(columnFamilyBytes));
System.out.println("Doing read for key: " + key);
}
final ArrayList<KeyValue> row = client.get(get).join(joinTimeout);
if (row == null || row.isEmpty()) {
return Status.NOT_FOUND;
}
// got something so populate the results
for (final KeyValue column : row) {
result.put(new String(column.qualifier()), // be GC'd.
new ByteArrayByteIterator(column.value()));
if (debug) {
System.out.println("Result for field: " + Bytes.pretty(column.qualifier()) + " is: " + Bytes.pretty(column.value()));
}
}
return Status.OK;
} catch (InterruptedException e) {
System.err.println("Thread interrupted");
Thread.currentThread().interrupt();
} catch (Exception e) {
System.err.println("Failure reading from row with key " + key + ": " + e.getMessage());
return Status.ERROR;
}
return Status.ERROR;
}
use of org.hbase.async.GetRequest 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 org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class UIDMeta method getUIDMeta.
/**
* Verifies the UID object exists, then attempts to fetch the meta from
* storage and if not found, returns a default object.
* <p>
* The reason for returning a default object (with the type, uid and name set)
* is due to users who may have just enabled meta data or have upgraded; we
* want to return valid data. If they modify the entry, it will write to
* storage. You can tell it's a default if the {@code created} value is 0. If
* the meta was generated at UID assignment or updated by the meta sync CLI
* command, it will have a valid created timestamp.
* @param tsdb The TSDB to use for storage access
* @param type The type of UID to fetch
* @param uid The ID of the meta to fetch
* @return A UIDMeta from storage or a default
* @throws HBaseException if there was an issue fetching
* @throws NoSuchUniqueId If the UID does not exist
*/
public static Deferred<UIDMeta> getUIDMeta(final TSDB tsdb, final UniqueIdType type, final byte[] uid) {
/**
* Callback used to verify that the UID to name mapping exists. Uses the TSD
* for verification so the name may be cached. If the name does not exist
* it will throw a NoSuchUniqueId and the meta data will not be returned.
* This helps in case the user deletes a UID but the meta data is still
* stored. The fsck utility can be used later to cleanup orphaned objects.
*/
class NameCB implements Callback<Deferred<UIDMeta>, String> {
/**
* Called after verifying that the name mapping exists
* @return The results of {@link #FetchMetaCB}
*/
@Override
public Deferred<UIDMeta> call(final String name) throws Exception {
/**
* Inner class called to retrieve the meta data after verifying that the
* name mapping exists. It requires the name to set the default, hence
* the reason it's nested.
*/
class FetchMetaCB implements Callback<Deferred<UIDMeta>, ArrayList<KeyValue>> {
/**
* Called to parse the response of our storage GET call after
* verification
* @return The stored UIDMeta or a default object if the meta data
* did not exist
*/
@Override
public Deferred<UIDMeta> call(ArrayList<KeyValue> row) throws Exception {
if (row == null || row.isEmpty()) {
// return the default
final UIDMeta meta = new UIDMeta();
meta.uid = UniqueId.uidToString(uid);
meta.type = type;
meta.name = name;
return Deferred.fromResult(meta);
}
final UIDMeta meta = JSON.parseToObject(row.get(0).value(), UIDMeta.class);
// overwrite the name and UID
meta.name = name;
meta.uid = UniqueId.uidToString(uid);
// fix missing types
if (meta.type == null) {
final String qualifier = new String(row.get(0).qualifier(), CHARSET);
meta.type = UniqueId.stringToUniqueIdType(qualifier.substring(0, qualifier.indexOf("_meta")));
}
meta.initializeChangedMap();
return Deferred.fromResult(meta);
}
}
final GetRequest get = new GetRequest(tsdb.uidTable(), uid);
get.family(FAMILY);
get.qualifier((type.toString().toLowerCase() + "_meta").getBytes(CHARSET));
return tsdb.getClient().get(get).addCallbackDeferring(new FetchMetaCB());
}
}
// verify that the UID is still in the map before fetching from storage
return tsdb.getUidName(type, uid).addCallbackDeferring(new NameCB());
}
use of org.hbase.async.GetRequest in project opentsdb by OpenTSDB.
the class UIDMeta method syncToStorage.
/**
* Attempts a CompareAndSet storage call, loading the object from storage,
* synchronizing changes, and attempting a put.
* <b>Note:</b> If the local object didn't have any fields set by the caller
* then the data will not be written.
* @param tsdb The TSDB to use for storage access
* @param overwrite When the RPC method is PUT, will overwrite all user
* accessible fields
* @return True if the storage call was successful, false if the object was
* modified in storage during the CAS call. If false, retry the call. Other
* failures will result in an exception being thrown.
* @throws HBaseException if there was an issue fetching
* @throws IllegalArgumentException if parsing failed
* @throws NoSuchUniqueId If the UID does not exist
* @throws IllegalStateException if the data hasn't changed. This is OK!
* @throws JSONException if the object could not be serialized
*/
public Deferred<Boolean> syncToStorage(final TSDB tsdb, final boolean overwrite) {
if (uid == null || uid.isEmpty()) {
throw new IllegalArgumentException("Missing UID");
}
if (type == null) {
throw new IllegalArgumentException("Missing type");
}
boolean has_changes = false;
for (Map.Entry<String, Boolean> entry : changed.entrySet()) {
if (entry.getValue()) {
has_changes = true;
break;
}
}
if (!has_changes) {
LOG.debug(this + " does not have changes, skipping sync to storage");
throw new IllegalStateException("No changes detected in UID meta data");
}
/**
* Callback used to verify that the UID to name mapping exists. Uses the TSD
* for verification so the name may be cached. If the name does not exist
* it will throw a NoSuchUniqueId and the meta data will not be saved to
* storage
*/
final class NameCB implements Callback<Deferred<Boolean>, String> {
private final UIDMeta local_meta;
public NameCB(final UIDMeta meta) {
local_meta = meta;
}
/**
* Nested callback used to merge and store the meta data after verifying
* that the UID mapping exists. It has to access the {@code local_meta}
* object so that's why it's nested within the NameCB class
*/
final class StoreUIDMeta implements Callback<Deferred<Boolean>, ArrayList<KeyValue>> {
/**
* Executes the CompareAndSet after merging changes
* @return True if the CAS was successful, false if the stored data
* was modified during flight.
*/
@Override
public Deferred<Boolean> call(final ArrayList<KeyValue> row) throws Exception {
final UIDMeta stored_meta;
if (row == null || row.isEmpty()) {
stored_meta = null;
} else {
stored_meta = JSON.parseToObject(row.get(0).value(), UIDMeta.class);
stored_meta.initializeChangedMap();
}
final byte[] original_meta = row == null || row.isEmpty() ? new byte[0] : row.get(0).value();
if (stored_meta != null) {
local_meta.syncMeta(stored_meta, overwrite);
}
// verify the name is set locally just to be safe
if (name == null || name.isEmpty()) {
local_meta.name = name;
}
final PutRequest put = new PutRequest(tsdb.uidTable(), UniqueId.stringToUid(uid), FAMILY, (type.toString().toLowerCase() + "_meta").getBytes(CHARSET), local_meta.getStorageJSON());
return tsdb.getClient().compareAndSet(put, original_meta);
}
}
/**
* NameCB method that fetches the object from storage for merging and
* use in the CAS call
* @return The results of the {@link #StoreUIDMeta} callback
*/
@Override
public Deferred<Boolean> call(final String name) throws Exception {
final GetRequest get = new GetRequest(tsdb.uidTable(), UniqueId.stringToUid(uid));
get.family(FAMILY);
get.qualifier((type.toString().toLowerCase() + "_meta").getBytes(CHARSET));
// #2 deferred
return tsdb.getClient().get(get).addCallbackDeferring(new StoreUIDMeta());
}
}
// start the callback chain by veryfing that the UID name mapping exists
return tsdb.getUidName(type, UniqueId.stringToUid(uid)).addCallbackDeferring(new NameCB(this));
}
Aggregations