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(
        22  // "^.{N}" + "(?:.{M})*" + "$" + wiggle
        + ((13 + tagsize) // "(?:.{M})*\\Q" + tagsize bytes + "\\E"
           * (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("})*");
    
    // at the top of the list will be the null=tagv pairs. We want to compile
    // 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
	  buf.append("(?:.{").append(tagsize).append("})*"); // catch tag pairs in between
          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();
  }
private String getRowKeyRegex ( ) { final StringBuilder tagv_buffer = new StringBuilder ( ) ; 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 ( 22 + ( ( 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 ( "})*" ) ; 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 ( ) ) { tagv_buffer . append ( buf . toString ( ) ) ; LOG . debug ( "Setting tagv filter: " + QueryUtil . byteRegexToString ( buf . toString ( ) ) ) ; } else if ( index >= pairs . size ( ) ) { 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 ( ) ; } if ( index < pairs . size ( ) ) { 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 ) { 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 ) { 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 ( ")" ) ; } 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 ( ) ; }
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.