diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java index ee49a0dc0b6c..4ccd3f498118 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java @@ -95,8 +95,8 @@ import org.apache.druid.query.aggregation.FloatMinAggregatorFactory; import org.apache.druid.query.aggregation.LongMaxAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; import org.apache.druid.query.filter.SelectorDimFilter; import org.apache.druid.segment.DoubleDimensionHandler; import org.apache.druid.segment.IndexIO; diff --git a/processing/src/main/java/org/apache/druid/jackson/AggregatorsModule.java b/processing/src/main/java/org/apache/druid/jackson/AggregatorsModule.java index dddf39956edb..f7aca511e17d 100644 --- a/processing/src/main/java/org/apache/druid/jackson/AggregatorsModule.java +++ b/processing/src/main/java/org/apache/druid/jackson/AggregatorsModule.java @@ -49,20 +49,20 @@ import org.apache.druid.query.aggregation.any.LongAnyAggregatorFactory; import org.apache.druid.query.aggregation.any.StringAnyAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstFoldingAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstFoldingAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastFoldingAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniqueFinalizingPostAggregator; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesSerde; import org.apache.druid.query.aggregation.hyperloglog.PreComputedHyperUniquesSerde; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastFoldingAggregatorFactory; import org.apache.druid.query.aggregation.mean.DoubleMeanAggregatorFactory; import org.apache.druid.query.aggregation.mean.DoubleMeanHolder; import org.apache.druid.query.aggregation.post.ArithmeticPostAggregator; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/any/StringAnyAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/any/StringAnyAggregatorFactory.java index f137af7e7fd3..418bb32f64eb 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/any/StringAnyAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/any/StringAnyAggregatorFactory.java @@ -27,7 +27,7 @@ import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.query.aggregation.AggregatorUtil; import org.apache.druid.query.aggregation.BufferAggregator; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.query.dimension.DefaultDimensionSpec; import org.apache.druid.segment.ColumnInspector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/FirstLastUtils.java b/processing/src/main/java/org/apache/druid/query/aggregation/first/FirstLastUtils.java deleted file mode 100644 index b9ef88dfdcf9..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/FirstLastUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.druid.query.aggregation.first; - -import org.apache.druid.segment.BaseObjectColumnValueSelector; -import org.apache.druid.segment.NilColumnValueSelector; -import org.apache.druid.segment.column.ColumnCapabilities; -import org.apache.druid.segment.column.ValueType; - -import javax.annotation.Nullable; - -public class FirstLastUtils -{ - - /** - * Returns whether a given value selector *might* contain object assignable from pairClass (SerializablePairLong*). - */ - public static boolean selectorNeedsFoldCheck( - final BaseObjectColumnValueSelector valueSelector, - @Nullable final ColumnCapabilities valueSelectorCapabilities, - Class pairClass - ) - { - if (valueSelectorCapabilities != null && !valueSelectorCapabilities.is(ValueType.COMPLEX)) { - // Known, non-complex type. - return false; - } - - if (valueSelector instanceof NilColumnValueSelector) { - // Nil column, definitely no SerializablePairLongObject. - return false; - } - - // Check if the selector class could possibly be of pairClass* (either a superclass or subclass). - final Class clazz = valueSelector.classOfObject(); - return clazz.isAssignableFrom(pairClass) - || pairClass.isAssignableFrom(clazz); - } - - /** - * Returns whether an object *might* is assignable to/from the pairClass. - */ - public static boolean objectNeedsFoldCheck(Object obj, Class pairClass) - { - if (obj == null) { - return false; - } - final Class clazz = obj.getClass(); - return clazz.isAssignableFrom(pairClass) - || pairClass.isAssignableFrom(clazz); - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstVectorAggregator.java deleted file mode 100644 index 6f6bfec014c1..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstVectorAggregator.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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.druid.query.aggregation.first; - -import org.apache.druid.collections.SerializablePair; -import org.apache.druid.common.config.NullHandling; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -/** - * Class for vectorized version of first/earliest aggregator over numeric types - */ -public abstract class NumericFirstVectorAggregator implements VectorAggregator -{ - static final int NULL_OFFSET = Long.BYTES; - static final int VALUE_OFFSET = NULL_OFFSET + Byte.BYTES; - final VectorObjectSelector objectSelector; - final VectorValueSelector valueSelector; - private final boolean useDefault = NullHandling.replaceWithDefault(); - private final VectorValueSelector timeSelector; - private long firstTime; - - NumericFirstVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector, VectorObjectSelector objectSelector) - { - this.timeSelector = timeSelector; - this.objectSelector = objectSelector; - this.valueSelector = valueSelector; - firstTime = Long.MAX_VALUE; - } - - @Override - public void init(ByteBuffer buf, int position) - { - buf.putLong(position, Long.MAX_VALUE); - buf.put(position + NULL_OFFSET, useDefault ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE); - initValue(buf, position + VALUE_OFFSET); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - - Object[] objectsWhichMightBeNumeric = null; - boolean[] nullValueVector = null; - - if (objectSelector != null) { - objectsWhichMightBeNumeric = objectSelector.getObjectVector(); - } else if (valueSelector != null) { - nullValueVector = valueSelector.getNullVector(); - } - - firstTime = buf.getLong(position); - - // the time vector is already sorted - // if earliest is on the default time dimension - // but if earliest uses earliest_by it might use a secondary timestamp - // which is not sorted. For correctness, we need to go over all elements. - // A possible optimization here is to have 2 paths one for earliest where - // we can take advantage of the sorted nature of time - // and the earliest_by where we have to go over all elements. - - int index; - for (int i = startRow; i < endRow; i++) { - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - - if (timeVector[i] >= firstTime) { - continue; - } - index = i; - - if (objectsWhichMightBeNumeric != null) { - final SerializablePair inPair = (SerializablePair) objectsWhichMightBeNumeric[index]; - if (inPair != null && inPair.lhs != null && inPair.lhs < firstTime) { - firstTime = inPair.lhs; - if (useDefault || inPair.rhs != null) { - updateTimeWithValue(buf, position, firstTime, index); - } else { - updateTimeWithNull(buf, position, firstTime); - } - } - } else { - final long earliestTime = timeVector[index]; - - if (earliestTime < firstTime) { - firstTime = earliestTime; - if (useDefault || nullValueVector == null || !nullValueVector[index]) { - updateTimeWithValue(buf, position, earliestTime, index); - } else { - updateTimeWithNull(buf, position, earliestTime); - } - } - } - } - } - - /** - * - * Checks if the aggregated value at a position in the buffer is null or not - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @return - */ - boolean isValueNull(ByteBuffer buf, int position) - { - return buf.get(position + NULL_OFFSET) == NullHandling.IS_NULL_BYTE; - } - - @Override - public void aggregate( - ByteBuffer buf, - int numRows, - int[] positions, - @Nullable int[] rows, - int positionOffset - ) - { - final long[] timeVector = timeSelector.getLongVector(); - - Object[] objectsWhichMightBeNumeric = null; - boolean[] nulls = null; - if (objectSelector != null) { - objectsWhichMightBeNumeric = objectSelector.getObjectVector(); - } else if (valueSelector != null) { - nulls = useDefault ? null : valueSelector.getNullVector(); - } - - for (int i = 0; i < numRows; i++) { - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - firstTime = buf.getLong(position); - - if (objectsWhichMightBeNumeric != null) { - final SerializablePair inPair = (SerializablePair) objectsWhichMightBeNumeric[row]; - if (useDefault || inPair != null) { - if (inPair.lhs != null && inPair.lhs < firstTime) { - if (inPair.rhs != null) { - updateTimeWithValue(buf, position, inPair.lhs, row); - } else { - updateTimeWithNull(buf, position, inPair.lhs); - } - } - } - } else { - if (timeVector[row] < firstTime) { - if (useDefault || nulls == null || !nulls[row]) { - updateTimeWithValue(buf, position, timeVector[row], row); - } else { - updateTimeWithNull(buf, position, timeVector[row]); - } - } - } - } - } - - /** - * Updates the time and the non null values to the appropriate position in buffer - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @param time the time to be updated in the buffer as the first time - * @param index he index of the vectorized vector which is the first value - */ - void updateTimeWithValue(ByteBuffer buf, int position, long time, int index) - { - buf.putLong(position, time); - buf.put(position + NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - putValue(buf, position + VALUE_OFFSET, index); - } - - /** - * Updates the time only to the appropriate position in buffer as the value is null - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @param time the time to be updated in the buffer as the last time - */ - void updateTimeWithNull(ByteBuffer buf, int position, long time) - { - buf.putLong(position, time); - buf.put(position + NULL_OFFSET, NullHandling.IS_NULL_BYTE); - } - - /** - *Abstract function which needs to be overridden by subclasses to set the initial value - */ - abstract void initValue(ByteBuffer buf, int position); - - /** - * Abstract function which needs to be overridden by subclasses to set the - * latest value in the buffer depending on the datatype - */ - abstract void putValue(ByteBuffer buf, int position, int index); - - @Override - public void close() - { - // no resources to cleanup - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/SingleStringFirstDimensionVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/first/SingleStringFirstDimensionVectorAggregator.java deleted file mode 100644 index 119e13464a09..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/SingleStringFirstDimensionVectorAggregator.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.druid.query.aggregation.first; - -import org.apache.druid.common.config.NullHandling; -import org.apache.druid.java.util.common.StringUtils; -import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class SingleStringFirstDimensionVectorAggregator implements VectorAggregator -{ - private final VectorValueSelector timeSelector; - private final SingleValueDimensionVectorSelector valueDimensionVectorSelector; - private long firstTime; - private final int maxStringBytes; - private final boolean useDefault = NullHandling.replaceWithDefault(); - - public SingleStringFirstDimensionVectorAggregator( - VectorValueSelector timeSelector, - SingleValueDimensionVectorSelector valueDimensionVectorSelector, - int maxStringBytes - ) - { - this.timeSelector = timeSelector; - this.valueDimensionVectorSelector = valueDimensionVectorSelector; - this.maxStringBytes = maxStringBytes; - this.firstTime = Long.MAX_VALUE; - } - - @Override - public void init(ByteBuffer buf, int position) - { - buf.putLong(position, Long.MAX_VALUE); - buf.put( - position + NumericFirstVectorAggregator.NULL_OFFSET, - useDefault ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE - ); - buf.putInt(position + NumericFirstVectorAggregator.VALUE_OFFSET, 0); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final int[] valueVector = valueDimensionVectorSelector.getRowVector(); - firstTime = buf.getLong(position); - int index; - - long earliestTime; - for (index = startRow; index < endRow; index++) { - if (nullTimeVector != null && nullTimeVector[index]) { - continue; - } - earliestTime = timeVector[index]; - if (earliestTime < firstTime) { - firstTime = earliestTime; - buf.putLong(position, firstTime); - buf.put(position + NumericFirstVectorAggregator.NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - buf.putInt(position + NumericFirstVectorAggregator.VALUE_OFFSET, valueVector[index]); - } - } - } - - @Override - public void aggregate(ByteBuffer buf, int numRows, int[] positions, @Nullable int[] rows, int positionOffset) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final int[] values = valueDimensionVectorSelector.getRowVector(); - for (int i = 0; i < numRows; i++) { - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - long firstTime = buf.getLong(position); - if (timeVector[row] < firstTime) { - firstTime = timeVector[row]; - buf.putLong(position, firstTime); - buf.put(position + NumericFirstVectorAggregator.NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - buf.putInt(position + NumericFirstVectorAggregator.VALUE_OFFSET, values[row]); - } - } - - } - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - int index = buf.getInt(position + NumericFirstVectorAggregator.VALUE_OFFSET); - long earliest = buf.getLong(position); - String strValue = valueDimensionVectorSelector.lookupName(index); - return new SerializablePairLongString(earliest, StringUtils.chop(strValue, maxStringBytes)); - } - - @Override - public void close() - { - // nothing to close - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregator.java deleted file mode 100644 index fd2260b8d665..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregator.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * 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.druid.query.aggregation.first; - -import org.apache.druid.java.util.common.DateTimes; -import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.segment.DimensionHandlerUtils; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class StringFirstVectorAggregator implements VectorAggregator -{ - private static final SerializablePairLongString INIT = new SerializablePairLongString( - DateTimes.MAX.getMillis(), - null - ); - private final VectorValueSelector timeSelector; - private final VectorObjectSelector valueSelector; - private final int maxStringBytes; - - - public StringFirstVectorAggregator( - VectorValueSelector timeSelector, - VectorObjectSelector valueSelector, - int maxStringBytes - ) - { - this.timeSelector = timeSelector; - this.valueSelector = valueSelector; - this.maxStringBytes = maxStringBytes; - } - - @Override - public void init(ByteBuffer buf, int position) - { - StringFirstLastUtils.writePair(buf, position, INIT, maxStringBytes); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - if (timeSelector == null) { - return; - } - final long[] times = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final Object[] objectsWhichMightBeStrings = valueSelector.getObjectVector(); - long firstTime = buf.getLong(position); - int index; - for (int i = startRow; i < endRow; i++) { - if (times[i] > firstTime) { - continue; - } - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - index = i; - final boolean foldNeeded = FirstLastUtils.objectNeedsFoldCheck(objectsWhichMightBeStrings[index], SerializablePairLongString.class); - if (foldNeeded) { - final SerializablePairLongString inPair = StringFirstLastUtils.readPairFromVectorSelectorsAtIndex( - timeSelector, - valueSelector, - index - ); - if (inPair != null) { - firstTime = buf.getLong(position); - if (inPair.lhs < firstTime) { - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(inPair.lhs, inPair.rhs), - maxStringBytes - ); - } - } - } else { - final long time = times[index]; - if (time < firstTime) { - final String value = DimensionHandlerUtils.convertObjectToString(objectsWhichMightBeStrings[index]); - firstTime = time; - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(time, value), - maxStringBytes - ); - } - } - } - - } - - @Override - public void aggregate(ByteBuffer buf, int numRows, int[] positions, @Nullable int[] rows, int positionOffset) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final Object[] objectsWhichMightBeStrings = valueSelector.getObjectVector(); - - // iterate once over the object vector to find first non null element and - // determine if the type is Pair or not - boolean foldNeeded = false; - for (Object obj : objectsWhichMightBeStrings) { - if (obj == null) { - continue; - } else { - foldNeeded = FirstLastUtils.objectNeedsFoldCheck(obj, SerializablePairLongString.class); - break; - } - } - - for (int i = 0; i < numRows; i++) { - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - long firstTime = buf.getLong(position); - if (timeVector[row] < firstTime) { - if (foldNeeded) { - final SerializablePairLongString inPair = StringFirstLastUtils.readPairFromVectorSelectorsAtIndex( - timeSelector, - valueSelector, - row - ); - if (inPair != null) { - if (inPair.lhs < firstTime) { - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(inPair.lhs, inPair.rhs), - maxStringBytes - ); - } - } - } else { - final String value = DimensionHandlerUtils.convertObjectToString(objectsWhichMightBeStrings[row]); - firstTime = timeVector[row]; - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(firstTime, value), - maxStringBytes - ); - } - } - } - - } - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - return StringFirstLastUtils.readPair(buf, position); - } - - @Override - public void close() - { - // nothing to close - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/DoubleFirstLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/DoubleFirstLastVectorAggregator.java new file mode 100644 index 000000000000..728018691550 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/DoubleFirstLastVectorAggregator.java @@ -0,0 +1,123 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.query.aggregation.SerializablePairLongDouble; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +/** + * Vectorized version of on heap aggregator for column selectors with type DOUBLE. + */ +public class DoubleFirstLastVectorAggregator extends FirstLastVectorAggregator +{ + private final SelectionPredicate selectionPredicate; + + protected DoubleFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorObjectSelector objectSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, null, objectSelector, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + protected DoubleFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorValueSelector valueSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, valueSelector, null, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + @Override + public void init(ByteBuffer buf, int position) + { + buf.putLong(position, selectionPredicate.initValue()); + buf.put( + position + NULLITY_OFFSET, + NullHandling.replaceWithDefault() ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE + ); + buf.putDouble(position + VALUE_OFFSET, 0.0D); + } + + @Nullable + @Override + public Object get(ByteBuffer buf, int position) + { + long time = buf.getLong(position); + if (buf.get(position + NULLITY_OFFSET) == NullHandling.IS_NULL_BYTE) { + return new SerializablePairLongDouble(time, null); + } + return new SerializablePairLongDouble(time, buf.getDouble(position + VALUE_OFFSET)); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, Double value) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putDouble(position + VALUE_OFFSET, value); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putDouble(position + VALUE_OFFSET, valueSelector.getDoubleVector()[index]); + } + + @Override + protected void putNull(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NULL_BYTE); + buf.putDouble(position + VALUE_OFFSET, 0.0D); + + } + + @Override + protected void putDefaultValue(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putDouble(position, 0.0D); + } + + @Override + protected SerializablePairLongDouble readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ) + { + return FirstLastUtils.readDoublePairFromVectorSelectors(timeNullityVector, timeVector, maybeFoldedObjects, index); + } +} + diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastUtils.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastUtils.java new file mode 100644 index 000000000000..1dce1472126d --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastUtils.java @@ -0,0 +1,155 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.query.aggregation.SerializablePairLongDouble; +import org.apache.druid.query.aggregation.SerializablePairLongFloat; +import org.apache.druid.query.aggregation.SerializablePairLongLong; +import org.apache.druid.segment.BaseObjectColumnValueSelector; +import org.apache.druid.segment.DimensionHandlerUtils; +import org.apache.druid.segment.NilColumnValueSelector; +import org.apache.druid.segment.column.ColumnCapabilities; +import org.apache.druid.segment.column.ValueType; + +import javax.annotation.Nullable; + +public class FirstLastUtils +{ + + /** + * Returns whether a given value selector *might* contain object assignable from pairClass (SerializablePairLong*). + */ + public static boolean selectorNeedsFoldCheck( + final BaseObjectColumnValueSelector valueSelector, + @Nullable final ColumnCapabilities valueSelectorCapabilities, + Class pairClass + ) + { + if (valueSelectorCapabilities != null && !valueSelectorCapabilities.is(ValueType.COMPLEX)) { + // Known, non-complex type. + return false; + } + + if (valueSelector instanceof NilColumnValueSelector) { + // Nil column, definitely no SerializablePairLongObject. + return false; + } + + // Check if the selector class could possibly be of pairClass* (either a superclass or subclass). + final Class clazz = valueSelector.classOfObject(); + return clazz.isAssignableFrom(pairClass) + || pairClass.isAssignableFrom(clazz); + } + + @Nullable + public static SerializablePairLongDouble readDoublePairFromVectorSelectors( + @Nullable boolean[] timeNullityVector, + long[] timeVector, + Object[] objectVector, + int index + ) + { + final long time; + final Double value; + + final Object object = objectVector[index]; + + if (object instanceof SerializablePairLongDouble) { + // We got a folded object, ignore timeSelector completely, the object has all the info it requires + final SerializablePairLongDouble pair = (SerializablePairLongDouble) object; + // if time == null, don't aggregate + if (pair.lhs == null) { + return null; + } + return pair; + } else { + if (timeNullityVector != null && timeNullityVector[index]) { + // Donot aggregate pairs where time is unknown + return null; + } + time = timeVector[index]; + value = DimensionHandlerUtils.convertObjectToDouble(object); + } + return new SerializablePairLongDouble(time, value); + } + + @Nullable + public static SerializablePairLongFloat readFloatPairFromVectorSelectors( + @Nullable boolean[] timeNullityVector, + long[] timeVector, + Object[] objectVector, + int index + ) + { + final long time; + final Float value; + + final Object object = objectVector[index]; + + if (object instanceof SerializablePairLongFloat) { + // We got a folded object, ignore timeSelector completely, the object has all the info it requires + final SerializablePairLongFloat pair = (SerializablePairLongFloat) object; + // if time == null, don't aggregate + if (pair.lhs == null) { + return null; + } + return pair; + } else { + if (timeNullityVector != null && timeNullityVector[index]) { + // Donot aggregate pairs where time is unknown + return null; + } + time = timeVector[index]; + value = DimensionHandlerUtils.convertObjectToFloat(object); + } + return new SerializablePairLongFloat(time, value); + } + @Nullable + public static SerializablePairLongLong readLongPairFromVectorSelectors( + @Nullable boolean[] timeNullityVector, + long[] timeVector, + Object[] objectVector, + int index + ) + { + final long time; + final Long value; + + final Object object = objectVector[index]; + + if (object instanceof SerializablePairLongLong) { + // We got a folded object, ignore timeSelector completely, the object has all the info it requires + final SerializablePairLongLong pair = (SerializablePairLongLong) object; + // if time == null, don't aggregate + if (pair.lhs == null) { + return null; + } + return pair; + } else { + if (timeNullityVector != null && timeNullityVector[index]) { + // Donot aggregate pairs where time is unknown + return null; + } + time = timeVector[index]; + value = DimensionHandlerUtils.convertObjectToLong(object); + } + return new SerializablePairLongLong(time, value); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastVectorAggregator.java new file mode 100644 index 000000000000..129465a6d591 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FirstLastVectorAggregator.java @@ -0,0 +1,266 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import com.google.common.base.Preconditions; +import org.apache.druid.collections.SerializablePair; +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +/** + * Base type for vectorized version of on heap 'last' aggregator for primitive numeric column selectors.. + */ +public abstract class FirstLastVectorAggregator> + implements VectorAggregator +{ + public static final int NULLITY_OFFSET = Long.BYTES; + public static final int VALUE_OFFSET = NULLITY_OFFSET + Byte.BYTES; + + @Nullable + private final VectorValueSelector timeSelector; + @Nullable + private final VectorValueSelector valueSelector; + @Nullable + private final VectorObjectSelector objectSelector; + private final SelectionPredicate selectionPredicate; + private final boolean useDefault = NullHandling.replaceWithDefault(); + + + /** + * timeSelector can be null, however aggregate functions are no-op then. + */ + public FirstLastVectorAggregator( + @Nullable VectorValueSelector timeSelector, + @Nullable VectorValueSelector valueSelector, + @Nullable VectorObjectSelector objectSelector, + SelectionPredicate selectionPredicate + ) + { + if (timeSelector != null) { + Preconditions.checkArgument( + (valueSelector != null && objectSelector == null) || (valueSelector == null && objectSelector != null), + "exactly one of 'valueSelector' and 'objectSelector' must be provided" + ); + } + this.timeSelector = timeSelector; + this.valueSelector = valueSelector; + this.objectSelector = objectSelector; + this.selectionPredicate = selectionPredicate; + } + + @Override + public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) + { + // Not a normal case, and this doesn't affect the folding. timeSelectors should be present (albeit irrelevent) when folding. + // timeSelector == null means that the aggregating column's capabilities aren't known, and it only happens for a special case + // while building string aggregator + if (timeSelector == null) { + return; + } + + // If objectSelector isn't null, then the objects might be folded up. If that's the case, whatever's represented by + // the timeSelector doesn't hold any relevance. + if (objectSelector != null) { + final Object[] maybeFoldedObjects = objectSelector.getObjectVector(); + final boolean[] timeNullityVector = timeSelector.getNullVector(); + final long[] timeVector = timeSelector.getLongVector(); + + PairType selectedPair = null; + + for (int index = startRow; index < endRow; ++index) { + + PairType pair = readPairFromVectorSelectors(timeNullityVector, timeVector, maybeFoldedObjects, index); + if (pair != null) { + if (selectedPair == null) { + selectedPair = pair; + } else if (selectionPredicate.apply(pair.lhs, selectedPair.lhs)) { + selectedPair = pair; + } + } + } + // Something's been selected of the row vector + if (selectedPair != null) { + // Compare the latest value of the folded up row vector to the latest value in the buffer + if (selectionPredicate.apply(selectedPair.lhs, buf.getLong(position))) { + if (selectedPair.rhs != null) { + putValue(buf, position, selectedPair.lhs, selectedPair.rhs); + } else if (useDefault) { + putDefaultValue(buf, position, selectedPair.lhs); + } else { + putNull(buf, position, selectedPair.lhs); + } + } + } + + } else { + // No object selector, no folding present. Check the timeSelector before checking the valueSelector + final boolean[] timeNullityVector = timeSelector.getNullVector(); + final long[] timeVector = timeSelector.getLongVector(); + final boolean[] valueNullityVector = valueSelector.getNullVector(); + Integer selectedIndex = null; + + for (int index = startRow; index < endRow; ++index) { + if (timeNullityVector != null && timeNullityVector[index]) { + // Don't aggregate values where time isn't present + continue; + } + // Find the latest time inside the vector objects + if (selectedIndex == null) { + selectedIndex = index; + } else { + if (selectionPredicate.apply(timeVector[index], timeVector[selectedIndex])) { + selectedIndex = index; + } + } + } + // Compare the selectedIndex's value to the value on the buffer. This way, we write to the buffer only once + // Weeds out empty vectors, where endRow == startRow + if (selectedIndex != null) { + if (selectionPredicate.apply(timeVector[selectedIndex], buf.getLong(position))) { + // Write the value here + if (valueNullityVector == null || !valueNullityVector[selectedIndex]) { + putValue(buf, position, timeVector[selectedIndex], valueSelector, selectedIndex); + } else if (useDefault) { + putDefaultValue(buf, position, timeVector[selectedIndex]); + } else { + putNull(buf, position, timeVector[selectedIndex]); + } + } + } + } + } + + @Override + public void aggregate( + ByteBuffer buf, + int numRows, + int[] positions, + @Nullable int[] rows, + int positionOffset + ) + { + // Not a normal case, and this doesn't affect the folding. timeSelectors should be present (albeit irrelevent) when folding. + // timeSelector == null means that the aggregating column's capabilities aren't known, and it only happens for a special case + // while building string aggregator + if (timeSelector == null) { + return; + } + + // If objectSelector isn't null, then the objects might be folded up. If that's the case, whatever's represented by + // the timeSelector doesn't hold any relevance. We should check for folded objects BEFORE even thinking about looking + // at the timeSelector + if (objectSelector != null) { + final Object[] maybeFoldedObjects = objectSelector.getObjectVector(); + final boolean[] timeNullityVector = timeSelector.getNullVector(); + final long[] timeVector = timeSelector.getLongVector(); + for (int i = 0; i < numRows; ++i) { + int position = positions[i] + positionOffset; + int row = rows == null ? i : rows[i]; + // All the information about the object would be in the single selector. This method will check the folding of the object selector, + // casting, and everything........ + PairType pair = readPairFromVectorSelectors(timeNullityVector, timeVector, maybeFoldedObjects, row); + if (pair != null) { + long lastTime = buf.getLong(position); + if (selectionPredicate.apply(pair.lhs, lastTime)) { + if (pair.rhs != null) { + putValue(buf, position, pair.lhs, pair.rhs); + } else if (useDefault) { + putDefaultValue(buf, position, pair.lhs); + } else { + putNull(buf, position, pair.lhs); + } + } + } + } + } else { + // No object selector, no folding present. Check the timeSelector before checking the valueSelector + final boolean[] timeNullityVector = timeSelector.getNullVector(); + final long[] timeVector = timeSelector.getLongVector(); + final boolean[] valueNullityVector = valueSelector.getNullVector(); + + for (int i = 0; i < numRows; ++i) { + int position = positions[i] + positionOffset; + int row = rows == null ? i : rows[i]; + long lastTime = buf.getLong(position); + if (timeNullityVector != null && timeNullityVector[row]) { + // Don't aggregate values where time isn't present + continue; + } + if (selectionPredicate.apply(timeVector[row], lastTime)) { + if (valueNullityVector == null || !valueNullityVector[row]) { + putValue(buf, position, timeVector[row], valueSelector, row); + } else if (useDefault) { + putDefaultValue(buf, position, timeVector[row]); + } else { + putNull(buf, position, timeVector[row]); + } + } + } + } + } + + /** + * Sets the value at the position. Subclasses can assume that the value isn't null + * + * 'position' refers to the location where the value of the pair will get updated (as opposed to the beginning of + * the serialized pair) + * + * It is only used if objectSelector is supplied + */ + protected abstract void putValue(ByteBuffer buf, int position, long time, RhsType value); + + /** + * Sets the value represented by the valueSelector at the given index. A slightly redundant method to {@link #putValue(ByteBuffer, int, long, Object)} + * to avoid autoboxing for the numeric types. Subclasses can assume that valueSelector.getNullVector[index] is false (i.e. + * the value represented at the index isn't null) + * + * It is used if valueSelector is supplied + */ + protected abstract void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index); + + /** + * Sets the default value for the type in the byte buffer at the given position. It is only used when replaceNullWithDefault = true, + * therefore the callers don't need to handle any other case. + * + * 'position' refers to the location where the value of the pair will get updated (as opposed to the beginning of + * the serialized pair) + */ + protected abstract void putDefaultValue(ByteBuffer buf, int position, long time); + + protected abstract void putNull(ByteBuffer buf, int position, long time); + + protected abstract PairType readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ); + + @Override + public void close() + { + // no resources to cleanup + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FloatFirstLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FloatFirstLastVectorAggregator.java new file mode 100644 index 000000000000..2edebc307823 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/FloatFirstLastVectorAggregator.java @@ -0,0 +1,122 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.query.aggregation.SerializablePairLongFloat; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +/** + * Vectorized version of on heap 'last' aggregator for column selectors with type FLOAT. + */ +public class FloatFirstLastVectorAggregator extends FirstLastVectorAggregator +{ + private final SelectionPredicate selectionPredicate; + + protected FloatFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorObjectSelector objectSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, null, objectSelector, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + protected FloatFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorValueSelector valueSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, valueSelector, null, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + @Override + public void init(ByteBuffer buf, int position) + { + buf.putLong(position, selectionPredicate.initValue()); + buf.put( + position + NULLITY_OFFSET, + NullHandling.replaceWithDefault() ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE + ); + buf.putFloat(position + VALUE_OFFSET, 0.0F); + } + + @Nullable + @Override + public Object get(ByteBuffer buf, int position) + { + long time = buf.getLong(position); + if (buf.get(position + NULLITY_OFFSET) == NullHandling.IS_NULL_BYTE) { + return new SerializablePairLongFloat(time, null); + } + return new SerializablePairLongFloat(time, buf.getFloat(position + VALUE_OFFSET)); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, Float value) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putFloat(position + VALUE_OFFSET, value); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putFloat(position + VALUE_OFFSET, valueSelector.getFloatVector()[index]); + } + + @Override + protected void putNull(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NULL_BYTE); + buf.putFloat(position + VALUE_OFFSET, 0.0F); + } + + @Override + protected void putDefaultValue(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putFloat(position + VALUE_OFFSET, 0.0F); + } + + @Override + protected SerializablePairLongFloat readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ) + { + return FirstLastUtils.readFloatPairFromVectorSelectors(timeNullityVector, timeVector, maybeFoldedObjects, index); + } +} + diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/LongFirstLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/LongFirstLastVectorAggregator.java new file mode 100644 index 000000000000..9b77426dfee3 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/LongFirstLastVectorAggregator.java @@ -0,0 +1,121 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.query.aggregation.SerializablePairLongLong; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +/** + * Vectorized version of on heap 'last' aggregator for column selectors with type LONG.. + */ +public class LongFirstLastVectorAggregator extends FirstLastVectorAggregator +{ + private final SelectionPredicate selectionPredicate; + + protected LongFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorObjectSelector objectSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, null, objectSelector, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + protected LongFirstLastVectorAggregator( + VectorValueSelector timeSelector, + VectorValueSelector valueSelector, + SelectionPredicate selectionPredicate + ) + { + super(timeSelector, valueSelector, null, selectionPredicate); + this.selectionPredicate = selectionPredicate; + } + + @Override + public void init(ByteBuffer buf, int position) + { + buf.putLong(position, selectionPredicate.initValue()); + buf.put( + position + NULLITY_OFFSET, + NullHandling.replaceWithDefault() ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE + ); + buf.putLong(position + VALUE_OFFSET, 0L); + } + + @Nullable + @Override + public Object get(ByteBuffer buf, int position) + { + long time = buf.getLong(position); + if (buf.get(position + NULLITY_OFFSET) == NullHandling.IS_NULL_BYTE) { + return new SerializablePairLongLong(time, null); + } + return new SerializablePairLongLong(time, buf.getLong(position + VALUE_OFFSET)); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, Long value) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putLong(position + VALUE_OFFSET, value); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putLong(position + VALUE_OFFSET, valueSelector.getLongVector()[index]); + } + + @Override + protected void putNull(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NULL_BYTE); + buf.putLong(position + VALUE_OFFSET, 0L); + } + + @Override + protected void putDefaultValue(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putLong(position + VALUE_OFFSET, 0L); + } + + @Override + protected SerializablePairLongLong readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ) + { + return FirstLastUtils.readLongPairFromVectorSelectors(timeNullityVector, timeVector, maybeFoldedObjects, index); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SelectionPredicate.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SelectionPredicate.java new file mode 100644 index 000000000000..fd1ca915b473 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SelectionPredicate.java @@ -0,0 +1,70 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.java.util.common.DateTimes; + +/** + * Differentiating factor between the first and the last aggregator. Specifies the + */ +public interface SelectionPredicate +{ + /** + * @return Time value to initialize the aggregation with + */ + long initValue(); + + /** + * @param currentTime Time of the current row + * @param selectedTime Aggregated time value + * @return true if the current row should be selected over the aggregated value, else false + */ + boolean apply(long currentTime, long selectedTime); + + SelectionPredicate FIRST_PREDICATE = new SelectionPredicate() + { + @Override + public long initValue() + { + return DateTimes.MAX.getMillis(); + } + + @Override + public boolean apply(long currentTime, long selectedTime) + { + return currentTime < selectedTime; + } + }; + + SelectionPredicate LAST_PREDICATE = new SelectionPredicate() + { + @Override + public long initValue() + { + return DateTimes.MIN.getMillis(); + } + + @Override + public boolean apply(long currentTime, long selectedTime) + { + return currentTime >= selectedTime; + } + }; +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SingleStringFirstLastDimensionVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SingleStringFirstLastDimensionVectorAggregator.java new file mode 100644 index 000000000000..031140e4f6c5 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/SingleStringFirstLastDimensionVectorAggregator.java @@ -0,0 +1,185 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.error.DruidException; +import org.apache.druid.java.util.common.StringUtils; +import org.apache.druid.query.aggregation.SerializablePairLongString; +import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +public class SingleStringFirstLastDimensionVectorAggregator + extends FirstLastVectorAggregator +{ + private final SingleValueDimensionVectorSelector singleValueDimensionVectorSelector; + private final int maxStringBytes; + private final SelectionPredicate selectionPredicate; + + protected SingleStringFirstLastDimensionVectorAggregator( + VectorValueSelector timeSelector, + SingleValueDimensionVectorSelector singleValueDimensionVectorSelector, + int maxStringBytes, + SelectionPredicate selectionPredicate + ) + { + super( + timeSelector, + new SingleValueDimensionVectorSelectorAdapter(singleValueDimensionVectorSelector), + null, + selectionPredicate + ); + this.singleValueDimensionVectorSelector = singleValueDimensionVectorSelector; + this.maxStringBytes = maxStringBytes; + this.selectionPredicate = selectionPredicate; + } + + @Override + public void init(ByteBuffer buf, int position) + { + buf.putLong(position, selectionPredicate.initValue()); + buf.put( + position + NULLITY_OFFSET, + NullHandling.replaceWithDefault() ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE + ); + buf.putInt(position + VALUE_OFFSET, 0); + } + + /** + * Doesnt need to handle the null handling because that is taken care of while inserting the value, therefore in + * replaceWithDefault mode, it is always going to be non-null + */ + @Nullable + @Override + public Object get(ByteBuffer buf, int position) + { + long time = buf.getLong(position); + if (buf.get(position + NULLITY_OFFSET) == NullHandling.IS_NULL_BYTE) { + return new SerializablePairLongString(time, null); + } + int index = buf.getInt(position + VALUE_OFFSET); + String value = singleValueDimensionVectorSelector.lookupName(index); + return new SerializablePairLongString(time, StringUtils.chop(value, maxStringBytes)); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, String value) + { + throw DruidException.defensive("This method is not applicable to the SingleStringFirstLastDimensionVectorAggregator"); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putInt( + position + VALUE_OFFSET, + ((SingleValueDimensionVectorSelectorAdapter) valueSelector).singleValueDimensionVectorSelector.getRowVector()[index] + ); + } + + @Override + protected void putDefaultValue(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NOT_NULL_BYTE); + buf.putInt(position + VALUE_OFFSET, 0); + } + + @Override + protected void putNull(ByteBuffer buf, int position, long time) + { + buf.putLong(position, time); + buf.put(position + NULLITY_OFFSET, NullHandling.IS_NULL_BYTE); + buf.putInt(position + VALUE_OFFSET, 0); + } + + @Override + protected SerializablePairLongString readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ) + { + throw DruidException.defensive("This method is not applicable to the SingleStringFirstLastDimensionVectorAggregator"); + } + + /** + * Adapter class to from {@link SingleValueDimensionVectorSelector} to {@link VectorValueSelector}, to pass to the parent + * class. The parent class only uses the passed in selector for the null check, therefore {@link #getNullVector()} is + * the only relevant method implemented by the adapter. Each string value (even null) is assigned an id that will get stored, + * therefore fetching the nullVector returns null (i.e. no null values) + */ + private static class SingleValueDimensionVectorSelectorAdapter implements VectorValueSelector + { + + private final SingleValueDimensionVectorSelector singleValueDimensionVectorSelector; + + public SingleValueDimensionVectorSelectorAdapter(SingleValueDimensionVectorSelector singleValueDimensionVectorSelector) + { + this.singleValueDimensionVectorSelector = singleValueDimensionVectorSelector; + } + + @Override + public int getMaxVectorSize() + { + throw DruidException.defensive("Unexpected call"); + } + + @Override + public int getCurrentVectorSize() + { + throw DruidException.defensive("Unexpected call"); + } + + @Override + public long[] getLongVector() + { + throw DruidException.defensive("Unexpected call"); + } + + @Override + public float[] getFloatVector() + { + throw DruidException.defensive("Unexpected call"); + } + + @Override + public double[] getDoubleVector() + { + throw DruidException.defensive("Unexpected call"); + } + + /** + * This is the only useful method, that will get used by the parent class. + */ + @Nullable + @Override + public boolean[] getNullVector() + { + return null; + } + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstLastUtils.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastUtils.java similarity index 90% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstLastUtils.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastUtils.java index ff1113c91132..afbb94faf8f3 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstLastUtils.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastUtils.java @@ -17,15 +17,13 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast; import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.query.aggregation.SerializablePairLongString; import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseObjectColumnValueSelector; import org.apache.druid.segment.DimensionHandlerUtils; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; import javax.annotation.Nullable; import java.nio.ByteBuffer; @@ -38,25 +36,29 @@ public class StringFirstLastUtils * Return the object at a particular index from the vector selectors. * index of bounds issues is the responsibility of the caller */ + @Nullable public static SerializablePairLongString readPairFromVectorSelectorsAtIndex( - VectorValueSelector timeSelector, - VectorObjectSelector valueSelector, + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, int index ) { final long time; final String string; - final Object object = valueSelector.getObjectVector()[index]; + final Object object = maybeFoldedObjects[index]; + if (object instanceof SerializablePairLongString) { final SerializablePairLongString pair = (SerializablePairLongString) object; time = pair.lhs; string = pair.rhs; - } else if (object != null) { - time = timeSelector.getLongVector()[index]; - string = DimensionHandlerUtils.convertObjectToString(object); } else { - // Don't aggregate nulls. - return null; + if (timeNullityVector != null && timeNullityVector[index]) { + // Donot aggregate pairs where time is unknown + return null; + } + time = timeVector[index]; + string = DimensionHandlerUtils.convertObjectToString(object); } return new SerializablePairLongString(time, string); diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastVectorAggregator.java new file mode 100644 index 000000000000..118d28e0c366 --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/StringFirstLastVectorAggregator.java @@ -0,0 +1,110 @@ +/* + * 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.druid.query.aggregation.firstlast; + +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.error.DruidException; +import org.apache.druid.query.aggregation.SerializablePairLongString; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; +import java.nio.ByteBuffer; + +public class StringFirstLastVectorAggregator extends FirstLastVectorAggregator +{ + private final int maxStringBytes; + private final SelectionPredicate selectionPredicate; + + protected StringFirstLastVectorAggregator( + @Nullable final VectorValueSelector timeSelector, + final VectorObjectSelector objectSelector, + final int maxStringBytes, + final SelectionPredicate selectionPredicate + ) + { + super(timeSelector, null, objectSelector, selectionPredicate); + this.maxStringBytes = maxStringBytes; + this.selectionPredicate = selectionPredicate; + } + + @Override + public void init(ByteBuffer buf, int position) + { + StringFirstLastUtils.writePair( + buf, + position, + new SerializablePairLongString(selectionPredicate.initValue(), null), + maxStringBytes + ); + } + + @Nullable + @Override + public Object get(ByteBuffer buf, int position) + { + return StringFirstLastUtils.readPair(buf, position); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, String value) + { + StringFirstLastUtils.writePair(buf, position, new SerializablePairLongString(time, value), maxStringBytes); + } + + @Override + protected void putValue(ByteBuffer buf, int position, long time, VectorValueSelector valueSelector, int index) + { + throw DruidException.defensive("This variant is not applicable to the StringFirstLastVectorAggregator"); + } + + @Override + protected void putDefaultValue(ByteBuffer buf, int position, long time) + { + StringFirstLastUtils.writePair( + buf, + position, + new SerializablePairLongString(time, NullHandling.defaultStringValue()), + maxStringBytes + ); + } + + @Override + protected void putNull(ByteBuffer buf, int position, long time) + { + StringFirstLastUtils.writePair(buf, position, new SerializablePairLongString(time, null), maxStringBytes); + } + + @Override + protected SerializablePairLongString readPairFromVectorSelectors( + boolean[] timeNullityVector, + long[] timeVector, + Object[] maybeFoldedObjects, + int index + ) + { + return StringFirstLastUtils.readPairFromVectorSelectorsAtIndex( + timeNullityVector, + timeVector, + maybeFoldedObjects, + index + ); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregator.java index cf121f72fc98..3861b580c170 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregatorFactory.java similarity index 98% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregatorFactory.java index 92880be84573..f0157512167a 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,6 +32,7 @@ import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.query.aggregation.SerializablePairLongDoubleComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstBufferAggregator.java index c00472e923c9..2a2fc229145b 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregator.java similarity index 50% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregator.java index 0fdd06231feb..11cfa3b5366e 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregator.java @@ -17,51 +17,23 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; -import org.apache.druid.query.aggregation.SerializablePairLongDouble; +import org.apache.druid.query.aggregation.firstlast.DoubleFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; import org.apache.druid.segment.vector.VectorObjectSelector; import org.apache.druid.segment.vector.VectorValueSelector; -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class DoubleFirstVectorAggregator extends NumericFirstVectorAggregator +public class DoubleFirstVectorAggregator extends DoubleFirstLastVectorAggregator { public DoubleFirstVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) { - super(timeSelector, null, objectSelector); + super(timeSelector, objectSelector, SelectionPredicate.FIRST_PREDICATE); } public DoubleFirstVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) { - super(timeSelector, valueSelector, null); - } - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putDouble(position, 0); - } - - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - double firstValue = valueSelector != null ? valueSelector.getDoubleVector()[index] : ((SerializablePairLongDouble) (objectSelector.getObjectVector()[index])).getRhs(); - buf.putDouble(position, firstValue); - } - - - /** - * @return The object as a pair with the position and the value stored at the position in the buffer. - */ - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongDouble(buf.getLong(position), rhsNull ? null : buf.getDouble(position + VALUE_OFFSET)); + super(timeSelector, valueSelector, SelectionPredicate.FIRST_PREDICATE); } } diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregator.java index 987937c2ba87..b1340b5dfc54 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregatorFactory.java similarity index 98% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregatorFactory.java index 5faf04607df7..d35782533748 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,6 +32,7 @@ import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.query.aggregation.SerializablePairLongFloatComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstBufferAggregator.java index b8881ee9500f..9b04b0d1a51f 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregator.java similarity index 51% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregator.java index 82a679095946..9d4b5bc71932 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregator.java @@ -17,50 +17,23 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; -import org.apache.druid.query.aggregation.SerializablePairLongFloat; +import org.apache.druid.query.aggregation.firstlast.FloatFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; import org.apache.druid.segment.vector.VectorObjectSelector; import org.apache.druid.segment.vector.VectorValueSelector; -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class FloatFirstVectorAggregator extends NumericFirstVectorAggregator +public class FloatFirstVectorAggregator extends FloatFirstLastVectorAggregator { public FloatFirstVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) { - super(timeSelector, null, objectSelector); + super(timeSelector, objectSelector, SelectionPredicate.FIRST_PREDICATE); } public FloatFirstVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) { - super(timeSelector, valueSelector, null); - } - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putFloat(position, 0); - } - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - float firstValue = valueSelector != null ? valueSelector.getFloatVector()[index] : ((SerializablePairLongFloat) objectSelector.getObjectVector()[index]).getRhs(); - buf.putFloat(position, firstValue); - } - - - /** - * @return The object as a pair with the position and the value stored at the position in the buffer. - */ - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongFloat(buf.getLong(position), rhsNull ? null : buf.getFloat(position + VALUE_OFFSET)); + super(timeSelector, valueSelector, SelectionPredicate.FIRST_PREDICATE); } } diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/GenericFirstAggregateCombiner.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/GenericFirstAggregateCombiner.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/GenericFirstAggregateCombiner.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/GenericFirstAggregateCombiner.java index cd72c306b798..f6a39aafc3ba 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/GenericFirstAggregateCombiner.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/GenericFirstAggregateCombiner.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.google.common.primitives.Longs; import org.apache.druid.collections.SerializablePair; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregator.java index d229819382e9..ad56e379563c 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregatorFactory.java similarity index 98% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregatorFactory.java index 6b8836050ef5..791ca1a02d30 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,6 +32,7 @@ import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.SerializablePairLongLongComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstBufferAggregator.java index 426d4c64816d..694d5903d1de 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregator.java similarity index 51% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregator.java index 8c7631db3c12..135946f61557 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregator.java @@ -17,48 +17,22 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; -import org.apache.druid.query.aggregation.SerializablePairLongLong; +import org.apache.druid.query.aggregation.firstlast.LongFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; import org.apache.druid.segment.vector.VectorObjectSelector; import org.apache.druid.segment.vector.VectorValueSelector; -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class LongFirstVectorAggregator extends NumericFirstVectorAggregator +public class LongFirstVectorAggregator extends LongFirstLastVectorAggregator { public LongFirstVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) { - super(timeSelector, null, objectSelector); + super(timeSelector, objectSelector, SelectionPredicate.FIRST_PREDICATE); } public LongFirstVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) { - super(timeSelector, valueSelector, null); - } - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putLong(position, 0); - } - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - long firstValue = valueSelector != null ? valueSelector.getLongVector()[index] : ((SerializablePairLongLong) objectSelector.getObjectVector()[index]).getRhs(); - buf.putLong(position, firstValue); - } - - /** - * @return The object as a pair with the position and the value stored at the position in the buffer. - */ - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongLong(buf.getLong(position), rhsNull ? null : buf.getLong(position + VALUE_OFFSET)); + super(timeSelector, valueSelector, SelectionPredicate.FIRST_PREDICATE); } } diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstAggregator.java similarity index 98% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstAggregator.java index 6b32996b4f2f..bc5f939c8b1c 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.collections.SerializablePair; import org.apache.druid.common.config.NullHandling; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstBufferAggregator.java similarity index 98% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstBufferAggregator.java index f20456d31223..e85e470fb613 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/NumericFirstBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/NumericFirstBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.collections.SerializablePair; import org.apache.druid.common.config.NullHandling; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/SingleStringFirstDimensionVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/SingleStringFirstDimensionVectorAggregator.java new file mode 100644 index 000000000000..e098aaddd95d --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/SingleStringFirstDimensionVectorAggregator.java @@ -0,0 +1,38 @@ +/* + * 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.druid.query.aggregation.firstlast.first; + +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; +import org.apache.druid.query.aggregation.firstlast.SingleStringFirstLastDimensionVectorAggregator; +import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +public class SingleStringFirstDimensionVectorAggregator extends SingleStringFirstLastDimensionVectorAggregator +{ + + public SingleStringFirstDimensionVectorAggregator( + VectorValueSelector timeSelector, + SingleValueDimensionVectorSelector singleValueDimensionVectorSelector, + int maxStringBytes + ) + { + super(timeSelector, singleValueDimensionVectorSelector, maxStringBytes, SelectionPredicate.FIRST_PREDICATE); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregator.java index 0d05833378c6..72ce511ae788 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregator.java @@ -17,12 +17,13 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.query.aggregation.Aggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastUtils; import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseObjectColumnValueSelector; import org.apache.druid.segment.DimensionHandlerUtils; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregatorFactory.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregatorFactory.java index 61486e0936ad..8ff45a27380b 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -33,6 +33,7 @@ import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.query.dimension.DefaultDimensionSpec; import org.apache.druid.segment.BaseObjectColumnValueSelector; @@ -208,10 +209,11 @@ public VectorAggregator factorizeVector(VectorColumnSelectorFactory selectorFact // For multivalue string we need to iterate a list of indexedInts which is also similar to iterating // over elements for an ARRAY typed column. These two which requires an iteration will be done together. if (!capabilities.hasMultipleValues().isTrue()) { - SingleValueDimensionVectorSelector sSelector = selectorFactory.makeSingleValueDimensionSelector( - DefaultDimensionSpec.of( - fieldName)); - return new SingleStringFirstDimensionVectorAggregator(timeSelector, sSelector, maxStringBytes); + SingleValueDimensionVectorSelector sSelector = + selectorFactory.makeSingleValueDimensionSelector(DefaultDimensionSpec.of(fieldName)); + if (sSelector.nameLookupPossibleInAdvance()) { + return new SingleStringFirstDimensionVectorAggregator(timeSelector, sSelector, maxStringBytes); + } } } } diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregator.java index 563455c9eefa..1f0a70bd1fe3 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregator.java @@ -17,11 +17,12 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastUtils; import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector; import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseObjectColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstFoldingAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstFoldingAggregatorFactory.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstFoldingAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstFoldingAggregatorFactory.java index 8c6c06856d8e..ebb74746f020 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/first/StringFirstFoldingAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstFoldingAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.fasterxml.jackson.annotation.JsonCreator; import org.apache.druid.query.aggregation.AggregatorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregator.java new file mode 100644 index 000000000000..a99332332b4e --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregator.java @@ -0,0 +1,39 @@ +/* + * 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.druid.query.aggregation.firstlast.first; + +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastVectorAggregator; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; + +public class StringFirstVectorAggregator extends StringFirstLastVectorAggregator +{ + public StringFirstVectorAggregator( + @Nullable VectorValueSelector timeSelector, + VectorObjectSelector objectSelector, + int maxStringBytes + ) + { + super(timeSelector, objectSelector, maxStringBytes, SelectionPredicate.FIRST_PREDICATE); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregator.java index 009e9c82333f..4f5a39851d2f 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregatorFactory.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregatorFactory.java index 56b58a33896e..3d22508c1cdb 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,8 +32,8 @@ import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.query.aggregation.SerializablePairLongDoubleComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastBufferAggregator.java index d605180951c4..8e8fcd9b9cc0 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregator.java similarity index 50% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregator.java index d40ba750476b..cf033b805cdf 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregator.java @@ -17,54 +17,23 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; -import org.apache.druid.query.aggregation.SerializablePairLongDouble; +import org.apache.druid.query.aggregation.firstlast.DoubleFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; import org.apache.druid.segment.vector.VectorObjectSelector; import org.apache.druid.segment.vector.VectorValueSelector; -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -/** - * Vectorized version of on heap 'last' aggregator for column selectors with type DOUBLE.. - */ -public class DoubleLastVectorAggregator extends NumericLastVectorAggregator +public class DoubleLastVectorAggregator extends DoubleFirstLastVectorAggregator { - double lastValue; public DoubleLastVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) { - super(timeSelector, null, objectSelector); - lastValue = 0; + super(timeSelector, objectSelector, SelectionPredicate.LAST_PREDICATE); } public DoubleLastVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) { - super(timeSelector, valueSelector, null); - lastValue = 0; - } - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - lastValue = valueSelector != null ? valueSelector.getDoubleVector()[index] : ((SerializablePairLongDouble) objectSelector.getObjectVector()[index]).getRhs(); - buf.putDouble(position, lastValue); - } - - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putDouble(position, 0); - } - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongDouble(buf.getLong(position), rhsNull ? null : buf.getDouble(position + VALUE_OFFSET)); + super(timeSelector, valueSelector, SelectionPredicate.LAST_PREDICATE); } } - diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregator.java index 63147a92db77..29117c61c9d1 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregatorFactory.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregatorFactory.java index 0eefc4586452..ac1ebfa4ae35 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,8 +32,8 @@ import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.query.aggregation.SerializablePairLongFloatComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.query.aggregation.first.FirstLastUtils; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastBufferAggregator.java index 68affc9cba90..cc798d806519 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregator.java similarity index 50% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregator.java index a5500c19cbe8..45f941e68722 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregator.java @@ -17,55 +17,23 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; -import org.apache.druid.query.aggregation.SerializablePairLongFloat; +import org.apache.druid.query.aggregation.firstlast.FloatFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; import org.apache.druid.segment.vector.VectorObjectSelector; import org.apache.druid.segment.vector.VectorValueSelector; -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -/** - * Vectorized version of on heap 'last' aggregator for column selectors with type FLOAT.. - */ -public class FloatLastVectorAggregator extends NumericLastVectorAggregator +public class FloatLastVectorAggregator extends FloatFirstLastVectorAggregator { - float lastValue; public FloatLastVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) { - super(timeSelector, null, objectSelector); - lastValue = 0; + super(timeSelector, objectSelector, SelectionPredicate.LAST_PREDICATE); } public FloatLastVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) { - super(timeSelector, valueSelector, null); - lastValue = 0; - } - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - lastValue = valueSelector != null ? valueSelector.getFloatVector()[index] : ((SerializablePairLongFloat) objectSelector.getObjectVector()[index]).getRhs(); - buf.putFloat(position, lastValue); - } - - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putFloat(position, 0); - } - - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongFloat(buf.getLong(position), rhsNull ? null : buf.getFloat(position + VALUE_OFFSET)); + super(timeSelector, valueSelector, SelectionPredicate.LAST_PREDICATE); } } - diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/GenericLastAggregateCombiner.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/GenericLastAggregateCombiner.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/GenericLastAggregateCombiner.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/GenericLastAggregateCombiner.java index 1b1e2dbd128b..dca26332557e 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/GenericLastAggregateCombiner.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/GenericLastAggregateCombiner.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.google.common.primitives.Longs; import org.apache.druid.collections.SerializablePair; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregator.java index f5f5791da960..5b35c76c38cd 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregatorFactory.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregatorFactory.java index 492df2136492..bae205cded3e 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,8 +32,8 @@ import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.SerializablePairLongLongComplexMetricSerde; import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.query.aggregation.first.FirstLastUtils; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.segment.ColumnInspector; import org.apache.druid.segment.ColumnSelectorFactory; @@ -149,9 +149,7 @@ public boolean canVectorize(ColumnInspector columnInspector) } @Override - public VectorAggregator factorizeVector( - VectorColumnSelectorFactory columnSelectorFactory - ) + public VectorAggregator factorizeVector(VectorColumnSelectorFactory columnSelectorFactory) { VectorValueSelector timeSelector = columnSelectorFactory.makeValueSelector(timeColumn); ColumnCapabilities capabilities = columnSelectorFactory.getColumnCapabilities(fieldName); diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastBufferAggregator.java index a4a318329b77..0aaf00e7f13a 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.segment.BaseLongColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregator.java new file mode 100644 index 000000000000..97c7eecaacdf --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregator.java @@ -0,0 +1,38 @@ +/* + * 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.druid.query.aggregation.firstlast.last; + +import org.apache.druid.query.aggregation.firstlast.LongFirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +public class LongLastVectorAggregator extends LongFirstLastVectorAggregator +{ + public LongLastVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) + { + super(timeSelector, objectSelector, SelectionPredicate.LAST_PREDICATE); + } + + public LongLastVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) + { + super(timeSelector, valueSelector, SelectionPredicate.LAST_PREDICATE); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastAggregator.java similarity index 95% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastAggregator.java index 50d4470fa54a..be2904d34d7d 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.collections.SerializablePair; import org.apache.druid.common.config.NullHandling; @@ -28,7 +28,7 @@ /** * Base type for on heap 'last' aggregator for primitive numeric column selectors.. * - * This could probably share a base class with {@link org.apache.druid.query.aggregation.first.NumericFirstAggregator} + * This could probably share a base class with {@link org.apache.druid.query.aggregation.firstlast.first.NumericFirstAggregator} */ public abstract class NumericLastAggregator implements Aggregator { diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastBufferAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastBufferAggregator.java index 2ba15a7929d3..cc1190fce0ec 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/NumericLastBufferAggregator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.collections.SerializablePair; import org.apache.druid.common.config.NullHandling; @@ -32,7 +32,7 @@ * Base type for buffer based 'last' aggregator for primitive numeric column selectors * * This could probably share a base type with - * {@link org.apache.druid.query.aggregation.first.NumericFirstBufferAggregator} ... + * {@link org.apache.druid.query.aggregation.firstlast.first.NumericFirstBufferAggregator} ... */ public abstract class NumericLastBufferAggregator implements BufferAggregator { diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/SingleStringLastDimensionVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/SingleStringLastDimensionVectorAggregator.java new file mode 100644 index 000000000000..aaaeb2039bdc --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/SingleStringLastDimensionVectorAggregator.java @@ -0,0 +1,38 @@ +/* + * 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.druid.query.aggregation.firstlast.last; + +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; +import org.apache.druid.query.aggregation.firstlast.SingleStringFirstLastDimensionVectorAggregator; +import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +public class SingleStringLastDimensionVectorAggregator extends SingleStringFirstLastDimensionVectorAggregator +{ + + public SingleStringLastDimensionVectorAggregator( + VectorValueSelector timeSelector, + SingleValueDimensionVectorSelector singleValueDimensionVectorSelector, + int maxStringBytes + ) + { + super(timeSelector, singleValueDimensionVectorSelector, maxStringBytes, SelectionPredicate.LAST_PREDICATE); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregator.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregator.java index f1dbab60938b..da6c474f8022 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregator.java @@ -17,13 +17,13 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.query.aggregation.Aggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.first.StringFirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastUtils; import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseObjectColumnValueSelector; import org.apache.druid.segment.DimensionHandlerUtils; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregatorFactory.java similarity index 94% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregatorFactory.java index a9bb2f0bbd6f..8e69d7018924 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -32,8 +32,8 @@ import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.query.aggregation.first.FirstLastUtils; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.FirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; import org.apache.druid.query.cache.CacheKeyBuilder; import org.apache.druid.query.dimension.DefaultDimensionSpec; import org.apache.druid.segment.BaseObjectColumnValueSelector; @@ -182,7 +182,11 @@ public VectorAggregator factorizeVector(VectorColumnSelectorFactory selectorFact SingleValueDimensionVectorSelector sSelector = selectorFactory.makeSingleValueDimensionSelector( DefaultDimensionSpec.of( fieldName)); - return new SingleStringLastDimensionVectorAggregator(timeSelector, sSelector, maxStringBytes); + // Relies on storing the id, and possibly retrieving it at a later stage, therefore name lookup should be + // possible for non current rows + if (sSelector.nameLookupPossibleInAdvance()) { + return new SingleStringLastDimensionVectorAggregator(timeSelector, sSelector, maxStringBytes); + } } } } diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregator.java similarity index 97% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregator.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregator.java index 3f78745f5fad..878cd36025c9 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregator.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregator.java @@ -17,12 +17,12 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.first.StringFirstLastUtils; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastUtils; import org.apache.druid.query.monomorphicprocessing.RuntimeShapeInspector; import org.apache.druid.segment.BaseLongColumnValueSelector; import org.apache.druid.segment.BaseObjectColumnValueSelector; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastFoldingAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastFoldingAggregatorFactory.java similarity index 96% rename from processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastFoldingAggregatorFactory.java rename to processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastFoldingAggregatorFactory.java index ad18eeebadc4..5abc2083b186 100644 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastFoldingAggregatorFactory.java +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastFoldingAggregatorFactory.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.fasterxml.jackson.annotation.JsonCreator; import org.apache.druid.query.aggregation.AggregatorFactory; diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregator.java new file mode 100644 index 000000000000..d0529d96e7ba --- /dev/null +++ b/processing/src/main/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregator.java @@ -0,0 +1,39 @@ +/* + * 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.druid.query.aggregation.firstlast.last; + +import org.apache.druid.query.aggregation.firstlast.SelectionPredicate; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastVectorAggregator; +import org.apache.druid.segment.vector.VectorObjectSelector; +import org.apache.druid.segment.vector.VectorValueSelector; + +import javax.annotation.Nullable; + +public class StringLastVectorAggregator extends StringFirstLastVectorAggregator +{ + public StringLastVectorAggregator( + @Nullable VectorValueSelector timeSelector, + VectorObjectSelector objectSelector, + int maxStringBytes + ) + { + super(timeSelector, objectSelector, maxStringBytes, SelectionPredicate.LAST_PREDICATE); + } +} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregator.java deleted file mode 100644 index 65fadf549a76..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.druid.query.aggregation.last; - -import org.apache.druid.query.aggregation.SerializablePairLongLong; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -/** - * Vectorized version of on heap 'last' aggregator for column selectors with type LONG.. - */ -public class LongLastVectorAggregator extends NumericLastVectorAggregator -{ - long lastValue; - - public LongLastVectorAggregator(VectorValueSelector timeSelector, VectorObjectSelector objectSelector) - { - super(timeSelector, null, objectSelector); - lastValue = 0; - } - - public LongLastVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector) - { - super(timeSelector, valueSelector, null); - lastValue = 0; - } - - @Override - public void initValue(ByteBuffer buf, int position) - { - buf.putLong(position, 0); - } - - @Override - void putValue(ByteBuffer buf, int position, int index) - { - lastValue = valueSelector != null ? valueSelector.getLongVector()[index] : ((SerializablePairLongLong) objectSelector.getObjectVector()[index]).getRhs(); - buf.putLong(position, lastValue); - } - - - /** - * @return The primitive object stored at the position in the buffer. - */ - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - final boolean rhsNull = isValueNull(buf, position); - return new SerializablePairLongLong(buf.getLong(position), rhsNull ? null : buf.getLong(position + VALUE_OFFSET)); - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastVectorAggregator.java deleted file mode 100644 index a556c3fea186..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/NumericLastVectorAggregator.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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.druid.query.aggregation.last; - -import org.apache.druid.collections.SerializablePair; -import org.apache.druid.common.config.NullHandling; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -/** - * Base type for vectorized version of on heap 'last' aggregator for primitive numeric column selectors.. - */ -public abstract class NumericLastVectorAggregator implements VectorAggregator -{ - static final int NULL_OFFSET = Long.BYTES; - static final int VALUE_OFFSET = NULL_OFFSET + Byte.BYTES; - final VectorValueSelector valueSelector; - final VectorObjectSelector objectSelector; - private final boolean useDefault = NullHandling.replaceWithDefault(); - private final VectorValueSelector timeSelector; - private long lastTime; - - - NumericLastVectorAggregator(VectorValueSelector timeSelector, VectorValueSelector valueSelector, VectorObjectSelector objectSelector) - { - this.timeSelector = timeSelector; - this.valueSelector = valueSelector; - this.objectSelector = objectSelector; - lastTime = Long.MIN_VALUE; - } - - @Override - public void init(ByteBuffer buf, int position) - { - buf.putLong(position, Long.MIN_VALUE); - buf.put(position + NULL_OFFSET, useDefault ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE); - initValue(buf, position + VALUE_OFFSET); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - if (timeSelector == null) { - return; - } - - final long[] timeVector = timeSelector.getLongVector(); - Object[] objectsWhichMightBeNumeric = null; - boolean[] nullValueVector = null; - boolean nullAbsent = false; - - if (objectSelector != null) { - objectsWhichMightBeNumeric = objectSelector.getObjectVector(); - } else if (valueSelector != null) { - nullValueVector = valueSelector.getNullVector(); - } - - lastTime = buf.getLong(position); - - if (nullValueVector == null) { - nullAbsent = true; - } - - //the time vector is already sorted so the last element would be the latest - //traverse the value vector from the back (for latest) - int index = endRow - 1; - if (!useDefault && !nullAbsent) { - for (int i = endRow - 1; i >= startRow; i--) { - if (!nullValueVector[i]) { - index = i; - break; - } - } - } - - if (objectsWhichMightBeNumeric != null) { - final SerializablePair inPair = (SerializablePair) objectsWhichMightBeNumeric[index]; - if (inPair != null && inPair.lhs != null && inPair.lhs >= lastTime) { - lastTime = inPair.lhs; - if (useDefault || inPair.rhs != null) { - updateTimeWithValue(buf, position, lastTime, index); - } else { - updateTimeWithNull(buf, position, lastTime); - } - } - } else { - final long latestTime = timeVector[index]; - if (latestTime >= lastTime) { - lastTime = latestTime; - if (useDefault || nullValueVector == null || !nullValueVector[index]) { - updateTimeWithValue(buf, position, lastTime, index); - } else { - updateTimeWithNull(buf, position, lastTime); - } - } - } - } - - /** - * - * Checks if the aggregated value at a position in the buffer is null or not - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @return - */ - boolean isValueNull(ByteBuffer buf, int position) - { - return buf.get(position + NULL_OFFSET) == NullHandling.IS_NULL_BYTE; - } - - @Override - public void aggregate( - ByteBuffer buf, - int numRows, - int[] positions, - @Nullable int[] rows, - int positionOffset - ) - { - if (timeSelector == null) { - return; - } - - final long[] timeVector = timeSelector.getLongVector(); - Object[] objectsWhichMightBeNumeric = null; - boolean[] nulls = null; - - if (objectSelector != null) { - objectsWhichMightBeNumeric = objectSelector.getObjectVector(); - } else if (valueSelector != null) { - nulls = useDefault ? null : valueSelector.getNullVector(); - } - - - - for (int i = 0; i < numRows; i++) { - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - long lastTime = buf.getLong(position); - - if (objectsWhichMightBeNumeric != null) { - final SerializablePair inPair = (SerializablePair) objectsWhichMightBeNumeric[row]; - if (useDefault || inPair != null) { - if (inPair.lhs != null && inPair.lhs >= lastTime) { - if (inPair.rhs != null) { - updateTimeWithValue(buf, position, inPair.lhs, row); - } else { - updateTimeWithNull(buf, position, inPair.lhs); - } - } - } - } else { - if (timeVector[row] >= lastTime) { - if (useDefault || nulls == null || !nulls[row]) { - updateTimeWithValue(buf, position, timeVector[row], row); - } else { - updateTimeWithNull(buf, position, timeVector[row]); - } - } - } - } - } - - /** - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @param time the time to be updated in the buffer as the last time - * @param index he index of the vectorized vector which is the last value - */ - void updateTimeWithValue(ByteBuffer buf, int position, long time, int index) - { - buf.putLong(position, time); - buf.put(position + NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - putValue(buf, position + VALUE_OFFSET, index); - } - - /** - * - * @param buf byte buffer storing the byte array representation of the aggregate - * @param position offset within the byte buffer at which the current aggregate value is stored - * @param time the time to be updated in the buffer as the last time - */ - void updateTimeWithNull(ByteBuffer buf, int position, long time) - { - buf.putLong(position, time); - buf.put(position + NULL_OFFSET, NullHandling.IS_NULL_BYTE); - } - - /** - *Abstract function which needs to be overridden by subclasses to set the initial value - */ - abstract void initValue(ByteBuffer buf, int position); - - /** - *Abstract function which needs to be overridden by subclasses to set the - * latest value in the buffer depending on the datatype - */ - abstract void putValue(ByteBuffer buf, int position, int index); - - @Override - public void close() - { - // no resources to cleanup - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/SingleStringLastDimensionVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/last/SingleStringLastDimensionVectorAggregator.java deleted file mode 100644 index 6b39088faa2e..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/SingleStringLastDimensionVectorAggregator.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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.druid.query.aggregation.last; - -import org.apache.druid.common.config.NullHandling; -import org.apache.druid.java.util.common.StringUtils; -import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.segment.vector.SingleValueDimensionVectorSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class SingleStringLastDimensionVectorAggregator implements VectorAggregator -{ - private final VectorValueSelector timeSelector; - private final SingleValueDimensionVectorSelector valueDimensionVectorSelector; - private long lastTime; - private final int maxStringBytes; - private final boolean useDefault = NullHandling.replaceWithDefault(); - - public SingleStringLastDimensionVectorAggregator( - VectorValueSelector timeSelector, - SingleValueDimensionVectorSelector valueDimensionVectorSelector, - int maxStringBytes - ) - { - this.timeSelector = timeSelector; - this.valueDimensionVectorSelector = valueDimensionVectorSelector; - this.maxStringBytes = maxStringBytes; - this.lastTime = Long.MIN_VALUE; - } - - @Override - public void init(ByteBuffer buf, int position) - { - buf.putLong(position, Long.MIN_VALUE); - buf.put( - position + NumericLastVectorAggregator.NULL_OFFSET, - useDefault ? NullHandling.IS_NOT_NULL_BYTE : NullHandling.IS_NULL_BYTE - ); - buf.putInt(position + NumericLastVectorAggregator.VALUE_OFFSET, 0); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final int[] valueVector = valueDimensionVectorSelector.getRowVector(); - lastTime = buf.getLong(position); - int index; - - long latestTime; - for (index = endRow - 1; index >= startRow; index--) { - if (nullTimeVector != null && nullTimeVector[index]) { - continue; - } - latestTime = timeVector[index]; - if (latestTime > lastTime) { - lastTime = latestTime; - buf.putLong(position, lastTime); - buf.put(position + NumericLastVectorAggregator.NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - buf.putInt(position + NumericLastVectorAggregator.VALUE_OFFSET, valueVector[index]); - } - } - } - - @Override - public void aggregate(ByteBuffer buf, int numRows, int[] positions, @Nullable int[] rows, int positionOffset) - { - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final int[] values = valueDimensionVectorSelector.getRowVector(); - for (int i = numRows - 1; i >= 0; i--) { - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - lastTime = buf.getLong(position); - if (timeVector[row] > lastTime) { - lastTime = timeVector[row]; - buf.putLong(position, lastTime); - buf.put(position + NumericLastVectorAggregator.NULL_OFFSET, NullHandling.IS_NOT_NULL_BYTE); - buf.putInt(position + NumericLastVectorAggregator.VALUE_OFFSET, values[row]); - } - } - } - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - int index = buf.getInt(position + NumericLastVectorAggregator.VALUE_OFFSET); - long earliest = buf.getLong(position); - String strValue = valueDimensionVectorSelector.lookupName(index); - return new SerializablePairLongString(earliest, StringUtils.chop(strValue, maxStringBytes)); - } - - @Override - public void close() - { - // nothing to close - } -} diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregator.java deleted file mode 100644 index 09ef10572b59..000000000000 --- a/processing/src/main/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregator.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.druid.query.aggregation.last; - -import org.apache.druid.java.util.common.DateTimes; -import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.VectorAggregator; -import org.apache.druid.query.aggregation.first.FirstLastUtils; -import org.apache.druid.query.aggregation.first.StringFirstLastUtils; -import org.apache.druid.segment.DimensionHandlerUtils; -import org.apache.druid.segment.vector.VectorObjectSelector; -import org.apache.druid.segment.vector.VectorValueSelector; - -import javax.annotation.Nullable; -import java.nio.ByteBuffer; - -public class StringLastVectorAggregator implements VectorAggregator -{ - private static final SerializablePairLongString INIT = new SerializablePairLongString( - DateTimes.MIN.getMillis(), - null - ); - private final VectorValueSelector timeSelector; - private final VectorObjectSelector valueSelector; - private final int maxStringBytes; - protected long lastTime; - - public StringLastVectorAggregator( - @Nullable final VectorValueSelector timeSelector, - final VectorObjectSelector valueSelector, - final int maxStringBytes - ) - { - this.timeSelector = timeSelector; - this.valueSelector = valueSelector; - this.maxStringBytes = maxStringBytes; - } - - @Override - public void init(ByteBuffer buf, int position) - { - StringFirstLastUtils.writePair(buf, position, INIT, maxStringBytes); - } - - @Override - public void aggregate(ByteBuffer buf, int position, int startRow, int endRow) - { - if (timeSelector == null) { - return; - } - final long[] times = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final Object[] objectsWhichMightBeStrings = valueSelector.getObjectVector(); - - lastTime = buf.getLong(position); - int index; - for (int i = endRow - 1; i >= startRow; i--) { - if (objectsWhichMightBeStrings[i] == null) { - continue; - } - if (times[i] <= lastTime) { - continue; - } - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - index = i; - final boolean foldNeeded = FirstLastUtils.objectNeedsFoldCheck(objectsWhichMightBeStrings[index], SerializablePairLongString.class); - if (foldNeeded) { - // Less efficient code path when folding is a possibility (we must read the value selector first just in case - // it's a foldable object). - final SerializablePairLongString inPair = StringFirstLastUtils.readPairFromVectorSelectorsAtIndex( - timeSelector, - valueSelector, - index - ); - if (inPair != null) { - final long lastTime = buf.getLong(position); - if (inPair.lhs >= lastTime) { - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(inPair.lhs, inPair.rhs), - maxStringBytes - ); - } - } - } else { - final long time = times[index]; - - if (time >= lastTime) { - final String value = DimensionHandlerUtils.convertObjectToString(objectsWhichMightBeStrings[index]); - lastTime = time; - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(time, value), - maxStringBytes - ); - } - } - } - - } - - @Override - public void aggregate( - ByteBuffer buf, - int numRows, - int[] positions, - @Nullable int[] rows, - int positionOffset - ) - { - if (timeSelector == null) { - return; - } - final long[] timeVector = timeSelector.getLongVector(); - final boolean[] nullTimeVector = timeSelector.getNullVector(); - final Object[] objectsWhichMightBeStrings = valueSelector.getObjectVector(); - - // iterate once over the object vector to find first non null element and - // determine if the type is Pair or not - boolean foldNeeded = false; - for (Object obj : objectsWhichMightBeStrings) { - if (obj != null) { - foldNeeded = FirstLastUtils.objectNeedsFoldCheck(obj, SerializablePairLongString.class); - break; - } - } - - for (int i = 0; i < numRows; i++) { - if (nullTimeVector != null && nullTimeVector[i]) { - continue; - } - int position = positions[i] + positionOffset; - int row = rows == null ? i : rows[i]; - long lastTime = buf.getLong(position); - if (timeVector[row] >= lastTime) { - if (foldNeeded) { - final SerializablePairLongString inPair = StringFirstLastUtils.readPairFromVectorSelectorsAtIndex( - timeSelector, - valueSelector, - row - ); - if (inPair != null) { - if (inPair.lhs >= lastTime) { - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(inPair.lhs, inPair.rhs), - maxStringBytes - ); - } - } - } else { - final String value = DimensionHandlerUtils.convertObjectToString(objectsWhichMightBeStrings[row]); - lastTime = timeVector[row]; - StringFirstLastUtils.writePair( - buf, - position, - new SerializablePairLongString(lastTime, value), - maxStringBytes - ); - } - } - } - } - - @Nullable - @Override - public Object get(ByteBuffer buf, int position) - { - return StringFirstLastUtils.readPair(buf, position); - } - - @Override - public void close() - { - // nothing to close - } -} - diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/AggregatorFactoryTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/AggregatorFactoryTest.java index 44c998cd89cd..ff7b18c3dca2 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/AggregatorFactoryTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/AggregatorFactoryTest.java @@ -28,15 +28,15 @@ import org.apache.druid.query.aggregation.any.LongAnyAggregatorFactory; import org.apache.druid.query.aggregation.any.StringAnyAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.mean.DoubleMeanAggregatorFactory; import org.apache.druid.query.aggregation.post.FinalizingFieldAccessPostAggregator; import org.apache.druid.query.dimension.DefaultDimensionSpec; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregationTest.java index 7109a0a47961..1d521d1a5c95 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregatorTest.java similarity index 86% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregatorTest.java index e055930a2169..734d7e3d6e8c 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/DoubleFirstVectorAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/DoubleFirstVectorAggregatorTest.java @@ -17,15 +17,18 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; import org.apache.druid.segment.column.ColumnType; +import org.apache.druid.segment.vector.BaseDoubleVectorValueSelector; import org.apache.druid.segment.vector.BaseLongVectorValueSelector; import org.apache.druid.segment.vector.MultiValueDimensionVectorSelector; import org.apache.druid.segment.vector.NoFilterVectorOffset; @@ -43,7 +46,7 @@ import java.nio.ByteBuffer; import java.util.concurrent.ThreadLocalRandom; -public class DoubleFirstVectorAggregationTest extends InitializedNullHandlingTest +public class DoubleFirstVectorAggregatorTest extends InitializedNullHandlingTest { private static final double EPSILON = 1e-5; private static final double[] VALUES = new double[]{7.8d, 11, 23.67, 60}; @@ -69,7 +72,8 @@ public class DoubleFirstVectorAggregationTest extends InitializedNullHandlingTes private DoubleFirstAggregatorFactory doubleFirstAggregatorFactory; private VectorColumnSelectorFactory selectorFactory; - private VectorValueSelector nonLongValueSelector; + private VectorValueSelector longValueSelector; + private VectorValueSelector doubleValueSelector; @Before public void setup() @@ -115,7 +119,7 @@ public int getCurrentVectorSize() } }; - nonLongValueSelector = new BaseLongVectorValueSelector(new NoFilterVectorOffset( + longValueSelector = new BaseLongVectorValueSelector(new NoFilterVectorOffset( LONG_VALUES.length, 0, LONG_VALUES.length @@ -159,6 +163,22 @@ public int getCurrentVectorSize() } }; + doubleValueSelector = new BaseDoubleVectorValueSelector(new NoFilterVectorOffset(VALUES.length, 0, VALUES.length)) + { + @Override + public double[] getDoubleVector() + { + return VALUES; + } + + @Nullable + @Override + public boolean[] getNullVector() + { + return null; + } + }; + selectorFactory = new VectorColumnSelectorFactory() { @Override @@ -185,7 +205,9 @@ public VectorValueSelector makeValueSelector(String column) if (TIME_COL.equals(column)) { return timeSelector; } else if (FIELD_NAME_LONG.equals(column)) { - return nonLongValueSelector; + return longValueSelector; + } else if (FIELD_NAME.equals(column)) { + return doubleValueSelector; } return null; } @@ -230,15 +252,15 @@ public void testFactory() } @Test - public void initValueShouldInitZero() + public void testInit() { - target.initValue(buf, 0); - double initVal = buf.getDouble(0); - Assert.assertEquals(0, initVal, EPSILON); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MAX.getMillis(), buf.getLong(0)); + Assert.assertEquals(0, buf.getDouble(FirstLastVectorAggregator.VALUE_OFFSET), EPSILON); } @Test - public void aggregate() + public void testAggregate() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -247,7 +269,7 @@ public void aggregate() } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -256,7 +278,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -270,7 +292,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 0, 2}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregationTest.java index 0df142677437..e1d8ee4c7409 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregatorTest.java similarity index 92% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregatorTest.java index a95e89bd32af..660fdc91e856 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/FloatFirstVectorAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/FloatFirstVectorAggregatorTest.java @@ -17,12 +17,14 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.common.config.NullHandling; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; @@ -44,7 +46,7 @@ import java.nio.ByteBuffer; import java.util.concurrent.ThreadLocalRandom; -public class FloatFirstVectorAggregationTest extends InitializedNullHandlingTest +public class FloatFirstVectorAggregatorTest extends InitializedNullHandlingTest { private static final double EPSILON = 1e-5; private static final float[] VALUES = new float[]{7.2f, 15.6f, 2.1f, 150.0f}; @@ -261,15 +263,15 @@ public void testFactory() } @Test - public void initValueShouldBeZero() + public void testInit() { - target.initValue(buf, 0); - float initVal = buf.getFloat(0); - Assert.assertEquals(0.0f, initVal, EPSILON); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MAX.getMillis(), buf.getLong(0)); + Assert.assertEquals(0.0f, buf.getDouble(FirstLastVectorAggregator.VALUE_OFFSET), EPSILON); } @Test - public void aggregate() + public void testAggregate() { target.init(buf, 0); target.aggregate(buf, 0, 0, VALUES.length); @@ -279,17 +281,17 @@ public void aggregate() } @Test - public void aggregateNulls1() + public void testAggregateNulls1() { target1.init(buf, 0); target1.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) target1.get(buf, 0); - Assert.assertEquals(Long.MAX_VALUE, result.lhs.longValue()); + Assert.assertEquals(pairs[0].lhs.longValue(), result.lhs.longValue()); Assert.assertEquals(NullHandling.defaultFloatValue(), result.rhs); } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) target.get(buf, 0); @@ -298,7 +300,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -316,7 +318,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregationTest.java index 104dbcfa60dd..e11c27c38c77 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregatorTest.java similarity index 92% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregatorTest.java index a45e0f25563d..24dd37dd0c24 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/LongFirstVectorAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/LongFirstVectorAggregatorTest.java @@ -17,12 +17,14 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.common.config.NullHandling; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; @@ -45,7 +47,7 @@ import java.util.concurrent.ThreadLocalRandom; -public class LongFirstVectorAggregationTest extends InitializedNullHandlingTest +public class LongFirstVectorAggregatorTest extends InitializedNullHandlingTest { private static final double EPSILON = 1e-5; private static final long[] VALUES = new long[]{7, 15, 2, 150}; @@ -188,7 +190,7 @@ public VectorValueSelector makeValueSelector(String column) { if (TIME_COL.equals(column)) { return timeSelector; - } else if (FIELD_NAME_LONG.equals(column)) { + } else if (FIELD_NAME_LONG.equals(column) || FIELD_NAME.equals(column)) { return nonLongValueSelector; } return null; @@ -234,15 +236,15 @@ public void testFactory() } @Test - public void initValueShouldInitZero() + public void testInit() { - target.initValue(buf, 0); - long initVal = buf.getLong(0); - Assert.assertEquals(0, initVal); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MAX.getMillis(), buf.getLong(0)); + Assert.assertEquals(0, buf.getLong(FirstLastVectorAggregator.VALUE_OFFSET)); } @Test - public void aggregate() + public void testAggregate() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -251,7 +253,7 @@ public void aggregate() } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -260,7 +262,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -278,7 +280,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregationTest.java index d2f332f0bb85..6f6bd41f6bc1 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.common.config.NullHandling; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregatorTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregatorTest.java index 2653940ae389..9f72ff8fd313 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstBufferAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstBufferAggregatorTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstLastUtilsTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstLastUtilsTest.java similarity index 94% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstLastUtilsTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstLastUtilsTest.java index b4e4088535cb..d6b95a89a995 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstLastUtilsTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstLastUtilsTest.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.query.aggregation.SerializablePairLongString; +import org.apache.druid.query.aggregation.firstlast.StringFirstLastUtils; import org.junit.Assert; import org.junit.Test; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstTimeseriesQueryTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstTimeseriesQueryTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstTimeseriesQueryTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstTimeseriesQueryTest.java index 267fa52ab639..2e960e6186e3 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstTimeseriesQueryTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstTimeseriesQueryTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregatorTest.java similarity index 96% rename from processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregatorTest.java index e3b461da5687..2652431e083c 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/first/StringFirstVectorAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstVectorAggregatorTest.java @@ -17,8 +17,9 @@ * under the License. */ -package org.apache.druid.query.aggregation.first; +package org.apache.druid.query.aggregation.firstlast.first; +import org.apache.druid.common.config.NullHandling; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongString; @@ -295,7 +296,7 @@ public void testFactory() } @Test - public void initValueShouldBeMaxDate() + public void testInit() { target.init(buf, 0); long initVal = buf.getLong(0); @@ -303,7 +304,7 @@ public void initValueShouldBeMaxDate() } @Test - public void aggregate() + public void testAggregate() { target.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) target.get(buf, 0); @@ -325,7 +326,7 @@ public void testStringEarliestOnNonStringColumns() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -334,12 +335,12 @@ public void aggregateBatchWithoutRows() for (int i = 0; i < positions.length; i++) { Pair result = (Pair) target.get(buf, positions[i] + positionOffset); Assert.assertEquals(times[i], result.lhs.longValue()); - Assert.assertEquals(VALUES[i], result.rhs); + Assert.assertEquals(NullHandling.nullToEmptyIfNeeded(VALUES[i]), result.rhs); } } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; @@ -349,7 +350,7 @@ public void aggregateBatchWithRows() for (int i = 0; i < positions.length; i++) { Pair result = (Pair) target.get(buf, positions[i] + positionOffset); Assert.assertEquals(times[rows[i]], result.lhs.longValue()); - Assert.assertEquals(VALUES[rows[i]], result.rhs); + Assert.assertEquals(NullHandling.nullToEmptyIfNeeded(VALUES[rows[i]]), result.rhs); } } diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregationTest.java index bbcf9be37a2b..1135fb76ca6f 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregatorTest.java similarity index 87% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregatorTest.java index d3125f190e1c..16e1bdb43892 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/DoubleLastVectorAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/DoubleLastVectorAggregatorTest.java @@ -17,15 +17,18 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongDouble; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; import org.apache.druid.segment.column.ColumnType; +import org.apache.druid.segment.vector.BaseDoubleVectorValueSelector; import org.apache.druid.segment.vector.BaseLongVectorValueSelector; import org.apache.druid.segment.vector.MultiValueDimensionVectorSelector; import org.apache.druid.segment.vector.NoFilterVectorOffset; @@ -70,7 +73,8 @@ public class DoubleLastVectorAggregatorTest extends InitializedNullHandlingTest private DoubleLastAggregatorFactory doubleLastAggregatorFactory; private VectorColumnSelectorFactory selectorFactory; - private VectorValueSelector nonLongValueSelector; + private VectorValueSelector longValueSelector; + private VectorValueSelector doubleValueSelector; @Before public void setup() @@ -116,7 +120,7 @@ public int getCurrentVectorSize() } }; - nonLongValueSelector = new BaseLongVectorValueSelector(new NoFilterVectorOffset( + longValueSelector = new BaseLongVectorValueSelector(new NoFilterVectorOffset( LONG_VALUES.length, 0, LONG_VALUES.length @@ -160,6 +164,22 @@ public int getCurrentVectorSize() } }; + doubleValueSelector = new BaseDoubleVectorValueSelector(new NoFilterVectorOffset(VALUES.length, 0, VALUES.length)) + { + @Override + public double[] getDoubleVector() + { + return VALUES; + } + + @Nullable + @Override + public boolean[] getNullVector() + { + return null; + } + }; + selectorFactory = new VectorColumnSelectorFactory() { @Override @@ -186,7 +206,9 @@ public VectorValueSelector makeValueSelector(String column) if (TIME_COL.equals(column)) { return timeSelector; } else if (FIELD_NAME_LONG.equals(column)) { - return nonLongValueSelector; + return longValueSelector; + } else if (FIELD_NAME.equals(column)) { + return doubleValueSelector; } return null; } @@ -231,15 +253,15 @@ public void testFactory() } @Test - public void initValueShouldInitZero() + public void testInit() { - target.initValue(buf, 0); - double initVal = buf.getDouble(0); - Assert.assertEquals(0, initVal, EPSILON); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MIN.getMillis(), buf.getLong(0)); + Assert.assertEquals(0, buf.getDouble(FirstLastVectorAggregator.VALUE_OFFSET), EPSILON); } @Test - public void aggregate() + public void testAggregate() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -248,7 +270,7 @@ public void aggregate() } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -257,7 +279,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -271,7 +293,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregationTest.java index 7030f6671e1b..77ac1083f454 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregatorTest.java similarity index 92% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregatorTest.java index 957d585e5fd9..b19767a4ae9c 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/FloatLastVectorAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/FloatLastVectorAggregatorTest.java @@ -17,12 +17,15 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.common.config.NullHandling; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FloatFirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; @@ -69,7 +72,7 @@ public class FloatLastVectorAggregatorTest extends InitializedNullHandlingTest private VectorObjectSelector selector; private BaseLongVectorValueSelector timeSelector; private ByteBuffer buf; - private FloatLastVectorAggregator target; + private FloatFirstLastVectorAggregator target; private FloatLastAggregatorFactory floatLastAggregatorFactory; private VectorColumnSelectorFactory selectorFactory; @@ -235,15 +238,15 @@ public void testFactory() } @Test - public void initValueShouldBeZero() + public void testInit() { - target.initValue(buf, 0); - float initVal = buf.getFloat(0); - Assert.assertEquals(0.0f, initVal, EPSILON); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MIN.getMillis(), buf.getLong(0)); + Assert.assertEquals(0.0f, buf.getFloat(FirstLastVectorAggregator.VALUE_OFFSET), EPSILON); } @Test - public void aggregate() + public void testAggregate() { target.init(buf, 0); target.aggregate(buf, 0, 0, VALUES.length); @@ -253,7 +256,7 @@ public void aggregate() } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) target.get(buf, 0); @@ -262,7 +265,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -280,7 +283,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregationTest.java index 111f86884251..6a922b63d5c6 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregatorTest.java similarity index 80% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregatorTest.java index 6cc8bfa9f5a2..04fffcd7d94d 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/LongLastVectorAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/LongLastVectorAggregatorTest.java @@ -17,12 +17,14 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.common.config.NullHandling; +import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.VectorAggregator; +import org.apache.druid.query.aggregation.firstlast.FirstLastVectorAggregator; import org.apache.druid.query.dimension.DimensionSpec; import org.apache.druid.segment.column.ColumnCapabilities; import org.apache.druid.segment.column.ColumnCapabilitiesImpl; @@ -187,7 +189,7 @@ public VectorValueSelector makeValueSelector(String column) { if (TIME_COL.equals(column)) { return timeSelector; - } else if (FIELD_NAME_LONG.equals(column)) { + } else if (FIELD_NAME_LONG.equals(column) || FIELD_NAME.equals(column)) { return nonLongValueSelector; } return null; @@ -233,16 +235,17 @@ public void testFactory() } @Test - public void initValueShouldInitZero() + public void testInit() { - target.initValue(buf, 0); - long initVal = buf.getLong(0); - Assert.assertEquals(0, initVal); + target.init(buf, 0); + Assert.assertEquals(DateTimes.MIN.getMillis(), buf.getLong(0)); + Assert.assertEquals(0, buf.getLong(FirstLastVectorAggregator.VALUE_OFFSET)); } @Test - public void aggregate() + public void testAggregate() { + target.init(buf, 0); target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); Assert.assertEquals(pairs[3].lhs.longValue(), result.lhs.longValue()); @@ -250,7 +253,7 @@ public void aggregate() } @Test - public void aggregateWithNulls() + public void testAggregateWithNulls() { target.aggregate(buf, 0, 0, pairs.length); Pair result = (Pair) target.get(buf, 0); @@ -259,7 +262,7 @@ public void aggregateWithNulls() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -277,7 +280,7 @@ public void aggregateBatchWithoutRows() } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; @@ -295,6 +298,67 @@ public void aggregateBatchWithRows() } } + @Test + public void testAggregateWithStringifiedLongs() + { + VectorObjectSelector objectSelector = new VectorObjectSelector() + { + @Override + public Object[] getObjectVector() + { + return new Object[]{"1000", "2000", "3000"}; + } + + @Override + public int getMaxVectorSize() + { + return 3; + } + + @Override + public int getCurrentVectorSize() + { + return 3; + } + }; + LongLastVectorAggregator ll = new LongLastVectorAggregator(createLongSelector(new Long[]{1L, 2L, 3L}), objectSelector); + clearBufferForPositions(0, 0); + ll.aggregate(buf, 0, 0, 3); + Pair val = (Pair) ll.get(buf, 0); + Assert.assertEquals(3, (long) val.lhs); + Assert.assertEquals(3000, (long) val.rhs); + } + + private VectorValueSelector createLongSelector(Long[] times) + { + return new BaseLongVectorValueSelector(new NoFilterVectorOffset(times.length, 0, times.length)) + { + @Override + public long[] getLongVector() + { + long[] timesCasted = new long[times.length]; + for (int i = 0; i < times.length; ++i) { + timesCasted[i] = times[i] == null ? 0 : times[i]; + } + return timesCasted; + } + + @Nullable + @Override + public boolean[] getNullVector() + { + if (NullHandling.replaceWithDefault()) { + return null; + } + boolean[] nulls = new boolean[times.length]; + for (int i = 0; i < times.length; ++i) { + nulls[i] = times[i] == null; + } + return nulls; + } + }; + } + private void clearBufferForPositions(int offset, int... positions) { for (int position : positions) { diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregationTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastAggregationTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregationTest.java index 6a6aa1e6509d..974d668b9818 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastAggregationTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastAggregationTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.common.config.NullHandling; import org.apache.druid.java.util.common.Pair; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregatorTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregatorTest.java index 37a1c417e198..4c3d7fea39e8 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastBufferAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastBufferAggregatorTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import org.apache.druid.query.aggregation.BufferAggregator; import org.apache.druid.query.aggregation.SerializablePairLongString; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastTimeseriesQueryTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastTimeseriesQueryTest.java similarity index 99% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastTimeseriesQueryTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastTimeseriesQueryTest.java index 318a2a47fd68..6bbada405b93 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastTimeseriesQueryTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastTimeseriesQueryTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregatorTest.java similarity index 95% rename from processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregatorTest.java rename to processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregatorTest.java index da79faae3c15..68aea948d6b1 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/last/StringLastVectorAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/firstlast/last/StringLastVectorAggregatorTest.java @@ -17,8 +17,9 @@ * under the License. */ -package org.apache.druid.query.aggregation.last; +package org.apache.druid.query.aggregation.firstlast.last; +import org.apache.druid.common.config.NullHandling; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Pair; import org.apache.druid.query.aggregation.SerializablePairLongString; @@ -358,7 +359,7 @@ public void testStringLastOnNonStringColumns() } @Test - public void initValueShouldBeMinDate() + public void testInit() { target.init(buf, 0); long initVal = buf.getLong(0); @@ -366,7 +367,7 @@ public void initValueShouldBeMinDate() } @Test - public void aggregate() + public void testAggregate() { target.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) target.get(buf, 0); @@ -375,7 +376,7 @@ public void aggregate() } @Test - public void aggregateNoOp() + public void testAggregateNoOp() { // Test that aggregates run just fine when the input field does not exist StringLastVectorAggregator aggregator = new StringLastVectorAggregator(null, selector, 10); @@ -383,7 +384,7 @@ public void aggregateNoOp() } @Test - public void aggregateBatchNoOp() + public void testAggregateBatchNoOp() { // Test that aggregates run just fine when the input field does not exist StringLastVectorAggregator aggregator = new StringLastVectorAggregator(null, selector, 10); @@ -394,7 +395,7 @@ public void aggregateBatchNoOp() } @Test - public void aggregateBatchWithoutRows() + public void testAggregateBatchWithoutRows() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -403,12 +404,12 @@ public void aggregateBatchWithoutRows() for (int i = 0; i < positions.length; i++) { Pair result = (Pair) target.get(buf, positions[i] + positionOffset); Assert.assertEquals(times[i], result.lhs.longValue()); - Assert.assertEquals(VALUES[i], result.rhs); + Assert.assertEquals(NullHandling.nullToEmptyIfNeeded(VALUES[i]), result.rhs); } } @Test - public void aggregateBatchWithRows() + public void testAggregateBatchWithRows() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; @@ -418,12 +419,12 @@ public void aggregateBatchWithRows() for (int i = 0; i < positions.length; i++) { Pair result = (Pair) target.get(buf, positions[i] + positionOffset); Assert.assertEquals(times[rows[i]], result.lhs.longValue()); - Assert.assertEquals(VALUES[rows[i]], result.rhs); + Assert.assertEquals(NullHandling.nullToEmptyIfNeeded(VALUES[rows[i]]), result.rhs); } } @Test - public void aggregateSingleDim() + public void testAggregateSingleDim() { targetSingleDim.aggregate(buf, 0, 0, VALUES.length); Pair result = (Pair) targetSingleDim.get(buf, 0); @@ -432,7 +433,7 @@ public void aggregateSingleDim() } @Test - public void aggregateBatchWithoutRowsSingleDim() + public void testAggregateBatchWithoutRowsSingleDim() { int[] positions = new int[]{0, 43, 70}; int positionOffset = 2; @@ -446,7 +447,7 @@ public void aggregateBatchWithoutRowsSingleDim() } @Test - public void aggregateBatchWithRowsSingleDim() + public void testAggregateBatchWithRowsSingleDim() { int[] positions = new int[]{0, 43, 70}; int[] rows = new int[]{3, 2, 0}; diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/post/FinalizingFieldAccessPostAggregatorTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/post/FinalizingFieldAccessPostAggregatorTest.java index ceea41d427bc..f5a19119b84c 100644 --- a/processing/src/test/java/org/apache/druid/query/aggregation/post/FinalizingFieldAccessPostAggregatorTest.java +++ b/processing/src/test/java/org/apache/druid/query/aggregation/post/FinalizingFieldAccessPostAggregatorTest.java @@ -34,7 +34,7 @@ import org.apache.druid.query.aggregation.CountAggregator; import org.apache.druid.query.aggregation.CountAggregatorFactory; import org.apache.druid.query.aggregation.PostAggregator; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; import org.apache.druid.query.groupby.GroupByQueryRunnerTest; import org.apache.druid.query.groupby.ResultRow; import org.apache.druid.query.timeseries.TimeseriesQuery; diff --git a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryQueryToolChestTest.java b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryQueryToolChestTest.java index 0c89afb75e23..d2b599049944 100644 --- a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryQueryToolChestTest.java +++ b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryQueryToolChestTest.java @@ -51,10 +51,10 @@ import org.apache.druid.query.aggregation.SerializablePairLongFloat; import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.post.ConstantPostAggregator; import org.apache.druid.query.aggregation.post.ExpressionPostAggregator; import org.apache.druid.query.dimension.DefaultDimensionSpec; diff --git a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java index 54cdcf129e92..080d5d5d4ba3 100644 --- a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java +++ b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java @@ -76,10 +76,10 @@ import org.apache.druid.query.aggregation.LongMaxAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniqueFinalizingPostAggregator; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; import org.apache.druid.query.aggregation.mean.DoubleMeanAggregatorFactory; import org.apache.druid.query.aggregation.post.ArithmeticPostAggregator; import org.apache.druid.query.aggregation.post.ConstantPostAggregator; diff --git a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java index b672798b1ba6..f1afabe9c75e 100644 --- a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java +++ b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java @@ -36,7 +36,7 @@ import org.apache.druid.query.aggregation.CountAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; import org.apache.druid.query.aggregation.SerializablePairLongString; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.post.ArithmeticPostAggregator; import org.apache.druid.query.aggregation.post.ConstantPostAggregator; import org.apache.druid.query.aggregation.post.FieldAccessPostAggregator; diff --git a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java index aefad5c6dde9..8f0ffadef8a0 100644 --- a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java +++ b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java @@ -54,9 +54,9 @@ import org.apache.druid.query.aggregation.FloatSumAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; import org.apache.druid.query.aggregation.post.FieldAccessPostAggregator; import org.apache.druid.query.dimension.DefaultDimensionSpec; import org.apache.druid.query.expression.TestExprMacroTable; diff --git a/processing/src/test/java/org/apache/druid/query/topn/TopNQueryQueryToolChestTest.java b/processing/src/test/java/org/apache/druid/query/topn/TopNQueryQueryToolChestTest.java index 23d202c72be0..f53fc77cb216 100644 --- a/processing/src/test/java/org/apache/druid/query/topn/TopNQueryQueryToolChestTest.java +++ b/processing/src/test/java/org/apache/druid/query/topn/TopNQueryQueryToolChestTest.java @@ -48,11 +48,11 @@ import org.apache.druid.query.aggregation.SerializablePairLongLong; import org.apache.druid.query.aggregation.SerializablePairLongString; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregator; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.post.ArithmeticPostAggregator; import org.apache.druid.query.aggregation.post.ConstantPostAggregator; import org.apache.druid.query.aggregation.post.FieldAccessPostAggregator; diff --git a/processing/src/test/java/org/apache/druid/query/topn/TopNQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/topn/TopNQueryRunnerTest.java index 4163afb997fa..79adf89fb86b 100644 --- a/processing/src/test/java/org/apache/druid/query/topn/TopNQueryRunnerTest.java +++ b/processing/src/test/java/org/apache/druid/query/topn/TopNQueryRunnerTest.java @@ -59,13 +59,13 @@ import org.apache.druid.query.aggregation.FloatMinAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniqueFinalizingPostAggregator; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; import org.apache.druid.query.aggregation.post.ExpressionPostAggregator; import org.apache.druid.query.context.ResponseContext; import org.apache.druid.query.dimension.DefaultDimensionSpec; diff --git a/processing/src/test/java/org/apache/druid/query/topn/UnnestTopNQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/topn/UnnestTopNQueryRunnerTest.java index ba0025490fa1..cb4ee3b942b1 100644 --- a/processing/src/test/java/org/apache/druid/query/topn/UnnestTopNQueryRunnerTest.java +++ b/processing/src/test/java/org/apache/druid/query/topn/UnnestTopNQueryRunnerTest.java @@ -38,7 +38,7 @@ import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.query.aggregation.DoubleMaxAggregatorFactory; import org.apache.druid.query.aggregation.DoubleMinAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; import org.apache.druid.query.context.ResponseContext; import org.apache.druid.query.expression.TestExprMacroTable; import org.apache.druid.query.ordering.StringComparators; diff --git a/processing/src/test/java/org/apache/druid/segment/IndexMergerRollupTest.java b/processing/src/test/java/org/apache/druid/segment/IndexMergerRollupTest.java index ddea2cbf62b0..c0b8cceb24b6 100644 --- a/processing/src/test/java/org/apache/druid/segment/IndexMergerRollupTest.java +++ b/processing/src/test/java/org/apache/druid/segment/IndexMergerRollupTest.java @@ -23,14 +23,14 @@ import com.google.common.collect.ImmutableMap; import org.apache.druid.data.input.MapBasedInputRow; import org.apache.druid.query.aggregation.AggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.segment.data.IncrementalIndexTest; import org.apache.druid.segment.incremental.IncrementalIndex; import org.apache.druid.segment.writeout.OffHeapMemorySegmentWriteOutMediumFactory; diff --git a/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadPlusTest.java b/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadPlusTest.java index ac501c1524e8..9fb08fb74ff9 100644 --- a/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadPlusTest.java +++ b/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadPlusTest.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.druid.common.config.NullHandling; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.SchemaPayloadPlus; import org.apache.druid.segment.TestHelper; diff --git a/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadTest.java b/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadTest.java index 0878e92d2d8c..dfb352775638 100644 --- a/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadTest.java +++ b/processing/src/test/java/org/apache/druid/segment/column/SchemaPayloadTest.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.druid.common.config.NullHandling; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.TestHelper; import org.junit.Assert; diff --git a/processing/src/test/java/org/apache/druid/segment/column/SegmentSchemaMappingTest.java b/processing/src/test/java/org/apache/druid/segment/column/SegmentSchemaMappingTest.java index 38c9362a11ce..4272e67433cc 100644 --- a/processing/src/test/java/org/apache/druid/segment/column/SegmentSchemaMappingTest.java +++ b/processing/src/test/java/org/apache/druid/segment/column/SegmentSchemaMappingTest.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.druid.common.config.NullHandling; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.SchemaPayloadPlus; import org.apache.druid.segment.SegmentMetadata; diff --git a/server/src/test/java/org/apache/druid/segment/metadata/FingerprintGeneratorTest.java b/server/src/test/java/org/apache/druid/segment/metadata/FingerprintGeneratorTest.java index 3d35691c7fb4..093585508029 100644 --- a/server/src/test/java/org/apache/druid/segment/metadata/FingerprintGeneratorTest.java +++ b/server/src/test/java/org/apache/druid/segment/metadata/FingerprintGeneratorTest.java @@ -22,7 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.druid.common.config.NullHandling; import org.apache.druid.query.aggregation.AggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.TestHelper; import org.apache.druid.segment.column.ColumnType; diff --git a/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaBackFillQueueTest.java b/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaBackFillQueueTest.java index e014c21e961b..238b5acc5442 100644 --- a/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaBackFillQueueTest.java +++ b/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaBackFillQueueTest.java @@ -28,7 +28,7 @@ import org.apache.druid.java.util.common.concurrent.ScheduledExecutors; import org.apache.druid.metadata.TestDerbyConnector; import org.apache.druid.query.aggregation.AggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.TestHelper; import org.apache.druid.segment.column.ColumnType; diff --git a/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaManagerTest.java b/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaManagerTest.java index a79b89f79b39..ed6a567644d4 100644 --- a/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaManagerTest.java +++ b/server/src/test/java/org/apache/druid/segment/metadata/SegmentSchemaManagerTest.java @@ -28,7 +28,7 @@ import org.apache.druid.metadata.MetadataStorageTablesConfig; import org.apache.druid.metadata.TestDerbyConnector; import org.apache.druid.query.aggregation.AggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; import org.apache.druid.segment.SchemaPayload; import org.apache.druid.segment.SchemaPayloadPlus; import org.apache.druid.segment.TestHelper; diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/aggregation/builtin/EarliestLatestAnySqlAggregator.java b/sql/src/main/java/org/apache/druid/sql/calcite/aggregation/builtin/EarliestLatestAnySqlAggregator.java index b47985ea95a9..73209a76a987 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/aggregation/builtin/EarliestLatestAnySqlAggregator.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/aggregation/builtin/EarliestLatestAnySqlAggregator.java @@ -51,14 +51,14 @@ import org.apache.druid.query.aggregation.any.FloatAnyAggregatorFactory; import org.apache.druid.query.aggregation.any.LongAnyAggregatorFactory; import org.apache.druid.query.aggregation.any.StringAnyAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.post.FinalizingFieldAccessPostAggregator; import org.apache.druid.segment.column.ColumnHolder; import org.apache.druid.segment.column.ColumnType; diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java index 661785cb9db5..ba0ce0539e5c 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java @@ -65,16 +65,16 @@ import org.apache.druid.query.aggregation.any.LongAnyAggregatorFactory; import org.apache.druid.query.aggregation.any.StringAnyAggregatorFactory; import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.FloatFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.FloatFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniqueFinalizingPostAggregator; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; import org.apache.druid.query.aggregation.post.ArithmeticPostAggregator; import org.apache.druid.query.aggregation.post.FieldAccessPostAggregator; import org.apache.druid.query.aggregation.post.FinalizingFieldAccessPostAggregator; diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSimpleQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSimpleQueryTest.java index 6fe2205a7ae0..3d7d2a2de33e 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSimpleQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteSimpleQueryTest.java @@ -24,8 +24,8 @@ import org.apache.druid.java.util.common.Intervals; import org.apache.druid.java.util.common.granularity.Granularities; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; -import org.apache.druid.query.aggregation.first.StringFirstAggregatorFactory; -import org.apache.druid.query.aggregation.last.StringLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.StringFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.StringLastAggregatorFactory; import org.apache.druid.query.dimension.DefaultDimensionSpec; import org.apache.druid.query.filter.LikeDimFilter; import org.apache.druid.query.groupby.GroupByQuery; diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java b/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java index f1aba574448a..c914532a3b90 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/util/TestDataBuilder.java @@ -49,12 +49,12 @@ import org.apache.druid.query.aggregation.DoubleSumAggregatorFactory; import org.apache.druid.query.aggregation.FloatSumAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; -import org.apache.druid.query.aggregation.first.DoubleFirstAggregatorFactory; -import org.apache.druid.query.aggregation.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.DoubleFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.first.LongFirstAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.DoubleLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.FloatLastAggregatorFactory; +import org.apache.druid.query.aggregation.firstlast.last.LongLastAggregatorFactory; import org.apache.druid.query.aggregation.hyperloglog.HyperUniquesAggregatorFactory; -import org.apache.druid.query.aggregation.last.DoubleLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.FloatLastAggregatorFactory; -import org.apache.druid.query.aggregation.last.LongLastAggregatorFactory; import org.apache.druid.query.groupby.GroupByQueryConfig; import org.apache.druid.query.lookup.LookupExtractorFactoryContainerProvider; import org.apache.druid.segment.IndexBuilder;