Crafts a list of FuzzyFilters for scanning over data table rows and filtering time series that the user doesn't want. Note: The caller has to restrict the scan to proper start and stop for the filter to work correctly. @param row_key_literals A list of key value pairs to filter on. @param fuzzy_key
(
final ByteMap<byte[][]> row_key_literals,
final byte[] fuzzy_key)
| 278 | * @return A sorted, non-empty list of FuzzyFilterPair |
| 279 | */ |
| 280 | private static List<FuzzyFilterPair> buildFuzzyFilters( |
| 281 | final ByteMap<byte[][]> row_key_literals, |
| 282 | final byte[] fuzzy_key) { |
| 283 | final int prefix_width = Const.SALT_WIDTH() + TSDB.metrics_width() + |
| 284 | Const.TIMESTAMP_BYTES; |
| 285 | final short name_width = TSDB.tagk_width(); |
| 286 | final short value_width = TSDB.tagv_width(); |
| 287 | final short tag_width = (short) (name_width + value_width); |
| 288 | int row_key_size = prefix_width; |
| 289 | if (row_key_literals != null) { |
| 290 | for(byte[][] v: row_key_literals.values()) { |
| 291 | final boolean not_key = v!=null && v.length==0; |
| 292 | if (!not_key) { |
| 293 | row_key_size += tag_width; |
| 294 | } |
| 295 | } |
| 296 | } |
| 297 | final List<FuzzyFilterPair> fuzzy_filter_pairs = |
| 298 | new ArrayList<FuzzyFilterPair>(row_key_literals.size()); |
| 299 | |
| 300 | // Initialize first_fuzzy_key and first_fuzzy_mask |
| 301 | // these will serve as model for the fuzzy filter list |
| 302 | // generated for tags with multiple values (|) |
| 303 | byte[] first_fuzzy_key = Arrays.copyOf(fuzzy_key, fuzzy_key.length); |
| 304 | byte[] first_fuzzy_mask = new byte[fuzzy_key.length]; |
| 305 | int fuzzy_offset = 0; |
| 306 | |
| 307 | // TODO - see if it's less expensive to skip the salt, timestamp and metric. |
| 308 | // skip salt & timestamp (filtering should be done by start/stop |
| 309 | // of the scanner) |
| 310 | while(fuzzy_offset < prefix_width) { |
| 311 | first_fuzzy_key[fuzzy_offset] = 0; |
| 312 | first_fuzzy_mask[fuzzy_offset++] = |
| 313 | (row_key_literals != null) ? (byte)1 : (byte)0; |
| 314 | } |
| 315 | |
| 316 | // first pass to build the key and mask |
| 317 | Iterator<Entry<byte[], byte[][]>> it = row_key_literals.iterator(); |
| 318 | while(it.hasNext()) { |
| 319 | Entry<byte[], byte[][]> entry = it.next(); |
| 320 | final boolean not_key = |
| 321 | entry.getValue() != null && entry.getValue().length == 0; |
| 322 | |
| 323 | if (!not_key) { |
| 324 | final byte[] tag_key = entry.getKey(); |
| 325 | System.arraycopy(tag_key, 0, |
| 326 | first_fuzzy_key, fuzzy_offset, name_width); |
| 327 | for (int i=0; i<name_width; i++) { |
| 328 | first_fuzzy_mask[fuzzy_offset++] = 0; |
| 329 | } |
| 330 | |
| 331 | final byte[] tag_value; |
| 332 | if (entry.getValue()!=null && entry.getValue().length > 0) { |
| 333 | tag_value = entry.getValue()[0]; |
| 334 | } else { |
| 335 | tag_value = null; |
| 336 | } |
| 337 |
no test coverage detected