use of com.facebook.presto.spi.function.TypeParameter in project presto by prestodb.
the class ArrayRemoveFunction method remove.
@TypeParameter("E")
@SqlType("array(E)")
public static Block remove(@OperatorDependency(operator = EQUAL, returnType = StandardTypes.BOOLEAN, argumentTypes = { "E", "E" }) MethodHandle equalsFunction, @TypeParameter("E") Type type, @SqlType("array(E)") Block array, @SqlType("E") Object value) {
int sizeAfterRemove = 0;
List<Integer> positions = new ArrayList<>();
for (int i = 0; i < array.getPositionCount(); i++) {
Object element = readNativeValue(type, array, i);
try {
if (element == null || !(boolean) equalsFunction.invoke(element, value)) {
positions.add(i);
sizeAfterRemove += array.getRegionSizeInBytes(i, 1);
}
} catch (Throwable t) {
Throwables.propagateIfInstanceOf(t, Error.class);
Throwables.propagateIfInstanceOf(t, PrestoException.class);
throw new PrestoException(GENERIC_INTERNAL_ERROR, t);
}
}
if (array.getPositionCount() == positions.size()) {
return array;
}
int entrySize = 0;
if (!positions.isEmpty()) {
entrySize = (int) Math.ceil(sizeAfterRemove / (double) positions.size());
}
BlockBuilder blockBuilder = type.createBlockBuilder(new BlockBuilderStatus(), positions.size(), entrySize);
for (int position : positions) {
type.appendTo(array, position, blockBuilder);
}
return blockBuilder.build();
}
use of com.facebook.presto.spi.function.TypeParameter in project presto by prestodb.
the class ArrayReverseFunction method reverse.
@TypeParameter("E")
@SqlType("array(E)")
public Block reverse(@TypeParameter("E") Type type, @SqlType("array(E)") Block block) {
int arrayLength = block.getPositionCount();
if (arrayLength < 2) {
return block;
}
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
for (int i = arrayLength - 1; i >= 0; i--) {
type.appendTo(block, i, blockBuilder);
}
pageBuilder.declarePositions(arrayLength);
return blockBuilder.getRegion(blockBuilder.getPositionCount() - arrayLength, arrayLength);
}
use of com.facebook.presto.spi.function.TypeParameter in project presto by prestodb.
the class ArrayShuffleFunction method shuffle.
@TypeParameter("E")
@SqlType("array(E)")
public Block shuffle(@TypeParameter("E") Type type, @SqlType("array(E)") Block block) {
int length = block.getPositionCount();
if (positions.length < length) {
positions = new int[length];
}
for (int i = 0; i < length; i++) {
positions[i] = i;
}
// Randomly swap a pair of positions
for (int i = length - 1; i > 0; i--) {
int index = ThreadLocalRandom.current().nextInt(i + 1);
int swap = positions[i];
positions[i] = positions[index];
positions[index] = swap;
}
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
for (int i = 0; i < length; i++) {
type.appendTo(block, positions[i], blockBuilder);
}
pageBuilder.declarePositions(length);
return blockBuilder.getRegion(blockBuilder.getPositionCount() - length, length);
}
use of com.facebook.presto.spi.function.TypeParameter in project presto by prestodb.
the class ArraySortFunction method sort.
@TypeParameter("E")
@SqlType("array(E)")
public Block sort(@OperatorDependency(operator = LESS_THAN, returnType = StandardTypes.BOOLEAN, argumentTypes = { "E", "E" }) MethodHandle lessThanFunction, @TypeParameter("E") Type type, @SqlType("array(E)") Block block) {
int arrayLength = block.getPositionCount();
if (positions.size() < arrayLength) {
positions = Ints.asList(new int[arrayLength]);
}
for (int i = 0; i < arrayLength; i++) {
positions.set(i, i);
}
Collections.sort(positions.subList(0, arrayLength), new Comparator<Integer>() {
@Override
public int compare(Integer p1, Integer p2) {
boolean nullLeft = block.isNull(p1);
boolean nullRight = block.isNull(p2);
if (nullLeft && nullRight) {
return 0;
}
if (nullLeft) {
return 1;
}
if (nullRight) {
return -1;
}
//TODO: This could be quite slow, it should use parametric equals
return type.compareTo(block, p1, block, p2);
}
});
if (pageBuilder.isFull()) {
pageBuilder.reset();
}
BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
for (int i = 0; i < arrayLength; i++) {
type.appendTo(block, positions.get(i), blockBuilder);
}
pageBuilder.declarePositions(arrayLength);
return blockBuilder.getRegion(blockBuilder.getPositionCount() - arrayLength, arrayLength);
}
Aggregations