/** * Performs a DFS search of the filter tree, populating the specified map with the number of instances of each * filter type appearing in the filter. * * @param filter The filter that needs to be traversed * * @return A map containing a count of each type of filter */ private Map<String, Long> buildFilterCount(Filter filter) { if (filter == null) { return Collections.emptyMap(); } Map<String, Long> filterTypeCounter = new LinkedHashMap<>(); Deque<Filter> filterStack = new ArrayDeque<>(); filterStack.add(filter); while (!filterStack.isEmpty()) { Filter currentFilter = filterStack.pop(); filterTypeCounter.merge(currentFilter.getClass().getSimpleName(), 1L, (old, increment) -> old + increment); if (currentFilter instanceof ComplexFilter) { filterStack.addAll(((ComplexFilter) currentFilter).getFields()); } } return filterTypeCounter; } }
/** * Evaluates a complex filter by performing a {@link SqlOperator} over a list of dimensions. * * @param complexFilter A complexFilter to be evaluated. * @param operator The sql operator to be applied to a complexFilter's fields. * @param builder The RelBuilder used to build queries with Calcite. * @param apiToFieldMapper A function to get the aliased aggregation's name from the metric name. * * @return a RexNode containing an equivalent filter to the one given. */ private RexNode listEvaluate( ComplexFilter complexFilter, SqlOperator operator, RelBuilder builder, ApiToFieldMapper apiToFieldMapper ) { List<RexNode> rexNodes = complexFilter.getFields() .stream() .map(filter -> dispatcher.invoke(filter, builder, apiToFieldMapper)) .collect(Collectors.toList()); return builder.call( operator, rexNodes ); } }