@Override
 public ServiceMetricEvent.Builder makeMetricBuilder(TopNQuery query) {
   return DruidMetrics.makePartialQueryTimeMetric(query)
       .setDimension("threshold", String.valueOf(query.getThreshold()))
       .setDimension("dimension", query.getDimensionSpec().getDimension())
       .setDimension("numMetrics", String.valueOf(query.getAggregatorSpecs().size()))
       .setDimension(
           "numComplexMetrics",
           String.valueOf(DruidMetrics.findNumComplexAggs(query.getAggregatorSpecs())));
 }
    @Override
    public Sequence<Result<TopNResultValue>> run(
        Query<Result<TopNResultValue>> input, Map<String, Object> responseContext) {
      if (!(input instanceof TopNQuery)) {
        throw new ISE("Can only handle [%s], got [%s]", TopNQuery.class, input.getClass());
      }

      final TopNQuery query = (TopNQuery) input;
      if (query.getThreshold() > minTopNThreshold) {
        return runner.run(query, responseContext);
      }

      final boolean isBySegment = query.getContextBySegment(false);

      return Sequences.map(
          runner.run(query.withThreshold(minTopNThreshold), responseContext),
          new Function<Result<TopNResultValue>, Result<TopNResultValue>>() {
            @Override
            public Result<TopNResultValue> apply(Result<TopNResultValue> input) {
              if (isBySegment) {
                BySegmentResultValue<Result<TopNResultValue>> value =
                    (BySegmentResultValue<Result<TopNResultValue>>) input.getValue();

                return new Result<TopNResultValue>(
                    input.getTimestamp(),
                    new BySegmentTopNResultValue(
                        Lists.transform(
                            value.getResults(),
                            new Function<Result<TopNResultValue>, Result<TopNResultValue>>() {
                              @Override
                              public Result<TopNResultValue> apply(Result<TopNResultValue> input) {
                                return new Result<>(
                                    input.getTimestamp(),
                                    new TopNResultValue(
                                        Lists.<Object>newArrayList(
                                            Iterables.limit(
                                                input.getValue(), query.getThreshold()))));
                              }
                            }),
                        value.getSegmentId(),
                        value.getInterval()));
              }

              return new Result<>(
                  input.getTimestamp(),
                  new TopNResultValue(
                      Lists.<Object>newArrayList(
                          Iterables.limit(input.getValue(), query.getThreshold()))));
            }
          });
    }
 public static TopNResultBuilder makeResultBuilder(TopNParams params, TopNQuery query) {
   final Comparator comparator =
       query
           .getTopNMetricSpec()
           .getComparator(query.getAggregatorSpecs(), query.getPostAggregatorSpecs());
   return query
       .getTopNMetricSpec()
       .getResultBuilder(
           params.getCursor().getTime(),
           query.getDimensionSpec(),
           query.getThreshold(),
           comparator,
           query.getAggregatorSpecs(),
           query.getPostAggregatorSpecs());
 }
    protected Pair<Integer, Integer> computeStartEnd(int cardinality) {
      int startIndex = ignoreFirstN;

      if (previousStop != null) {
        int lookupId = dimSelector.lookupId(previousStop) + 1;
        if (lookupId < 0) {
          lookupId *= -1;
        }
        if (lookupId > ignoreFirstN + keepOnlyN) {
          startIndex = ignoreFirstN + keepOnlyN;
        } else {
          startIndex = Math.max(lookupId, startIndex);
        }
      }

      int endIndex = Math.min(ignoreFirstN + keepOnlyN, cardinality);

      if (ignoreAfterThreshold && query.getDimensionsFilter() == null) {
        endIndex = Math.min(endIndex, startIndex + query.getThreshold());
      }

      return Pair.of(startIndex, endIndex);
    }
 private static List<PostAggregator> prunePostAggregators(TopNQuery query) {
   return AggregatorUtil.pruneDependentPostAgg(
       query.getPostAggregatorSpecs(),
       query.getTopNMetricSpec().getMetricName(query.getDimensionSpec()));
 }