use of com.facebook.presto.operator.JoinProbe in project presto by prestodb.
the class TestJoinProbeCompiler method testSingleChannel.
@Test(dataProvider = "hashEnabledValues")
public void testSingleChannel(boolean hashEnabled) throws Exception {
taskContext.addPipelineContext(0, true, true).addDriverContext();
ImmutableList<Type> types = ImmutableList.of(VARCHAR, DOUBLE);
ImmutableList<Type> outputTypes = ImmutableList.of(VARCHAR);
List<Integer> outputChannels = ImmutableList.of(0);
LookupSourceSupplierFactory lookupSourceSupplierFactory = joinCompiler.compileLookupSourceFactory(types, Ints.asList(0));
// crate hash strategy with a single channel blocks -- make sure there is some overlap in values
List<Block> varcharChannel = ImmutableList.of(BlockAssertions.createStringSequenceBlock(10, 20), BlockAssertions.createStringSequenceBlock(20, 30), BlockAssertions.createStringSequenceBlock(15, 25));
List<Block> extraUnusedDoubleChannel = ImmutableList.of(BlockAssertions.createDoubleSequenceBlock(10, 20), BlockAssertions.createDoubleSequenceBlock(20, 30), BlockAssertions.createDoubleSequenceBlock(15, 25));
LongArrayList addresses = new LongArrayList();
for (int blockIndex = 0; blockIndex < varcharChannel.size(); blockIndex++) {
Block block = varcharChannel.get(blockIndex);
for (int positionIndex = 0; positionIndex < block.getPositionCount(); positionIndex++) {
addresses.add(encodeSyntheticAddress(blockIndex, positionIndex));
}
}
Optional<Integer> hashChannel = Optional.empty();
List<List<Block>> channels = ImmutableList.of(varcharChannel, extraUnusedDoubleChannel);
if (hashEnabled) {
ImmutableList.Builder<Block> hashChannelBuilder = ImmutableList.builder();
for (Block block : varcharChannel) {
hashChannelBuilder.add(TypeUtils.getHashBlock(ImmutableList.<Type>of(VARCHAR), block));
}
types = ImmutableList.of(VARCHAR, DOUBLE, BigintType.BIGINT);
hashChannel = Optional.of(2);
channels = ImmutableList.of(varcharChannel, extraUnusedDoubleChannel, hashChannelBuilder.build());
outputChannels = ImmutableList.of(0, 2);
outputTypes = ImmutableList.of(VARCHAR, BigintType.BIGINT);
}
LookupSource lookupSource = lookupSourceSupplierFactory.createLookupSourceSupplier(taskContext.getSession().toConnectorSession(), addresses, channels, hashChannel, Optional.empty()).get();
JoinProbeCompiler joinProbeCompiler = new JoinProbeCompiler();
JoinProbeFactory probeFactory = joinProbeCompiler.internalCompileJoinProbe(types, outputChannels, Ints.asList(0), hashChannel);
Page page = SequencePageBuilder.createSequencePage(types, 10, 10, 10);
Page outputPage = new Page(page.getBlock(0));
if (hashEnabled) {
page = new Page(page.getBlock(0), page.getBlock(1), TypeUtils.getHashBlock(ImmutableList.of(VARCHAR), page.getBlock(0)));
outputPage = new Page(page.getBlock(0), page.getBlock(2));
}
JoinProbe joinProbe = probeFactory.createJoinProbe(lookupSource, page);
// verify channel count
assertEquals(joinProbe.getOutputChannelCount(), outputChannels.size());
PageBuilder pageBuilder = new PageBuilder(outputTypes);
for (int position = 0; position < page.getPositionCount(); position++) {
assertTrue(joinProbe.advanceNextPosition());
pageBuilder.declarePosition();
joinProbe.appendTo(pageBuilder);
assertEquals(joinProbe.getCurrentJoinPosition(), lookupSource.getJoinPosition(position, page, page));
}
assertFalse(joinProbe.advanceNextPosition());
assertPageEquals(outputTypes, pageBuilder.build(), outputPage);
}
use of com.facebook.presto.operator.JoinProbe in project presto by prestodb.
the class JoinProbeCompiler method internalCompileJoinOperatorFactory.
@VisibleForTesting
public HashJoinOperatorFactoryFactory internalCompileJoinOperatorFactory(List<Type> types, List<Integer> probeOutputChannels, List<Integer> probeJoinChannel, Optional<Integer> probeHashChannel) {
Class<? extends JoinProbe> joinProbeClass = compileJoinProbe(types, probeOutputChannels, probeJoinChannel, probeHashChannel);
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("JoinProbeFactory"), type(Object.class), type(JoinProbeFactory.class));
classDefinition.declareDefaultConstructor(a(PUBLIC));
Parameter lookupSource = arg("lookupSource", LookupSource.class);
Parameter page = arg("page", Page.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "createJoinProbe", type(JoinProbe.class), lookupSource, page);
method.getBody().newObject(joinProbeClass).dup().append(lookupSource).append(page).invokeConstructor(joinProbeClass, LookupSource.class, Page.class).retObject();
DynamicClassLoader classLoader = new DynamicClassLoader(joinProbeClass.getClassLoader());
JoinProbeFactory joinProbeFactory;
if (probeJoinChannel.isEmpty()) {
// see comment in PagesIndex#createLookupSource
joinProbeFactory = new SimpleJoinProbe.SimpleJoinProbeFactory(types, probeOutputChannels, probeJoinChannel, probeHashChannel);
} else {
Class<? extends JoinProbeFactory> joinProbeFactoryClass = defineClass(classDefinition, JoinProbeFactory.class, classLoader);
try {
joinProbeFactory = joinProbeFactoryClass.newInstance();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
Class<? extends OperatorFactory> operatorFactoryClass = IsolatedClass.isolateClass(classLoader, OperatorFactory.class, LookupJoinOperatorFactory.class, LookupJoinOperator.class);
return new HashJoinOperatorFactoryFactory(joinProbeFactory, operatorFactoryClass);
}
use of com.facebook.presto.operator.JoinProbe in project presto by prestodb.
the class JoinProbeCompiler method compileJoinProbe.
private Class<? extends JoinProbe> compileJoinProbe(List<Type> types, List<Integer> probeOutputChannels, List<Integer> probeChannels, Optional<Integer> probeHashChannel) {
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("JoinProbe"), type(Object.class), type(JoinProbe.class));
// declare fields
FieldDefinition lookupSourceField = classDefinition.declareField(a(PRIVATE, FINAL), "lookupSource", LookupSource.class);
FieldDefinition positionCountField = classDefinition.declareField(a(PRIVATE, FINAL), "positionCount", int.class);
List<FieldDefinition> blockFields = new ArrayList<>();
for (int i = 0; i < types.size(); i++) {
FieldDefinition channelField = classDefinition.declareField(a(PRIVATE, FINAL), "block_" + i, Block.class);
blockFields.add(channelField);
}
List<FieldDefinition> probeBlockFields = new ArrayList<>();
for (int i = 0; i < probeChannels.size(); i++) {
FieldDefinition channelField = classDefinition.declareField(a(PRIVATE, FINAL), "probeBlock_" + i, Block.class);
probeBlockFields.add(channelField);
}
FieldDefinition probeBlocksArrayField = classDefinition.declareField(a(PRIVATE, FINAL), "probeBlocks", Block[].class);
FieldDefinition probePageField = classDefinition.declareField(a(PRIVATE, FINAL), "probePage", Page.class);
FieldDefinition pageField = classDefinition.declareField(a(PRIVATE, FINAL), "page", Page.class);
FieldDefinition positionField = classDefinition.declareField(a(PRIVATE), "position", int.class);
FieldDefinition probeHashBlockField = classDefinition.declareField(a(PRIVATE, FINAL), "probeHashBlock", Block.class);
generateConstructor(classDefinition, probeChannels, probeHashChannel, lookupSourceField, blockFields, probeBlockFields, probeBlocksArrayField, probePageField, pageField, probeHashBlockField, positionField, positionCountField);
generateGetChannelCountMethod(classDefinition, probeOutputChannels.size());
generateAppendToMethod(classDefinition, callSiteBinder, types, probeOutputChannels, blockFields, positionField);
generateAdvanceNextPosition(classDefinition, positionField, positionCountField);
generateGetCurrentJoinPosition(classDefinition, callSiteBinder, lookupSourceField, probePageField, pageField, probeHashChannel, probeHashBlockField, positionField);
generateCurrentRowContainsNull(classDefinition, probeBlockFields, positionField);
generateGetPosition(classDefinition, positionField);
generateGetPage(classDefinition, pageField);
return defineClass(classDefinition, JoinProbe.class, callSiteBinder.getBindings(), getClass().getClassLoader());
}
Aggregations