public TopNQuery build() { return new TopNQuery( dataSource, virtualColumns, dimensionSpec, topNMetricSpec, threshold, querySegmentSpec, dimFilter, granularity, aggregatorSpecs, postAggregatorSpecs, context ); }
@Override protected BinaryFn<Result<TopNResultValue>, Result<TopNResultValue>, Result<TopNResultValue>> createMergeFn( Query<Result<TopNResultValue>> input ) { TopNQuery query = (TopNQuery) input; return new TopNBinaryFn( query.getGranularity(), query.getDimensionSpec(), query.getTopNMetricSpec(), query.getThreshold(), query.getAggregatorSpecs(), query.getPostAggregatorSpecs() ); } };
@Override public TopNQuery withOverriddenContext(Map<String, Object> contextOverrides) { return new TopNQueryBuilder(this).context(computeOverriddenContext(getContext(), contextOverrides)).build(); }
public TopNQueryBuilder(final TopNQuery query) { this.dataSource = query.getDataSource(); this.virtualColumns = query.getVirtualColumns(); this.dimensionSpec = query.getDimensionSpec(); this.topNMetricSpec = query.getTopNMetricSpec(); this.threshold = query.getThreshold(); this.querySegmentSpec = query.getQuerySegmentSpec(); this.dimFilter = query.getDimensionsFilter(); this.granularity = query.getGranularity(); this.aggregatorSpecs = query.getAggregatorSpecs(); this.postAggregatorSpecs = query.getPostAggregatorSpecs(); this.context = query.getContext(); }
@Override public String toString() { return "TopNQuery{" + "dataSource='" + getDataSource() + '\'' + ", dimensionSpec=" + dimensionSpec + ", topNMetricSpec=" + topNMetricSpec + ", threshold=" + threshold + ", querySegmentSpec=" + getQuerySegmentSpec() + ", virtualColumns=" + virtualColumns + ", dimFilter=" + dimFilter + ", granularity='" + getGranularity() + '\'' + ", aggregatorSpecs=" + aggregatorSpecs + ", postAggregatorSpecs=" + postAggregatorSpecs + '}'; }
@Override public byte[] computeCacheKey(TopNQuery query) { final CacheKeyBuilder builder = new CacheKeyBuilder(TOPN_QUERY) .appendCacheable(query.getDimensionSpec()) .appendCacheable(query.getTopNMetricSpec()) .appendInt(query.getThreshold()) .appendCacheable(query.getGranularity()) .appendCacheable(query.getDimensionsFilter()) .appendCacheables(query.getAggregatorSpecs()) .appendCacheable(query.getVirtualColumns()); final List<PostAggregator> postAggregators = prunePostAggregators(query); if (!postAggregators.isEmpty()) { // Append post aggregators only when they are used as sort keys. // Note that appending an empty list produces a different cache key from not appending it. builder.appendCacheablesIgnoringOrder(postAggregators); } return builder.build(); }
final String dimension = query.getDimensionSpec().getDimension(); final int cardinality = adapter.getDimensionCardinality(dimension); if (queryMetrics != null) { for (AggregatorFactory aggregatorFactory : query.getAggregatorSpecs()) { numBytesPerRecord += aggregatorFactory.getMaxIntermediateSizeWithNulls(); query.initTopNAlgorithmSelector(selector); final ColumnCapabilities columnCapabilities = query.getVirtualColumns() .getColumnCapabilitiesWithFallback(adapter, dimension); } else if (query.getDimensionSpec().getOutputType() != ValueType.STRING) { } else if (selector.isAggregateAllMetrics()) { topNAlgorithm = new PooledTopNAlgorithm(adapter, query, bufferPool); } else if (selector.isAggregateTopNMetricFirst() || query.getContextBoolean("doAggregateTopNMetricFirst", false)) { topNAlgorithm = new AggregateTopNMetricFirstAlgorithm(adapter, query, bufferPool); } else {
@Override public void numMetrics(TopNQuery query) { setDimension("numMetrics", String.valueOf(query.getAggregatorSpecs().size())); }
@Override public Sequence<Result<TopNResultValue>> run( QueryPlus<Result<TopNResultValue>> queryPlus, Map<String, Object> responseContext ) { TopNQuery topNQuery = (TopNQuery) queryPlus.getQuery(); if (topNQuery.getDimensionsFilter() != null) { topNQuery = topNQuery.withDimFilter(topNQuery.getDimensionsFilter().optimize()); } final TopNQuery delegateTopNQuery = topNQuery; if (TopNQueryEngine.canApplyExtractionInPost(delegateTopNQuery)) { final DimensionSpec dimensionSpec = delegateTopNQuery.getDimensionSpec(); QueryPlus<Result<TopNResultValue>> delegateQueryPlus = queryPlus.withQuery( delegateTopNQuery.withDimensionSpec( new DefaultDimensionSpec( dimensionSpec.getDimension(), dimensionSpec.getOutputName() ) ) ); return runner.run(delegateQueryPlus, responseContext); } else { return runner.run(queryPlus.withQuery(delegateTopNQuery), responseContext); } } },
private String dimension = query.getDimensionSpec().getOutputName(); private final AggregatorFactory[] aggregatorFactories = query.getAggregatorSpecs() .toArray(new AggregatorFactory[0]); private final String[] aggFactoryNames = extractFactoryName(query.getAggregatorSpecs()); private final PostAggregator[] postAggregators = query.getPostAggregatorSpecs().toArray(new PostAggregator[0]);
private String dimension = query.getDimensionSpec().getOutputName(); private final List<PostAggregator> prunedAggs = prunePostAggregators(query); private final AggregatorFactory[] aggregatorFactories = query.getAggregatorSpecs() .toArray(new AggregatorFactory[0]); private final String[] aggFactoryNames = extractFactoryName(query.getAggregatorSpecs());
public static boolean canApplyExtractionInPost(TopNQuery query) { return query.getDimensionSpec() != null && query.getDimensionSpec().getExtractionFn() != null && ExtractionFn.ExtractionType.ONE_TO_ONE.equals(query.getDimensionSpec() .getExtractionFn() .getExtractionType()) && query.getTopNMetricSpec().canBeOptimizedUnordered(); } }
private static List<PostAggregator> prunePostAggregators(TopNQuery query) { return AggregatorUtil.pruneDependentPostAgg( query.getPostAggregatorSpecs(), query.getTopNMetricSpec().getMetricName(query.getDimensionSpec()) ); }
@VisibleForTesting public Pair<Integer, Integer> computeStartEnd(int cardinality) { int startIndex = ignoreFirstN; if (previousStop != null) { if (idLookup == null) { throw new UnsupportedOperationException("Only DimensionSelectors which support idLookup() are supported yet"); } int lookupId = idLookup.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 && query.getIntervals().stream().anyMatch(interval -> interval.contains(storageAdapter.getInterval()))) { endIndex = Math.min(endIndex, startIndex + query.getThreshold()); } return Pair.of(startIndex, endIndex); } }
final int minTopNThreshold = query.getContextValue("minTopNThreshold", config.getMinTopNThreshold()); if (query.getThreshold() > minTopNThreshold) { return runner.run(queryPlus, responseContext); runner.run(queryPlus.withQuery(query.withThreshold(minTopNThreshold)), responseContext), new Function<Result<TopNResultValue>, Result<TopNResultValue>>()
@Override public void threshold(TopNQuery query) { setDimension("threshold", String.valueOf(query.getThreshold())); }
@Override public void dimension(TopNQuery query) { setDimension("dimension", query.getDimensionSpec().getDimension()); }
public TopNQueryBuilder(final TopNQuery query) { this.dataSource = query.getDataSource(); this.virtualColumns = query.getVirtualColumns(); this.dimensionSpec = query.getDimensionSpec(); this.topNMetricSpec = query.getTopNMetricSpec(); this.threshold = query.getThreshold(); this.querySegmentSpec = query.getQuerySegmentSpec(); this.dimFilter = query.getDimensionsFilter(); this.granularity = query.getGranularity(); this.aggregatorSpecs = query.getAggregatorSpecs(); this.postAggregatorSpecs = query.getPostAggregatorSpecs(); this.context = query.getContext(); }
@Override public byte[] computeCacheKey(TopNQuery query) { final CacheKeyBuilder builder = new CacheKeyBuilder(TOPN_QUERY) .appendCacheable(query.getDimensionSpec()) .appendCacheable(query.getTopNMetricSpec()) .appendInt(query.getThreshold()) .appendCacheable(query.getGranularity()) .appendCacheable(query.getDimensionsFilter()) .appendCacheables(query.getAggregatorSpecs()) .appendCacheable(query.getVirtualColumns()); final List<PostAggregator> postAggregators = prunePostAggregators(query); if (!postAggregators.isEmpty()) { // Append post aggregators only when they are used as sort keys. // Note that appending an empty list produces a different cache key from not appending it. builder.appendCacheablesIgnoringOrder(postAggregators); } return builder.build(); }
final String dimension = query.getDimensionSpec().getDimension(); final int cardinality = adapter.getDimensionCardinality(dimension); if (queryMetrics != null) { for (AggregatorFactory aggregatorFactory : query.getAggregatorSpecs()) { numBytesPerRecord += aggregatorFactory.getMaxIntermediateSizeWithNulls(); query.initTopNAlgorithmSelector(selector); final ColumnCapabilities columnCapabilities = query.getVirtualColumns() .getColumnCapabilitiesWithFallback(adapter, dimension); } else if (query.getDimensionSpec().getOutputType() != ValueType.STRING) { } else if (selector.isAggregateAllMetrics()) { topNAlgorithm = new PooledTopNAlgorithm(adapter, query, bufferPool); } else if (selector.isAggregateTopNMetricFirst() || query.getContextBoolean("doAggregateTopNMetricFirst", false)) { topNAlgorithm = new AggregateTopNMetricFirstAlgorithm(adapter, query, bufferPool); } else {