use of com.facebook.presto.operator.aggregation.TypedSet in project presto by prestodb.
the class MapTransformKeyFunction method transform.
public static Block transform(Type keyType, Type transformedKeyType, Type valueType, ConnectorSession session, Block block, MethodHandle function) {
int positionCount = block.getPositionCount();
BlockBuilder resultBuilder = new InterleavedBlockBuilder(ImmutableList.of(transformedKeyType, valueType), new BlockBuilderStatus(), positionCount);
TypedSet typedSet = new TypedSet(transformedKeyType, positionCount / 2);
for (int position = 0; position < positionCount; position += 2) {
Object key = readNativeValue(keyType, block, position);
Object value = readNativeValue(valueType, block, position + 1);
Object transformedKey;
try {
transformedKey = function.invoke(key, value);
} catch (Throwable throwable) {
throw Throwables.propagate(throwable);
}
if (transformedKey == null) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "map key cannot be null");
}
writeNativeValue(transformedKeyType, resultBuilder, transformedKey);
valueType.appendTo(block, position + 1, resultBuilder);
if (typedSet.contains(resultBuilder, position)) {
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, format("Duplicate keys (%s) are not allowed", transformedKeyType.getObjectValue(session, resultBuilder, position)));
}
typedSet.add(resultBuilder, position);
}
return resultBuilder.build();
}
use of com.facebook.presto.operator.aggregation.TypedSet in project presto by prestodb.
the class MapFromEntriesFunction method mapFromEntries.
@TypeParameter("K")
@TypeParameter("V")
@SqlType("map(K,V)")
@SqlNullable
public Block mapFromEntries(@TypeParameter("map(K,V)") MapType mapType, SqlFunctionProperties properties, @SqlType("array(row(K,V))") Block block) {
Type keyType = mapType.getKeyType();
Type valueType = mapType.getValueType();
RowType rowType = RowType.anonymous(ImmutableList.of(keyType, valueType));
int entryCount = block.getPositionCount();
BlockBuilder mapBlockBuilder = mapType.createBlockBuilder(null, block.getPositionCount());
BlockBuilder resultBuilder = mapBlockBuilder.beginBlockEntry();
TypedSet uniqueKeys = new TypedSet(keyType, entryCount, "map_from_entries");
for (int i = 0; i < entryCount; i++) {
if (block.isNull(i)) {
mapBlockBuilder.closeEntry();
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "map entry cannot be null");
}
Block rowBlock = rowType.getObject(block, i);
if (rowBlock.isNull(0)) {
mapBlockBuilder.closeEntry();
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "map key cannot be null");
}
if (uniqueKeys.contains(rowBlock, 0)) {
mapBlockBuilder.closeEntry();
throw new PrestoException(INVALID_FUNCTION_ARGUMENT, format("Duplicate keys (%s) are not allowed", keyType.getObjectValue(properties, rowBlock, 0)));
}
uniqueKeys.add(rowBlock, 0);
keyType.appendTo(rowBlock, 0, resultBuilder);
valueType.appendTo(rowBlock, 1, resultBuilder);
}
mapBlockBuilder.closeEntry();
return mapType.getObject(mapBlockBuilder, mapBlockBuilder.getPositionCount() - 1);
}
use of com.facebook.presto.operator.aggregation.TypedSet in project presto by prestodb.
the class ArraysOverlapFunction method arraysOverlapSetBased.
private static Boolean arraysOverlapSetBased(Type type, Block leftArray, Block rightArray) {
int leftPositionCount = leftArray.getPositionCount();
int rightPositionCount = rightArray.getPositionCount();
if (leftPositionCount == 0 || rightPositionCount == 0) {
return false;
}
Block lookArray = leftArray;
Block itrArray = rightArray;
if (leftPositionCount > rightPositionCount) {
lookArray = rightArray;
itrArray = leftArray;
}
boolean itrArrHasNull = false;
TypedSet typedSet = new TypedSet(type, lookArray.getPositionCount(), "arraysOverlap");
for (int i = 0; i < lookArray.getPositionCount(); i++) {
typedSet.add(lookArray, i);
}
for (int i = 0; i < itrArray.getPositionCount(); i++) {
if (itrArray.isNull(i)) {
itrArrHasNull = true;
continue;
}
if (typedSet.contains(itrArray, i)) {
return true;
}
}
if (itrArrHasNull || typedSet.isContainNullElements()) {
return null;
}
return false;
}
use of com.facebook.presto.operator.aggregation.TypedSet in project presto by prestodb.
the class MultimapAggregationFunction method output.
public static void output(Type keyType, Type valueType, MultimapAggregationState state, BlockBuilder out) {
if (state.isEmpty()) {
out.appendNull();
} else {
// TODO: Avoid copy value block associated with the same key by using strategy similar to multimap_from_entries
ObjectBigArray<BlockBuilder> valueArrayBlockBuilders = new ObjectBigArray<>();
valueArrayBlockBuilders.ensureCapacity(state.getEntryCount());
BlockBuilder distinctKeyBlockBuilder = keyType.createBlockBuilder(null, state.getEntryCount(), expectedValueSize(keyType, 100));
TypedSet keySet = new TypedSet(keyType, state.getEntryCount(), MultimapAggregationFunction.NAME);
state.forEach((key, value, keyValueIndex) -> {
// Merge values of the same key into an array
if (!keySet.contains(key, keyValueIndex)) {
keySet.add(key, keyValueIndex);
keyType.appendTo(key, keyValueIndex, distinctKeyBlockBuilder);
BlockBuilder valueArrayBuilder = valueType.createBlockBuilder(null, 10, expectedValueSize(valueType, EXPECTED_ENTRY_SIZE));
valueArrayBlockBuilders.set(keySet.positionOf(key, keyValueIndex), valueArrayBuilder);
}
valueType.appendTo(value, keyValueIndex, valueArrayBlockBuilders.get(keySet.positionOf(key, keyValueIndex)));
});
// Write keys and value arrays into one Block
Type valueArrayType = new ArrayType(valueType);
BlockBuilder multimapBlockBuilder = out.beginBlockEntry();
for (int i = 0; i < distinctKeyBlockBuilder.getPositionCount(); i++) {
keyType.appendTo(distinctKeyBlockBuilder, i, multimapBlockBuilder);
valueArrayType.writeObject(multimapBlockBuilder, valueArrayBlockBuilders.get(i).build());
}
out.closeEntry();
}
}
use of com.facebook.presto.operator.aggregation.TypedSet in project presto by prestodb.
the class BenchmarkArrayDistinct method oldArrayDistinct.
@ScalarFunction
@SqlType("array(varchar)")
public static Block oldArrayDistinct(@SqlType("array(varchar)") Block array) {
if (array.getPositionCount() == 0) {
return array;
}
TypedSet typedSet = new TypedSet(VARCHAR, array.getPositionCount(), "old_array_distinct");
BlockBuilder distinctElementBlockBuilder = VARCHAR.createBlockBuilder(null, array.getPositionCount());
for (int i = 0; i < array.getPositionCount(); i++) {
if (!typedSet.contains(array, i)) {
typedSet.add(array, i);
VARCHAR.appendTo(array, i, distinctElementBlockBuilder);
}
}
return distinctElementBlockBuilder.build();
}
Aggregations