def findValues()

in atlas-core/src/main/scala/com/netflix/atlas/core/index/RoaringTagIndex.scala [444:495]


  def findValues(query: TagQuery): List[String] = {
    require(query.key.isDefined)
    val k = query.key.get
    val kp = keyMap.get(k, -1)
    if (kp < 0) return Nil

    val vidx = itemIndex.get(kp)
    if (vidx == null) return Nil

    val offset = findOffset(values, query.offset)
    val results = new util.BitSet(values.length)

    if (query.query.isEmpty) {
      // No query filter, just use all values for a key
      vidx.foreachKey { v =>
        if (v >= offset) {
          results.set(v)
        }
      }
    } else {
      // Need to restrict by the query, always include restriction for items with the key
      val has = Query.HasKey(k)
      val q = query.query.fold[Query](has)(q => q.and(has))
      val itemSet = findImpl(q, 0)

      // Double check if there were any matches
      if (itemSet.isEmpty) return Nil

      if (vidx.size < itemSet.getCardinality / 8) {
        // Loop over the values for a key since it is considerably smaller than the
        // overall set of matches. All we need to confirm is that there is at least
        // one item matching the query criteria with a given value
        vidx.foreach { (v, items) =>
          if (v >= offset && hasNonEmptyIntersection(itemSet, items)) {
            results.set(v)
          }
        }
      } else {
        // Loop over the items that match the query
        val iter = itemSet.getIntIterator
        while (iter.hasNext) {
          val tags = itemTags(iter.next())
          val v = getValue(tags, kp)
          if (v >= offset) {
            results.set(v)
          }
        }
      }
    }

    createResultList(values, results, query.limit)
  }