use of net.opentsdb.utils.ByteArrayPair in project opentsdb by OpenTSDB.
the class TimeSeriesLookup method getRowKeyRegex.
/**
* Constructs a row key regular expression to pass to HBase if the user gave
* some tags in the query
* @return The regular expression to use.
*/
private String getRowKeyRegex() {
final StringBuilder tagv_buffer = new StringBuilder();
// remember, tagks are sorted in the row key so we need to supply a sorted
// regex or matching will fail.
Collections.sort(pairs);
final short name_width = TSDB.tagk_width();
final short value_width = TSDB.tagv_width();
final short tagsize = (short) (name_width + value_width);
int index = 0;
final StringBuilder buf = new StringBuilder(// "^.{N}" + "(?:.{M})*" + "$" + wiggle
22 + (// "(?:.{M})*\\Q" + tagsize bytes + "\\E"
(13 + tagsize) * (pairs.size())));
buf.append("(?s)^.{").append(query.useMeta() ? TSDB.metrics_width() : TSDB.metrics_width() + Const.SALT_WIDTH()).append("}");
if (!query.useMeta()) {
buf.append("(?:.{").append(Const.TIMESTAMP_BYTES).append("})*");
}
buf.append("(?:.{").append(tagsize).append("})*");
// a separate regex for them.
for (; index < pairs.size(); index++) {
if (pairs.get(index).getKey() != null) {
break;
}
if (index > 0) {
buf.append("|");
}
buf.append("(?:.{").append(name_width).append("})");
buf.append("\\Q");
QueryUtil.addId(buf, pairs.get(index).getValue(), true);
}
buf.append("(?:.{").append(tagsize).append("})*").append("$");
if (index > 0 && index < pairs.size()) {
// we had one or more tagvs to lookup AND we have tagk or tag pairs to
// filter on, so we dump the previous regex into the tagv_filter and
// continue on with a row key
tagv_buffer.append(buf.toString());
LOG.debug("Setting tagv filter: " + QueryUtil.byteRegexToString(buf.toString()));
} else if (index >= pairs.size()) {
// in this case we don't have any tagks to deal with so we can just
// pass the previously compiled regex to the rowkey filter of the
// scanner
LOG.debug("Setting scanner row key filter with tagvs only: " + QueryUtil.byteRegexToString(buf.toString()));
if (tagv_buffer.length() > 0) {
tagv_filter = tagv_buffer.toString();
}
return buf.toString();
}
// catch any left over tagk/tag pairs
if (index < pairs.size()) {
// This condition is true whenever the first tagk in the pairs has a null value.
buf.setLength(0);
buf.append("(?s)^.{").append(query.useMeta() ? TSDB.metrics_width() : TSDB.metrics_width() + Const.SALT_WIDTH()).append("}");
if (!query.useMeta()) {
buf.append("(?:.{").append(Const.TIMESTAMP_BYTES).append("})");
}
ByteArrayPair last_pair = null;
for (; index < pairs.size(); index++) {
if (last_pair != null && last_pair.getValue() == null && Bytes.memcmp(last_pair.getKey(), pairs.get(index).getKey()) == 0) {
// tagk=null is a wildcard so we don't need to bother adding
// tagk=tagv pairs with the same tagk.
LOG.debug("Skipping pair due to wildcard: " + pairs.get(index));
} else if (last_pair != null && Bytes.memcmp(last_pair.getKey(), pairs.get(index).getKey()) == 0) {
// in this case we're ORing e.g. "host=web01|host=web02"
buf.append("|\\Q");
QueryUtil.addId(buf, pairs.get(index).getKey(), false);
QueryUtil.addId(buf, pairs.get(index).getValue(), true);
} else {
if (last_pair != null) {
buf.append(")");
}
// moving on to the next tagk set
// catch tag pairs in between
buf.append("(?:.{").append(tagsize).append("})*");
buf.append("(?:");
if (pairs.get(index).getKey() != null && pairs.get(index).getValue() != null) {
buf.append("\\Q");
QueryUtil.addId(buf, pairs.get(index).getKey(), false);
QueryUtil.addId(buf, pairs.get(index).getValue(), true);
} else {
buf.append("\\Q");
QueryUtil.addId(buf, pairs.get(index).getKey(), true);
buf.append("(?:.{").append(value_width).append("})");
}
}
last_pair = pairs.get(index);
}
buf.append(")(?:.{").append(tagsize).append("})*").append("$");
}
if (tagv_buffer.length() > 0) {
tagv_filter = tagv_buffer.toString();
}
return buf.toString();
}
use of net.opentsdb.utils.ByteArrayPair in project opentsdb by OpenTSDB.
the class TimeSeriesLookup method resolveUIDs.
/**
* Resolves the metric and tag strings to their UIDs
* @return A deferred to wait on for resolution to complete.
*/
private Deferred<Object> resolveUIDs() {
class TagsCB implements Callback<Object, ArrayList<Object>> {
@Override
public Object call(final ArrayList<Object> ignored) throws Exception {
rowkey_regex = getRowKeyRegex();
return null;
}
}
class PairResolution implements Callback<Object, ArrayList<byte[]>> {
@Override
public Object call(final ArrayList<byte[]> tags) throws Exception {
if (tags.size() < 2) {
throw new IllegalArgumentException("Somehow we received an array " + "that wasn't two bytes in size! " + tags);
}
pairs.add(new ByteArrayPair(tags.get(0), tags.get(1)));
return Deferred.fromResult(null);
}
}
class TagResolution implements Callback<Deferred<Object>, Object> {
@Override
public Deferred<Object> call(final Object unused) throws Exception {
if (query.getTags() == null || query.getTags().isEmpty()) {
return Deferred.fromResult(null);
}
pairs = Collections.synchronizedList(new ArrayList<ByteArrayPair>(query.getTags().size()));
final ArrayList<Deferred<Object>> deferreds = new ArrayList<Deferred<Object>>(pairs.size());
for (final Pair<String, String> tags : query.getTags()) {
final ArrayList<Deferred<byte[]>> deferred_tags = new ArrayList<Deferred<byte[]>>(2);
if (tags.getKey() != null && !tags.getKey().equals("*")) {
deferred_tags.add(tsdb.getUIDAsync(UniqueIdType.TAGK, tags.getKey()));
} else {
deferred_tags.add(Deferred.<byte[]>fromResult(null));
}
if (tags.getValue() != null && !tags.getValue().equals("*")) {
deferred_tags.add(tsdb.getUIDAsync(UniqueIdType.TAGV, tags.getValue()));
} else {
deferred_tags.add(Deferred.<byte[]>fromResult(null));
}
deferreds.add(Deferred.groupInOrder(deferred_tags).addCallback(new PairResolution()));
}
return Deferred.group(deferreds).addCallback(new TagsCB());
}
}
class MetricCB implements Callback<Deferred<Object>, byte[]> {
@Override
public Deferred<Object> call(final byte[] uid) throws Exception {
metric_uid = uid;
LOG.debug("Found UID (" + UniqueId.uidToString(metric_uid) + ") for metric (" + query.getMetric() + ")");
return new TagResolution().call(null);
}
}
if (query.getMetric() != null && !query.getMetric().isEmpty() && !query.getMetric().equals("*")) {
return tsdb.getUIDAsync(UniqueIdType.METRIC, query.getMetric()).addCallbackDeferring(new MetricCB());
} else {
try {
return new TagResolution().call(null);
} catch (Exception e) {
return Deferred.fromError(e);
}
}
}
Aggregations