diff --git a/server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/utils/StarTreeQueryHelper.java b/server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/utils/StarTreeQueryHelper.java index 04a98e82a97fd..d516a886b6170 100644 --- a/server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/utils/StarTreeQueryHelper.java +++ b/server/src/main/java/org/opensearch/index/compositeindex/datacube/startree/utils/StarTreeQueryHelper.java @@ -11,6 +11,8 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.SegmentReader; import org.apache.lucene.search.CollectionTerminatedException; +import org.apache.lucene.util.FixedBitSet; +import org.apache.lucene.util.NumericUtils; import org.opensearch.common.lucene.Lucene; import org.opensearch.index.codec.composite.CompositeIndexFieldInfo; import org.opensearch.index.codec.composite.CompositeIndexReader; @@ -28,14 +30,15 @@ import org.opensearch.search.aggregations.AggregatorFactory; import org.opensearch.search.aggregations.LeafBucketCollector; import org.opensearch.search.aggregations.LeafBucketCollectorBase; +import org.opensearch.search.aggregations.metrics.CompensatedSum; import org.opensearch.search.aggregations.metrics.MetricAggregatorFactory; import org.opensearch.search.aggregations.support.ValuesSource; import org.opensearch.search.builder.SearchSourceBuilder; import org.opensearch.search.internal.SearchContext; -import org.opensearch.search.startree.StarTreeFilter; import org.opensearch.search.startree.StarTreeQueryContext; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -50,8 +53,6 @@ */ public class StarTreeQueryHelper { - private static Map starTreeValuesMap = new HashMap<>(); - /** * Checks if the search context can be supported by star-tree */ @@ -69,10 +70,6 @@ public static boolean isStarTreeSupported(SearchContext context, boolean trackTo return canUseStarTree; } - /** - * Gets a parsed OriginalOrStarTreeQuery from the search context and source builder. - * Returns null if the query cannot be supported. - */ /** * Gets a parsed OriginalOrStarTreeQuery from the search context and source builder. @@ -98,10 +95,14 @@ public static StarTreeQueryContext getStarTreeQueryContext(SearchContext context return null; } + boolean needCaching = context.aggregations().factories().getFactories().length > 1; +// List metricInfos = new ArrayList<>(); for (AggregatorFactory aggregatorFactory : context.aggregations().factories().getFactories()) { - if (validateStarTreeMetricSuport(compositeMappedFieldType, aggregatorFactory) == false) { + MetricStat metricStat = validateStarTreeMetricSuport(compositeMappedFieldType, aggregatorFactory); + if (metricStat == null) { return null; } +// metricInfos.add(new ) } return starTreeQueryContext; @@ -150,10 +151,11 @@ private static Map getStarTreePredicates(QueryBuilder queryBuilder return predicateMap; } - private static boolean validateStarTreeMetricSuport( + private static MetricStat validateStarTreeMetricSuport( CompositeDataCubeFieldType compositeIndexFieldInfo, AggregatorFactory aggregatorFactory ) { +// List metricStats = new ArrayList<>(); if (aggregatorFactory instanceof MetricAggregatorFactory && aggregatorFactory.getSubFactories().getFactories().length == 0) { String field; Map> supportedMetrics = compositeIndexFieldInfo.getMetrics() @@ -162,10 +164,12 @@ private static boolean validateStarTreeMetricSuport( MetricStat metricStat = ((MetricAggregatorFactory) aggregatorFactory).getMetricStat(); field = ((MetricAggregatorFactory) aggregatorFactory).getField(); - return supportedMetrics.containsKey(field) && supportedMetrics.get(field).contains(metricStat); - } else { - return false; + + if (supportedMetrics.containsKey(field) && supportedMetrics.get(field).contains(metricStat)) { + return metricStat; + } } + return null; } public static CompositeIndexFieldInfo getSupportedStarTree(SearchContext context) { @@ -200,19 +204,32 @@ public static LeafBucketCollector getStarTreeLeafCollector( SortedNumericStarTreeValuesIterator valuesIterator = (SortedNumericStarTreeValuesIterator) starTreeValues.getMetricValuesIterator( metricName ); - StarTreeValuesIterator result = context.getStarTreeFilteredValues(ctx, starTreeValues); + // Obtain a FixedBitSet of matched document IDs + FixedBitSet matchedDocIds = context.getStarTreeFilteredValues(ctx, starTreeValues); // Assuming this method gives a FixedBitSet + + // Safety check: make sure the FixedBitSet is non-null and valid + if (matchedDocIds == null) { + throw new IllegalStateException("FixedBitSet is null"); + } + + int numBits = matchedDocIds.length(); // Get the length of the FixedBitSet - int entryId; - while ((entryId = result.nextEntry()) != StarTreeValuesIterator.NO_MORE_ENTRIES) { - if (valuesIterator.advance(entryId) != StarTreeValuesIterator.NO_MORE_ENTRIES) { + // Iterate over the FixedBitSet + for (int bit = matchedDocIds.nextSetBit(0); bit != -1; bit = bit + 1 < numBits ? matchedDocIds.nextSetBit(bit + 1) : -1) { + // Advance to the bit (entryId) in the valuesIterator + if (valuesIterator.advance(bit) != StarTreeValuesIterator.NO_MORE_ENTRIES) { int count = valuesIterator.valuesCount(); for (int i = 0; i < count; i++) { long value = valuesIterator.nextValue(); - valueConsumer.accept(value); // Apply the operation (max, sum, etc.) + valueConsumer.accept(value); // Apply the consumer operation (e.g., max, sum) } } } + + // Call the final consumer after processing all entries finalConsumer.run(); + + // Return a LeafBucketCollector that terminates collection return new LeafBucketCollectorBase(sub, valuesSource.doubleValues(ctx)) { @Override public void collect(int doc, long bucket) { @@ -220,4 +237,131 @@ public void collect(int doc, long bucket) { } }; } + +// public static LeafBucketCollector getStarTreeLeafCollectorNew( +// SearchContext context, +// ValuesSource.Numeric valuesSource, +// LeafReaderContext ctx, +// LeafBucketCollector sub, +// CompositeIndexFieldInfo starTree, +// String metric, +// Consumer valueConsumer, +// Runnable finalConsumer +// ) throws IOException { +// // Check in contextCache if the star-tree values are already computed +// Map> cache = context.getStarTreeQueryContext().getLeafResultsCache(); +// if(cache != null) { +// +// if (cache.containsKey(ctx)) { +// MetricInfo metricInfoMap = cache.get(ctx).get(metric); +// finalConsumer.run(); +// } +// } +// else if (!cache.containsKey(ctx)) { +// // TODO: fetch from cache +// +// } else { +// // TODO: compute cache first +// } +// +// StarTreeValues starTreeValues = getStarTreeValues(ctx, starTree); +// String fieldName = ((ValuesSource.Numeric.FieldData) valuesSource).getIndexFieldName(); +// String metricName = StarTreeUtils.fullyQualifiedFieldNameForStarTreeMetricsDocValues(starTree.getField(), fieldName, metric); +// +// assert starTreeValues != null; +// List valuesIterators; +// SortedNumericStarTreeValuesIterator valuesIterator = (SortedNumericStarTreeValuesIterator) starTreeValues.getMetricValuesIterator( +// metricName +// ); +// StarTreeValuesIterator result = context.getStarTreeFilteredValues(ctx, starTreeValues); +// +// int entryId; +// while ((entryId = result.nextEntry()) != StarTreeValuesIterator.NO_MORE_ENTRIES) { +// for +// if (valuesIterator.advance(entryId) != StarTreeValuesIterator.NO_MORE_ENTRIES) { +// int count = valuesIterator.valuesCount(); +// for (int i = 0; i < count; i++) { +// long value = valuesIterator.nextValue(); +// valueConsumer.accept(value); // Apply the operation (max, sum, etc.) +// } +// } +// } +// finalConsumer.run(); +// return new LeafBucketCollectorBase(sub, valuesSource.doubleValues(ctx)) { +// @Override +// public void collect(int doc, long bucket) { +// throw new CollectionTerminatedException(); +// } +// }; +// } +// +// public abstract class MetricInfo { +// String metric; +// MetricStat metricStat; +// +// +// +// MetricInfo (String metric, MetricStat metricStat) { +// if (metricStat == MetricStat.SUM) { +// return new SumMetricInfo(metric); +// } +// return null; +// } +// +// +// public abstract void valueConsumer(long value); +// +// public abstract T getMetricValue(); +// } +// +// public class SumMetricInfo extends MetricInfo { +// CompensatedSum compensatedSum; +// +// public SumMetricInfo(String metric) { +// super(metric, MetricStat.SUM); +// compensatedSum = new CompensatedSum(0,0); +// } +// +// public void valueConsumer(long value) { +// compensatedSum.add(NumericUtils.sortableLongToDouble(value)); +// } +// +// public Double getMetricValue() { +// return compensatedSum.value(); +// } +// } +// +// public static void computeLeafResultsCache(SearchContext context, +// LeafReaderContext ctx, +// CompositeIndexFieldInfo starTree, +// List metricInfos) throws IOException { +// Map leafCache = new HashMap<>(); +// StarTreeValues starTreeValues = getStarTreeValues(ctx, starTree); +// assert starTreeValues != null; +// StarTreeValuesIterator result = context.getStarTreeFilteredValues(ctx, starTreeValues); +// +// List entryIdCache = new ArrayList<>(); +// int entryId; +// while ((entryId = result.nextEntry()) != StarTreeValuesIterator.NO_MORE_ENTRIES) { +// entryIdCache.add(entryId); +// } +// +// for (MetricInfo metricInfo : metricInfos) { +// SortedNumericStarTreeValuesIterator valuesIterator = (SortedNumericStarTreeValuesIterator) starTreeValues.getMetricValuesIterator( +// metricInfo.metric +// ); +// +// for (int cachedEntryId : entryIdCache) { +// if (valuesIterator.advance(cachedEntryId) != StarTreeValuesIterator.NO_MORE_ENTRIES) { +// int count = valuesIterator.valuesCount(); +// for (int i = 0; i < count; i++) { +// long value = valuesIterator.nextValue(); +// metricInfo.valueConsumer(value); +// } +// } +// } +// leafCache.put(metricInfo.metric, metricInfo); +// } +// context.getStarTreeQueryContext().getLeafResultsCache().put(ctx, leafCache); +// } } diff --git a/server/src/main/java/org/opensearch/search/DefaultSearchContext.java b/server/src/main/java/org/opensearch/search/DefaultSearchContext.java index fd53fa4153b1e..cfe2ad7681a58 100644 --- a/server/src/main/java/org/opensearch/search/DefaultSearchContext.java +++ b/server/src/main/java/org/opensearch/search/DefaultSearchContext.java @@ -44,6 +44,7 @@ import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BitSet; +import org.apache.lucene.util.FixedBitSet; import org.opensearch.Version; import org.opensearch.action.search.SearchShardTask; import org.opensearch.action.search.SearchType; @@ -1170,13 +1171,12 @@ public StarTreeQueryContext getStarTreeQueryContext() { } @Override - public StarTreeValuesIterator getStarTreeFilteredValues(LeafReaderContext ctx, StarTreeValues starTreeValues) throws IOException { + public FixedBitSet getStarTreeFilteredValues(LeafReaderContext ctx, StarTreeValues starTreeValues) throws IOException { if (this.starTreeValuesMap.containsKey(ctx)) { - return starTreeValuesMap.get(ctx); } StarTreeFilter filter = new StarTreeFilter(starTreeValues, this.getStarTreeQueryContext().getQueryMap()); - StarTreeValuesIterator result = filter.getStarTreeResult(); + FixedBitSet result = filter.getStarTreeResult(); starTreeValuesMap.put(ctx, result); return result; diff --git a/server/src/main/java/org/opensearch/search/aggregations/metrics/AvgAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/metrics/AvgAggregator.java index f1b32fe8c9602..ffd14976b57b0 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/metrics/AvgAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/metrics/AvgAggregator.java @@ -34,6 +34,7 @@ import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.CollectionTerminatedException; import org.apache.lucene.search.ScoreMode; +import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.NumericUtils; import org.opensearch.common.lease.Releasables; import org.opensearch.common.util.BigArrays; @@ -268,18 +269,29 @@ public LeafBucketCollector getStarTreeLeafCollector( SortedNumericStarTreeValuesIterator countValueIterator = (SortedNumericStarTreeValuesIterator) starTreeValues.getMetricValuesIterator( countMetricName ); - StarTreeValuesIterator result = context.getStarTreeFilteredValues(ctx, starTreeValues); + FixedBitSet matchedDocIds = context.getStarTreeFilteredValues(ctx, starTreeValues); - int entryId; - while ((entryId = result.nextEntry()) != StarTreeValuesIterator.NO_MORE_ENTRIES) { - if (sumValuesIterator.advance(entryId) != StarTreeValuesIterator.NO_MORE_ENTRIES) { + + // Safety check: make sure the FixedBitSet is non-null and valid + if (matchedDocIds == null) { + throw new IllegalStateException("FixedBitSet is null"); + } + + int numBits = matchedDocIds.length(); // Get the length of the FixedBitSet + + // Iterate over the FixedBitSet + for (int bit = matchedDocIds.nextSetBit(0); bit != -1; bit = bit + 1 < numBits ? matchedDocIds.nextSetBit(bit + 1) : -1) { + // Advance to the bit (entryId) in the valuesIterator + if (sumValuesIterator.advance(bit) != StarTreeValuesIterator.NO_MORE_ENTRIES && + countValueIterator.advance(bit) != StarTreeValuesIterator.NO_MORE_ENTRIES) { int count = sumValuesIterator.valuesCount(); for (int i = 0; i < count; i++) { kahanSummation.add(NumericUtils.sortableLongToDouble(sumValuesIterator.nextValue())); - counts.increment(0, countValueIterator.nextValue()); + counts.increment(0, countValueIterator.nextValue()); // Apply the consumer operation (e.g., max, sum) } } } + sums.set(0, kahanSummation.value()); return new LeafBucketCollectorBase(sub, valuesSource.doubleValues(ctx)) { @Override diff --git a/server/src/main/java/org/opensearch/search/aggregations/metrics/MaxAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/metrics/MaxAggregator.java index e68dcc4acb614..338f12ea238e1 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/metrics/MaxAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/metrics/MaxAggregator.java @@ -169,7 +169,7 @@ public LeafBucketCollector getStarTreeCollector(LeafReaderContext ctx, LeafBucke ctx, sub, starTree, - MetricStat.SUM.getTypeName(), + MetricStat.MAX.getTypeName(), value -> { max.set(Math.max(max.get(), (NumericUtils.sortableLongToDouble(value)))); }, diff --git a/server/src/main/java/org/opensearch/search/aggregations/metrics/MinAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/metrics/MinAggregator.java index 11f38020aa8a1..3b4e789ced691 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/metrics/MinAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/metrics/MinAggregator.java @@ -166,7 +166,7 @@ public LeafBucketCollector getStarTreeCollector(LeafReaderContext ctx, LeafBucke ctx, sub, starTree, - MetricStat.SUM.getTypeName(), + MetricStat.MIN.getTypeName(), value -> { min.set(Math.min(min.get(), (NumericUtils.sortableLongToDouble(value)))); }, diff --git a/server/src/main/java/org/opensearch/search/aggregations/metrics/SumAggregator.java b/server/src/main/java/org/opensearch/search/aggregations/metrics/SumAggregator.java index 617ee6a939e6c..c3c7ad299430c 100644 --- a/server/src/main/java/org/opensearch/search/aggregations/metrics/SumAggregator.java +++ b/server/src/main/java/org/opensearch/search/aggregations/metrics/SumAggregator.java @@ -100,6 +100,7 @@ public LeafBucketCollector getLeafCollector(LeafReaderContext ctx, final LeafBuc if (supportedStarTree != null) { return getStarTreeCollector(ctx, sub, supportedStarTree); } + System.out.println("nopes nopes"); return getDefaultLeafCollector(ctx, sub); } @@ -135,7 +136,7 @@ public void collect(int doc, long bucket) throws IOException { public LeafBucketCollector getStarTreeCollector(LeafReaderContext ctx, LeafBucketCollector sub, CompositeIndexFieldInfo starTree) throws IOException { - final CompensatedSum kahanSummation = new CompensatedSum(0, 0); + final CompensatedSum kahanSummation = new CompensatedSum(sums.get(0), 0); return StarTreeQueryHelper.getStarTreeLeafCollector( context, valuesSource, diff --git a/server/src/main/java/org/opensearch/search/internal/SearchContext.java b/server/src/main/java/org/opensearch/search/internal/SearchContext.java index 66b2ba9c98431..ae78e8ca76845 100644 --- a/server/src/main/java/org/opensearch/search/internal/SearchContext.java +++ b/server/src/main/java/org/opensearch/search/internal/SearchContext.java @@ -36,6 +36,7 @@ import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.FieldDoc; import org.apache.lucene.search.Query; +import org.apache.lucene.util.FixedBitSet; import org.opensearch.action.search.SearchShardTask; import org.opensearch.action.search.SearchType; import org.opensearch.common.Nullable; @@ -130,7 +131,7 @@ public List toInternalAggregations(Collection co private final List releasables = new CopyOnWriteArrayList<>(); private final AtomicBoolean closed = new AtomicBoolean(false); private InnerHitsContext innerHitsContext; - protected volatile Map starTreeValuesMap; + protected volatile Map starTreeValuesMap; private volatile boolean searchTimedOut; protected SearchContext() {} @@ -545,7 +546,7 @@ public SearchContext starTreeQueryContext(StarTreeQueryContext starTreeQueryCont return this; } - public StarTreeValuesIterator getStarTreeFilteredValues(LeafReaderContext ctx, StarTreeValues starTreeValues) throws IOException { + public FixedBitSet getStarTreeFilteredValues(LeafReaderContext ctx, StarTreeValues starTreeValues) throws IOException { return null; } } diff --git a/server/src/main/java/org/opensearch/search/startree/StarTreeFilter.java b/server/src/main/java/org/opensearch/search/startree/StarTreeFilter.java index fee32ba48e1f5..d56ce506ebddb 100644 --- a/server/src/main/java/org/opensearch/search/startree/StarTreeFilter.java +++ b/server/src/main/java/org/opensearch/search/startree/StarTreeFilter.java @@ -10,6 +10,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.lucene.util.BitSet; import org.apache.lucene.util.DocIdSetBuilder; import org.apache.lucene.util.FixedBitSet; import org.opensearch.index.compositeindex.datacube.Dimension; @@ -57,48 +58,59 @@ public StarTreeFilter(StarTreeValues starTreeAggrStructure, Map pr *
  • For the remaining columns, use star-tree doc values to match them * */ - public StarTreeValuesIterator getStarTreeResult() throws IOException { + public FixedBitSet getStarTreeResult() throws IOException { StarTreeResult starTreeResult = traverseStarTree(); - List andIterators = new ArrayList<>(); - andIterators.add(new StarTreeValuesIterator(starTreeResult._matchedDocIds.build().iterator())); - StarTreeValuesIterator starTreeValuesIterator = andIterators.get(0); - int length = 0; - // No matches, return + // Initialize FixedBitSet with size maxMatchedDoc + 1 + FixedBitSet bitSet = new FixedBitSet(starTreeResult.maxMatchedDoc + 1); + StarTreeValuesIterator starTreeValuesIterator = new StarTreeValuesIterator(starTreeResult._matchedDocIds.build().iterator()); + + // No matches, return an empty FixedBitSet if (starTreeResult.maxMatchedDoc == -1) { - return starTreeValuesIterator; + return bitSet; + } + + // Set bits in FixedBitSet for initially matched documents + while (starTreeValuesIterator.nextEntry() != NO_MORE_DOCS) { + bitSet.set(starTreeValuesIterator.entryId()); } + + // Temporary FixedBitSet reused for filtering + FixedBitSet tempBitSet = new FixedBitSet(starTreeResult.maxMatchedDoc + 1); + + // Process remaining predicate columns to further filter the results for (String remainingPredicateColumn : starTreeResult._remainingPredicateColumns) { logger.debug("remainingPredicateColumn : {}, maxMatchedDoc : {} ", remainingPredicateColumn, starTreeResult.maxMatchedDoc); - DocIdSetBuilder builder = new DocIdSetBuilder(starTreeResult.maxMatchedDoc + 1); + SortedNumericStarTreeValuesIterator ndv = (SortedNumericStarTreeValuesIterator) this.starTreeValues.getDimensionValuesIterator( remainingPredicateColumn ); - List entryIds = new ArrayList<>(); + long queryValue = queryMap.get(remainingPredicateColumn); // Get the query value directly - while (starTreeValuesIterator.nextEntry() != NO_MORE_DOCS) { - int entryId = starTreeValuesIterator.entryId(); - if (ndv.advance(entryId) > 0) { + // Clear the temporary bit set before reuse + tempBitSet.clear(0, starTreeResult.maxMatchedDoc + 1); + + // Iterate over the current set of matched document IDs + for (int entryId = bitSet.nextSetBit(0); entryId >= 0; entryId = bitSet.nextSetBit(entryId + 1)) { + if (ndv.advance(entryId) != StarTreeValuesIterator.NO_MORE_ENTRIES) { final int valuesCount = ndv.valuesCount(); for (int i = 0; i < valuesCount; i++) { long value = ndv.nextValue(); - // Directly compare value with queryValue + // Compare the value with the query value if (value == queryValue) { - entryIds.add(entryId); - break; + tempBitSet.set(entryId); // Set bit for the matching entryId + break; // No need to check other values for this entryId } } } } - DocIdSetBuilder.BulkAdder adder = builder.grow(entryIds.size()); - for (int entryId : entryIds) { - adder.add(entryId); - } - length = entryIds.size(); - starTreeValuesIterator = new StarTreeValuesIterator(builder.build().iterator()); + + // Perform intersection of the current matches with the temp results for this predicate + bitSet.and(tempBitSet); } - return starTreeValuesIterator; + + return bitSet; // Return the final FixedBitSet with all matches } /** diff --git a/server/src/main/java/org/opensearch/search/startree/StarTreeQueryContext.java b/server/src/main/java/org/opensearch/search/startree/StarTreeQueryContext.java index 2b12c9bba604f..6d184938ccfb5 100644 --- a/server/src/main/java/org/opensearch/search/startree/StarTreeQueryContext.java +++ b/server/src/main/java/org/opensearch/search/startree/StarTreeQueryContext.java @@ -8,10 +8,15 @@ package org.opensearch.search.startree; +import org.apache.lucene.index.LeafReaderContext; import org.opensearch.common.annotation.ExperimentalApi; import org.opensearch.index.codec.composite.CompositeIndexFieldInfo; +import org.opensearch.index.compositeindex.datacube.startree.utils.StarTreeQueryHelper; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * Query class for querying star tree data structure. @@ -33,6 +38,18 @@ public class StarTreeQueryContext { */ private final Map queryMap; +// /** +// * Cache for leaf results +// * This is used to cache the results for each leaf reader context +// * to avoid reading the data from the leaf reader context multiple times +// */ +// private volatile Map> leafResultsCache; + +// /** +// * List of metrics to be computed & cached +// */ +// private List metrics; + public StarTreeQueryContext(CompositeIndexFieldInfo starTree, Map queryMap) { this.starTree = starTree; this.queryMap = queryMap; @@ -45,4 +62,18 @@ public CompositeIndexFieldInfo getStarTree() { public Map getQueryMap() { return queryMap; } + +// public void initializeLeafResultsCache() { +// this.leafResultsCache = new ConcurrentHashMap<>(); +// this.metrics = new ArrayList<>(); +// } +// +// public Map> getLeafResultsCache() { +// return leafResultsCache; +// } +// +// public void addMetric(StarTreeQueryHelper.MetricInfo metric) { +// metrics.add(metric); +// } + }