use of io.trino.spi.Page in project trino by trinodb.
the class GenericPartitioningSpiller method flush.
private synchronized ListenableFuture<Void> flush(int partition) {
PageBuilder pageBuilder = pageBuilders.get(partition);
if (pageBuilder.isEmpty()) {
return immediateVoidFuture();
}
Page page = pageBuilder.build();
pageBuilder.reset();
return getSpiller(partition).spill(page);
}
use of io.trino.spi.Page in project trino by trinodb.
the class Query method removePagesFromExchange.
private synchronized QueryResultRows removePagesFromExchange(QueryInfo queryInfo, long targetResultBytes) {
// For queries with no output, return a fake boolean result for clients that require it.
if ((queryInfo.getState() == QueryState.FINISHED) && queryInfo.getOutputStage().isEmpty()) {
return queryResultRowsBuilder(session).withSingleBooleanValue(createColumn("result", BooleanType.BOOLEAN), true).build();
}
// Remove as many pages as possible from the exchange until just greater than DESIRED_RESULT_BYTES
// NOTE: it is critical that query results are created for the pages removed from the exchange
// client while holding the lock because the query may transition to the finished state when the
// last page is removed. If another thread observes this state before the response is cached
// the pages will be lost.
QueryResultRows.Builder resultBuilder = queryResultRowsBuilder(session).withExceptionConsumer(this::handleSerializationException).withColumnsAndTypes(columns, types);
try (PagesSerde.PagesSerdeContext context = serde.newContext()) {
long bytes = 0;
while (bytes < targetResultBytes) {
Slice serializedPage = exchangeClient.pollPage();
if (serializedPage == null) {
break;
}
Page page = serde.deserialize(context, serializedPage);
bytes += page.getLogicalSizeInBytes();
resultBuilder.addPage(page);
}
if (exchangeClient.isFinished()) {
exchangeClient.close();
}
} catch (Throwable cause) {
queryManager.failQuery(queryId, cause);
}
return resultBuilder.build();
}
use of io.trino.spi.Page in project trino by trinodb.
the class TestSpatialPartitioningInternalAggregation method test.
@Test(dataProvider = "partitionCount")
public void test(int partitionCount) {
TestingAggregationFunction function = getFunction();
List<OGCGeometry> geometries = makeGeometries();
Block geometryBlock = makeGeometryBlock(geometries);
Block partitionCountBlock = BlockAssertions.createRLEBlock(partitionCount, geometries.size());
Rectangle expectedExtent = new Rectangle(-10, -10, Math.nextUp(10.0), Math.nextUp(10.0));
String expectedValue = getSpatialPartitioning(expectedExtent, geometries, partitionCount);
AggregatorFactory aggregatorFactory = function.createAggregatorFactory(SINGLE, Ints.asList(0, 1), OptionalInt.empty());
Page page = new Page(geometryBlock, partitionCountBlock);
Aggregator aggregator = aggregatorFactory.createAggregator();
aggregator.processPage(page);
String aggregation = (String) BlockAssertions.getOnlyValue(function.getFinalType(), getFinalBlock(function.getFinalType(), aggregator));
assertEquals(aggregation, expectedValue);
GroupedAggregator groupedAggregator = aggregatorFactory.createGroupedAggregator();
groupedAggregator.processPage(createGroupByIdBlock(0, page.getPositionCount()), page);
String groupValue = (String) getGroupValue(function.getFinalType(), groupedAggregator, 0);
assertEquals(groupValue, expectedValue);
}
use of io.trino.spi.Page in project trino by trinodb.
the class TestSpatialJoinOperator method testYield.
@Test
public void testYield() {
// create a filter function that yields for every probe match
// verify we will yield #match times totally
TaskContext taskContext = createTaskContext();
DriverContext driverContext = taskContext.addPipelineContext(0, true, true, false).addDriverContext();
// force a yield for every match
AtomicInteger filterFunctionCalls = new AtomicInteger();
InternalJoinFilterFunction filterFunction = new TestInternalJoinFilterFunction(((leftPosition, leftPage, rightPosition, rightPage) -> {
filterFunctionCalls.incrementAndGet();
driverContext.getYieldSignal().forceYieldForTesting();
return true;
}));
RowPagesBuilder buildPages = rowPagesBuilder(ImmutableList.of(GEOMETRY, VARCHAR)).row(POLYGON_A, "A").pageBreak().row(POLYGON_B, "B");
PagesSpatialIndexFactory pagesSpatialIndexFactory = buildIndex(driverContext, (build, probe, r) -> build.contains(probe), Optional.empty(), Optional.of(filterFunction), buildPages);
// 10 points in polygon A (x0...x9)
// 10 points in polygons A and B (y0...y9)
// 10 points in polygon B (z0...z9)
// 40 total matches
RowPagesBuilder probePages = rowPagesBuilder(ImmutableList.of(GEOMETRY, VARCHAR));
for (int i = 0; i < 10; i++) {
probePages.row(stPoint(1 + 0.1 * i, 1 + 0.1 * i), "x" + i);
}
for (int i = 0; i < 10; i++) {
probePages.row(stPoint(4.5 + 0.01 * i, 4.5 + 0.01 * i), "y" + i);
}
for (int i = 0; i < 10; i++) {
probePages.row(stPoint(6 + 0.1 * i, 6 + 0.1 * i), "z" + i);
}
List<Page> probeInput = probePages.build();
OperatorFactory joinOperatorFactory = new SpatialJoinOperatorFactory(2, new PlanNodeId("test"), INNER, probePages.getTypes(), Ints.asList(1), 0, Optional.empty(), pagesSpatialIndexFactory);
Operator operator = joinOperatorFactory.createOperator(driverContext);
assertTrue(operator.needsInput());
operator.addInput(probeInput.get(0));
operator.finish();
// we will yield 40 times due to filterFunction
for (int i = 0; i < 40; i++) {
driverContext.getYieldSignal().setWithDelay(5 * SECONDS.toNanos(1), driverContext.getYieldExecutor());
assertNull(operator.getOutput());
assertEquals(filterFunctionCalls.get(), i + 1, "Expected join to stop processing (yield) after calling filter function once");
driverContext.getYieldSignal().reset();
}
// delayed yield is not going to prevent operator from producing a page now (yield won't be forced because filter function won't be called anymore)
driverContext.getYieldSignal().setWithDelay(5 * SECONDS.toNanos(1), driverContext.getYieldExecutor());
Page output = operator.getOutput();
assertNotNull(output);
// make sure we have 40 matches
assertEquals(output.getPositionCount(), 40);
}
use of io.trino.spi.Page in project trino by trinodb.
the class HiveUpdatablePageSource method updateRows.
@Override
public void updateRows(Page page, List<Integer> columnValueAndRowIdChannels) {
int positionCount = page.getPositionCount();
// should be filtered out by engine
verify(positionCount > 0, "Unexpected empty page");
HiveUpdateProcessor updateProcessor = transaction.getUpdateProcessor().orElseThrow(() -> new IllegalArgumentException("updateProcessor not present"));
ColumnarRow acidBlock = updateProcessor.getAcidBlock(page, columnValueAndRowIdChannels);
int fieldCount = acidBlock.getFieldCount();
checkArgument(fieldCount == 3 || fieldCount == 4, "The rowId block for UPDATE should have 3 or 4 children, but has %s", fieldCount);
deleteRowsInternal(acidBlock);
Block mergedColumnsBlock = updateProcessor.createMergedColumnsBlock(page, columnValueAndRowIdChannels);
Block currentTransactionBlock = RunLengthEncodedBlock.create(BIGINT, writeId, positionCount);
Block[] blockArray = { new RunLengthEncodedBlock(INSERT_OPERATION_BLOCK, positionCount), currentTransactionBlock, acidBlock.getField(BUCKET_CHANNEL), createRowIdBlock(positionCount), currentTransactionBlock, mergedColumnsBlock };
Page insertPage = new Page(blockArray);
lazyInitializeInsertFileWriter();
insertFileWriter.orElseThrow(() -> new IllegalArgumentException("insertFileWriter not present")).appendRows(insertPage);
}
Aggregations