Search in sources :

Example 1 with ByteArrayPair

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();
}
Also used : ByteArrayPair(net.opentsdb.utils.ByteArrayPair)

Example 2 with ByteArrayPair

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);
        }
    }
}
Also used : Deferred(com.stumbleupon.async.Deferred) ArrayList(java.util.ArrayList) DeferredGroupException(com.stumbleupon.async.DeferredGroupException) ByteArrayPair(net.opentsdb.utils.ByteArrayPair) Callback(com.stumbleupon.async.Callback)

Aggregations

ByteArrayPair (net.opentsdb.utils.ByteArrayPair)2 Callback (com.stumbleupon.async.Callback)1 Deferred (com.stumbleupon.async.Deferred)1 DeferredGroupException (com.stumbleupon.async.DeferredGroupException)1 ArrayList (java.util.ArrayList)1