|
@@ -28,15 +28,7 @@ final class ValuesBytesRefAggregators {
|
|
|
if (valuesOrdinal == null) {
|
|
|
return delegate;
|
|
|
}
|
|
|
- BytesRefVector dict = valuesOrdinal.getDictionaryVector();
|
|
|
- final IntVector hashIds;
|
|
|
- BytesRef spare = new BytesRef();
|
|
|
- try (var hashIdsBuilder = values.blockFactory().newIntVectorFixedBuilder(dict.getPositionCount())) {
|
|
|
- for (int p = 0; p < dict.getPositionCount(); p++) {
|
|
|
- hashIdsBuilder.appendInt(Math.toIntExact(BlockHash.hashOrdToGroup(state.bytes.add(dict.getBytesRef(p, spare)))));
|
|
|
- }
|
|
|
- hashIds = hashIdsBuilder.build();
|
|
|
- }
|
|
|
+ final IntVector hashIds = hashDict(state, valuesOrdinal.getDictionaryVector());
|
|
|
IntBlock ordinalIds = valuesOrdinal.getOrdinalsBlock();
|
|
|
return new GroupingAggregatorFunction.AddInput() {
|
|
|
@Override
|
|
@@ -85,17 +77,7 @@ final class ValuesBytesRefAggregators {
|
|
|
|
|
|
@Override
|
|
|
public void add(int positionOffset, IntVector groupIds) {
|
|
|
- for (int groupPosition = 0; groupPosition < groupIds.getPositionCount(); groupPosition++) {
|
|
|
- int groupId = groupIds.getInt(groupPosition);
|
|
|
- if (ordinalIds.isNull(groupPosition + positionOffset)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- int valuesStart = ordinalIds.getFirstValueIndex(groupPosition + positionOffset);
|
|
|
- int valuesEnd = valuesStart + ordinalIds.getValueCount(groupPosition + positionOffset);
|
|
|
- for (int v = valuesStart; v < valuesEnd; v++) {
|
|
|
- state.addValueOrdinal(groupId, hashIds.getInt(ordinalIds.getInt(v)));
|
|
|
- }
|
|
|
- }
|
|
|
+ addOrdinalInputBlock(state, positionOffset, groupIds, ordinalIds, hashIds);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -114,15 +96,7 @@ final class ValuesBytesRefAggregators {
|
|
|
if (valuesOrdinal == null) {
|
|
|
return delegate;
|
|
|
}
|
|
|
- BytesRefVector dict = valuesOrdinal.getDictionaryVector();
|
|
|
- final IntVector hashIds;
|
|
|
- BytesRef spare = new BytesRef();
|
|
|
- try (var hashIdsBuilder = values.blockFactory().newIntVectorFixedBuilder(dict.getPositionCount())) {
|
|
|
- for (int p = 0; p < dict.getPositionCount(); p++) {
|
|
|
- hashIdsBuilder.appendInt(Math.toIntExact(BlockHash.hashOrdToGroup(state.bytes.add(dict.getBytesRef(p, spare)))));
|
|
|
- }
|
|
|
- hashIds = hashIdsBuilder.build();
|
|
|
- }
|
|
|
+ final IntVector hashIds = hashDict(state, valuesOrdinal.getDictionaryVector());
|
|
|
var ordinalIds = valuesOrdinal.getOrdinalsVector();
|
|
|
return new GroupingAggregatorFunction.AddInput() {
|
|
|
@Override
|
|
@@ -157,10 +131,7 @@ final class ValuesBytesRefAggregators {
|
|
|
|
|
|
@Override
|
|
|
public void add(int positionOffset, IntVector groupIds) {
|
|
|
- for (int groupPosition = 0; groupPosition < groupIds.getPositionCount(); groupPosition++) {
|
|
|
- int groupId = groupIds.getInt(groupPosition);
|
|
|
- state.addValueOrdinal(groupId, hashIds.getInt(ordinalIds.getInt(groupPosition + positionOffset)));
|
|
|
- }
|
|
|
+ addOrdinalInputVector(state, positionOffset, groupIds, ordinalIds, hashIds);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -169,4 +140,114 @@ final class ValuesBytesRefAggregators {
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+ static IntVector hashDict(ValuesBytesRefAggregator.GroupingState state, BytesRefVector dict) {
|
|
|
+ BytesRef scratch = new BytesRef();
|
|
|
+ try (var hashIdsBuilder = dict.blockFactory().newIntVectorFixedBuilder(dict.getPositionCount())) {
|
|
|
+ for (int p = 0; p < dict.getPositionCount(); p++) {
|
|
|
+ final long hashId = BlockHash.hashOrdToGroup(state.bytes.add(dict.getBytesRef(p, scratch)));
|
|
|
+ hashIdsBuilder.appendInt(Math.toIntExact(hashId));
|
|
|
+ }
|
|
|
+ return hashIdsBuilder.build();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void addOrdinalInputBlock(
|
|
|
+ ValuesBytesRefAggregator.GroupingState state,
|
|
|
+ int positionOffset,
|
|
|
+ IntVector groupIds,
|
|
|
+ IntBlock ordinalIds,
|
|
|
+ IntVector hashIds
|
|
|
+ ) {
|
|
|
+ for (int p = 0; p < groupIds.getPositionCount(); p++) {
|
|
|
+ final int valuePosition = p + positionOffset;
|
|
|
+ final int groupId = groupIds.getInt(valuePosition);
|
|
|
+ final int start = ordinalIds.getFirstValueIndex(valuePosition);
|
|
|
+ final int end = start + ordinalIds.getValueCount(valuePosition);
|
|
|
+ for (int i = start; i < end; i++) {
|
|
|
+ int ord = ordinalIds.getInt(i);
|
|
|
+ state.addValueOrdinal(groupId, hashIds.getInt(ord));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void addOrdinalInputVector(
|
|
|
+ ValuesBytesRefAggregator.GroupingState state,
|
|
|
+ int positionOffset,
|
|
|
+ IntVector groupIds,
|
|
|
+ IntVector ordinalIds,
|
|
|
+ IntVector hashIds
|
|
|
+ ) {
|
|
|
+ for (int p = 0; p < groupIds.getPositionCount(); p++) {
|
|
|
+ int groupId = groupIds.getInt(p);
|
|
|
+ int ord = ordinalIds.getInt(p + positionOffset);
|
|
|
+ state.addValueOrdinal(groupId, hashIds.getInt(ord));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void combineIntermediateInputValues(
|
|
|
+ ValuesBytesRefAggregator.GroupingState state,
|
|
|
+ int positionOffset,
|
|
|
+ IntVector groupIds,
|
|
|
+ BytesRefBlock values
|
|
|
+ ) {
|
|
|
+ BytesRefVector dict = null;
|
|
|
+ IntBlock ordinals = null;
|
|
|
+ {
|
|
|
+ final OrdinalBytesRefBlock asOrdinals = values.asOrdinals();
|
|
|
+ if (asOrdinals != null) {
|
|
|
+ dict = asOrdinals.getDictionaryVector();
|
|
|
+ ordinals = asOrdinals.getOrdinalsBlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (dict != null && dict.getPositionCount() < groupIds.getPositionCount()) {
|
|
|
+ try (var hashIds = hashDict(state, dict)) {
|
|
|
+ IntVector ordinalsVector = ordinals.asVector();
|
|
|
+ if (ordinalsVector != null) {
|
|
|
+ addOrdinalInputVector(state, positionOffset, groupIds, ordinalsVector, hashIds);
|
|
|
+ } else {
|
|
|
+ addOrdinalInputBlock(state, positionOffset, groupIds, ordinals, hashIds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ final BytesRef scratch = new BytesRef();
|
|
|
+ for (int p = 0; p < groupIds.getPositionCount(); p++) {
|
|
|
+ final int valuePosition = p + positionOffset;
|
|
|
+ final int groupId = groupIds.getInt(valuePosition);
|
|
|
+ final int start = values.getFirstValueIndex(valuePosition);
|
|
|
+ final int end = start + values.getValueCount(valuePosition);
|
|
|
+ for (int i = start; i < end; i++) {
|
|
|
+ state.addValue(groupId, values.getBytesRef(i, scratch));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void combineIntermediateInputValues(
|
|
|
+ ValuesBytesRefAggregator.GroupingState state,
|
|
|
+ int positionOffset,
|
|
|
+ IntBlock groupIds,
|
|
|
+ BytesRefBlock values
|
|
|
+ ) {
|
|
|
+ final BytesRef scratch = new BytesRef();
|
|
|
+ for (int groupPosition = 0; groupPosition < groupIds.getPositionCount(); groupPosition++) {
|
|
|
+ if (groupIds.isNull(groupPosition)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int groupStart = groupIds.getFirstValueIndex(groupPosition);
|
|
|
+ int groupEnd = groupStart + groupIds.getValueCount(groupPosition);
|
|
|
+ for (int g = groupStart; g < groupEnd; g++) {
|
|
|
+ if (values.isNull(groupPosition + positionOffset)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int groupId = groupIds.getInt(g);
|
|
|
+ int valuesStart = values.getFirstValueIndex(groupPosition + positionOffset);
|
|
|
+ int valuesEnd = valuesStart + values.getValueCount(groupPosition + positionOffset);
|
|
|
+ for (int v = valuesStart; v < valuesEnd; v++) {
|
|
|
+ var bytes = values.getBytesRef(v, scratch);
|
|
|
+ state.addValue(groupId, bytes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|