/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.linkedin.pinot.core.query.pruner; import com.linkedin.pinot.common.data.FieldSpec; import com.linkedin.pinot.common.request.FilterOperator; import com.linkedin.pinot.common.utils.request.FilterQueryTree; import com.linkedin.pinot.core.segment.index.ColumnMetadata; import java.util.List; import java.util.Map; import javax.annotation.Nonnull; /** * Abstract implementation for {@link SegmentPruner}, containing code common to * sub classes. * */ public abstract class AbstractSegmentPruner implements SegmentPruner { public abstract boolean pruneSegment(FilterQueryTree filterQueryTree, Map<String, ColumnMetadata> columnMetadataMap); /** * Given a non leaf filter query tree node prunes it as follows: * <ul> * <li> For 'AND', node is pruned as long as at least one child can prune it. </li> * <li> For 'OR', node is pruned as long as all children can prune it. </li> * </ul> * * @param filterQueryTree Non leaf node in the filter query tree. * @param columnMetadataMap Map for column metadata. * * @return True to prune, false otherwise */ protected boolean pruneNonLeaf(@Nonnull FilterQueryTree filterQueryTree, @Nonnull Map<String, ColumnMetadata> columnMetadataMap) { List<FilterQueryTree> children = filterQueryTree.getChildren(); if (children.isEmpty()) { return false; } FilterOperator filterOperator = filterQueryTree.getOperator(); switch (filterOperator) { case AND: for (FilterQueryTree child : children) { if (pruneSegment(child, columnMetadataMap)) { return true; } } return false; case OR: for (FilterQueryTree child : children) { if (!pruneSegment(child, columnMetadataMap)) { return false; } } return true; default: throw new IllegalStateException("Unsupported filter operator: " + filterOperator); } } /** * Helper method to get value of the specified type from the given string. * @param input Input String for which to get the value * @param dataType Data type to construct from the String. * @return Comparable value of specified data type built from the input String. */ protected static Comparable getValue(@Nonnull String input, @Nonnull FieldSpec.DataType dataType) { switch (dataType) { case INT: return Integer.valueOf(input); case LONG: return Long.valueOf(input); case FLOAT: return Float.valueOf(input); case DOUBLE: return Double.valueOf(input); case STRING: return input; default: throw new IllegalStateException("Unsupported data type: " + dataType); } } }