| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.carbondata.core.scan.filter; |
| |
| import java.util.AbstractCollection; |
| import java.util.BitSet; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.carbondata.core.datastore.page.ColumnPage; |
| import org.apache.carbondata.core.metadata.datatype.DataType; |
| import org.apache.carbondata.core.metadata.datatype.DataTypes; |
| import org.apache.carbondata.core.metadata.schema.table.column.CarbonMeasure; |
| import org.apache.carbondata.core.scan.filter.executer.FilterBitSetUpdater; |
| import org.apache.carbondata.core.scan.filter.executer.MeasureColumnExecutorFilterInfo; |
| import org.apache.carbondata.core.scan.filter.resolver.resolverinfo.MeasureColumnResolvedFilterInfo; |
| import org.apache.carbondata.core.util.DataTypeUtil; |
| |
| import it.unimi.dsi.fastutil.booleans.BooleanOpenHashSet; |
| import it.unimi.dsi.fastutil.bytes.ByteOpenHashSet; |
| import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet; |
| import it.unimi.dsi.fastutil.floats.FloatOpenHashSet; |
| import it.unimi.dsi.fastutil.ints.IntOpenHashSet; |
| import it.unimi.dsi.fastutil.longs.LongOpenHashSet; |
| import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet; |
| |
| /** |
| * Utility class for executing the filter |
| */ |
| public class FilterExecutorUtil { |
| /** |
| * Below method will be used to execute measure filter based on data type |
| * This is done to avoid conversion of primitive type to primitive object |
| * as it may cause lots of gc when number of record is high and will impact performance |
| * |
| * @param page |
| * @param bitSet |
| * @param measureColumnExecutorFilterInfo |
| * @param measureColumnResolvedFilterInfo |
| * @param filterBitSetUpdater |
| */ |
| public static void executeIncludeExcludeFilterForMeasure(ColumnPage page, BitSet bitSet, |
| MeasureColumnExecutorFilterInfo measureColumnExecutorFilterInfo, |
| MeasureColumnResolvedFilterInfo measureColumnResolvedFilterInfo, |
| FilterBitSetUpdater filterBitSetUpdater) { |
| final CarbonMeasure measure = measureColumnResolvedFilterInfo.getMeasure(); |
| final DataType dataType = FilterUtil.getMeasureDataType(measureColumnResolvedFilterInfo); |
| int numberOfRows = page.getPageSize(); |
| BitSet nullBitSet = page.getNullBits(); |
| Object[] filterKeys = measureColumnExecutorFilterInfo.getFilterKeys(); |
| // to handle the null value |
| for (int i = 0; i < filterKeys.length; i++) { |
| if (filterKeys[i] == null) { |
| for (int j = nullBitSet.nextSetBit(0); j >= 0; j = nullBitSet.nextSetBit(j + 1)) { |
| bitSet.flip(j); |
| } |
| } |
| } |
| AbstractCollection filterSet = measureColumnExecutorFilterInfo.getFilterSet(); |
| if (dataType == DataTypes.BYTE) { |
| ByteOpenHashSet byteOpenHashSet = (ByteOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (byteOpenHashSet.contains((byte) page.getLong(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.BOOLEAN) { |
| BooleanOpenHashSet booleanOpenHashSet = (BooleanOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (booleanOpenHashSet.contains(page.getBoolean(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.SHORT) { |
| ShortOpenHashSet shortOpenHashSet = (ShortOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (shortOpenHashSet.contains((short) page.getLong(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.INT) { |
| IntOpenHashSet intOpenHashSet = (IntOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (intOpenHashSet.contains((int) page.getLong(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.FLOAT) { |
| FloatOpenHashSet floatOpenHashSet = (FloatOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (floatOpenHashSet.contains((float) page.getDouble(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.DOUBLE) { |
| DoubleOpenHashSet doubleOpenHashSet = (DoubleOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (doubleOpenHashSet.contains(page.getDouble(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (dataType == DataTypes.LONG) { |
| LongOpenHashSet longOpenHashSet = (LongOpenHashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| if (longOpenHashSet.contains(page.getLong(i))) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else if (DataTypes.isDecimal(dataType)) { |
| Set bigDecimalHashSet = (HashSet) filterSet; |
| for (int i = 0; i < numberOfRows; i++) { |
| if (!nullBitSet.get(i)) { |
| final Object measureObjectBasedOnDataType = |
| DataTypeUtil.getMeasureObjectBasedOnDataType(page, i, dataType, measure); |
| if (bigDecimalHashSet.contains(measureObjectBasedOnDataType)) { |
| filterBitSetUpdater.updateBitset(bitSet, i); |
| } |
| } |
| } |
| } else { |
| throw new IllegalArgumentException("Invalid data type"); |
| } |
| } |
| } |