/** * 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.hadoop.hive.ql.exec.vector.keyseries; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hive.ql.exec.vector.VectorizedRowBatch; import com.google.common.base.Preconditions; /** * Implementation of when a one key series or a serialized key series is being presented. * */ public abstract class VectorKeySeriesSingleImpl extends VectorKeySeriesImpl implements VectorKeySeries { private static final Log LOG = LogFactory.getLog(VectorKeySeriesSingleImpl.class.getName()); protected int currentBatchSize; // The number of keys (with sequential duplicates collapsed, both NULL and non-NULL) in the batch. protected int seriesCount; // The current position in the key series. protected int seriesPosition; // The number of duplicates for each series key (NULL or non-NULL). protected final int[] duplicateCounts; // Whether a series key is NULL. protected final boolean[] seriesIsAllNull; // The number of non-NULL keys. They have associated hash codes and key data. protected int nonNullKeyCount; // The current non-NULL key position. protected int nonNullKeyPosition; // The hash code for each non-NULL key. protected final int[] hashCodes; VectorKeySeriesSingleImpl() { super(); seriesCount = 0; seriesPosition = 0; duplicateCounts = new int[VectorizedRowBatch.DEFAULT_SIZE]; seriesIsAllNull = new boolean[VectorizedRowBatch.DEFAULT_SIZE]; nonNullKeyCount = 0; nonNullKeyPosition = -1; hashCodes = new int[VectorizedRowBatch.DEFAULT_SIZE]; } public boolean validate() { Preconditions.checkState(seriesCount > 0); Preconditions.checkState(seriesCount <= currentBatchSize); Preconditions.checkState(nonNullKeyCount >= 0); Preconditions.checkState(nonNullKeyCount <= seriesCount); validateDuplicateCount(); return true; } private void validateDuplicateCount() { int sum = 0; int duplicateCount; for (int i = 0; i < seriesCount; i++) { duplicateCount = duplicateCounts[i]; Preconditions.checkState(duplicateCount > 0); Preconditions.checkState(duplicateCount <= currentBatchSize); sum += duplicateCount; } Preconditions.checkState(sum == currentBatchSize); } @Override public void positionToFirst() { seriesPosition = 0; currentLogical = 0; currentDuplicateCount = duplicateCounts[0]; currentIsAllNull = seriesIsAllNull[0]; if (!currentIsAllNull) { nonNullKeyPosition = 0; currentHashCode = hashCodes[0]; setNextNonNullKey(0); } else { nonNullKeyPosition = -1; } Preconditions.checkState(currentDuplicateCount > 0); } // Consumes whole key. @Override public boolean next() { currentLogical += currentDuplicateCount; if (currentLogical >= currentBatchSize) { return false; } Preconditions.checkState(seriesPosition + 1 < seriesCount); seriesPosition++; currentDuplicateCount = duplicateCounts[seriesPosition]; currentIsAllNull = seriesIsAllNull[seriesPosition]; if (!currentIsAllNull) { Preconditions.checkState(nonNullKeyPosition + 1 < nonNullKeyCount); nonNullKeyPosition++; currentHashCode = hashCodes[nonNullKeyPosition]; setNextNonNullKey(nonNullKeyPosition); } Preconditions.checkState(currentDuplicateCount > 0); return true; } // For use by VectorKeySeriesMulti so that the minimum equal key can be advanced. public void advance(int duplicateCount) { currentLogical += currentDuplicateCount; currentDuplicateCount -= duplicateCount; if (currentDuplicateCount == 0) { seriesPosition++; currentIsAllNull = seriesIsAllNull[seriesPosition]; currentDuplicateCount = duplicateCounts[seriesPosition]; if (!currentIsAllNull) { nonNullKeyPosition++; currentHashCode = hashCodes[nonNullKeyPosition]; setNextNonNullKey(nonNullKeyPosition); } } } protected abstract void setNextNonNullKey(int nonNullKeyPosition); }