private void forEachMatch()

in spectator-reg-atlas/src/main/java/com/netflix/spectator/atlas/impl/QueryIndex.java [394:470]


  private void forEachMatch(Id tags, int i, Consumer<T> consumer) {
    // Matches for this level
    matches.forEach(consumer);

    final String keyRef = key;
    if (keyRef != null) {

      boolean keyPresent = false;

      final int tagsSize = tags.size();
      for (int j = i; j < tagsSize; ++j) {
        String k = tags.getKey(j);
        String v = tags.getValue(j);
        int cmp = compare(k, keyRef);
        if (cmp == 0) {
          final int nextPos = j + 1;
          keyPresent = true;

          // Find exact matches
          QueryIndex<T> eqIdx = equalChecks.get(v);
          if (eqIdx != null) {
            eqIdx.forEachMatch(tags, nextPos, consumer);
          }

          // Scan for matches with other conditions
          List<QueryIndex<T>> otherMatches = otherChecksCache.get(v);
          if (otherMatches == null) {
            // Avoid the list and cache allocations if there are no other checks at
            // this level
            if (!otherChecks.isEmpty()) {
              List<QueryIndex<T>> tmp = new ArrayList<>();
              otherChecksTree.forEach(v, kq -> {
                if (kq instanceof Query.In || kq.matches(v)) {
                  QueryIndex<T> idx = otherChecks.get(kq);
                  if (idx != null) {
                    tmp.add(idx);
                    idx.forEachMatch(tags, nextPos, consumer);
                  }
                }
              });
              otherChecksCache.put(v, tmp);
            }
          } else {
            // Enhanced for loop typically results in iterator being allocated. Using
            // size/get avoids the allocation and has better throughput.
            final int n = otherMatches.size();
            for (int p = 0; p < n; ++p) {
              otherMatches.get(p).forEachMatch(tags, nextPos, consumer);
            }
          }

          // Check matches for has key
          final QueryIndex<T> hasKeyIdxRef = hasKeyIdx;
          if (hasKeyIdxRef != null) {
            hasKeyIdxRef.forEachMatch(tags, j, consumer);
          }
        }

        // Quit loop if the key was found or not present
        if (cmp >= 0) {
          break;
        }
      }

      // Check matches with other keys
      final QueryIndex<T> otherKeysIdxRef = otherKeysIdx;
      if (otherKeysIdxRef != null) {
        otherKeysIdxRef.forEachMatch(tags, i, consumer);
      }

      // Check matches with missing keys
      final QueryIndex<T> missingKeysIdxRef = missingKeysIdx;
      if (missingKeysIdxRef != null && !keyPresent) {
        missingKeysIdxRef.forEachMatch(tags, i, consumer);
      }
    }
  }