private Scanner getScanner ( ) { final Scanner scanner = tsdb . getClient ( ) . newScanner ( tsdb . metaTable ( ) ) ; scanner . setStartKey ( metric_uid ) ; // increment the metric UID by one so we can scan all of the rows for the // given metric final long stop = UniqueId . uidToLong ( metric_uid , TSDB . metrics_width ( ) ) + 1 ; scanner . setStopKey ( UniqueId . longToUID ( stop , TSDB . metrics_width ( ) ) ) ; scanner . setFamily ( TSMeta . FAMILY ( ) ) ; // set the filter if we have tags if ( ! tags . isEmpty ( ) ) { final short name_width = TSDB . tagk_width ( ) ; final short value_width = TSDB . tagv_width ( ) ; final short tagsize = ( short ) ( name_width + value_width ) ; // Generate a regexp for our tags. Say we have 2 tags: { 0 0 1 0 0 2 } // and { 4 5 6 9 8 7 }, the regexp will be: // "^.{7}(?:.{6})*\\Q\000\000\001\000\000\002\\E(?:.{6})*\\Q\004\005\006\011\010\007\\E(?:.{6})*$" final StringBuilder buf = new StringBuilder ( 15 // "^.{N}" + "(?:.{M})*" + "$" + ( ( 13 + tagsize ) // "(?:.{M})*\\Q" + tagsize bytes + "\\E" * ( tags . size ( ) ) ) ) ; // Alright, let's build this regexp. From the beginning... buf . append ( "(?s)" // Ensure we use the DOTALL flag. + "^.{" ) // ... start by skipping the metric ID. . append ( TSDB . metrics_width ( ) ) . append ( "}" ) ; final Iterator < byte [ ] > tags = this . tag_uids . iterator ( ) ; byte [ ] tag = tags . hasNext ( ) ? tags . next ( ) : null ; // Tags and group_bys are already sorted. We need to put them in the // regexp in order by ID, which means we just merge two sorted lists. do { // Skip any number of tags. buf . append ( "(?:.{" ) . append ( tagsize ) . append ( "})*\\Q" ) ; UniqueId . addIdToRegexp ( buf , tag ) ; tag = tags . hasNext ( ) ? tags . next ( ) : null ; } while ( tag != null ) ; // Stop when they both become null. // Skip any number of tags before the end. buf . append ( "(?:.{" ) . append ( tagsize ) . append ( "})*$" ) ; scanner . setKeyRegexp ( buf . toString ( ) , CHARSET ) ; } return scanner ; }
Configures the scanner for a specific metric and optional tags