}
private void generateCompareTo(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> sortTypes, List<Integer> sortChannels, List<SortOrder> sortOrders)
{
CompilerContext context = new CompilerContext(BOOTSTRAP_METHOD);
MethodDefinition compareToMethod = classDefinition.declareMethod(context,
a(PUBLIC),
"compareTo",
type(int.class),
arg("pagesIndex", PagesIndex.class),
arg("leftPosition", int.class),
arg("rightPosition", int.class));
Variable valueAddresses = context.declareVariable(LongArrayList.class, "valueAddresses");
compareToMethod
.getBody()
.comment("LongArrayList valueAddresses = pagesIndex.valueAddresses")
.append(valueAddresses.set(context.getVariable("pagesIndex").invoke("getValueAddresses", LongArrayList.class)));
Variable leftPageAddress = context.declareVariable(long.class, "leftPageAddress");
compareToMethod
.getBody()
.comment("long leftPageAddress = valueAddresses.getLong(leftPosition)")
.append(leftPageAddress.set(valueAddresses.invoke("getLong", long.class, context.getVariable("leftPosition"))));
Variable leftBlockIndex = context.declareVariable(int.class, "leftBlockIndex");
compareToMethod
.getBody()
.comment("int leftBlockIndex = decodeSliceIndex(leftPageAddress)")
.append(leftBlockIndex.set(invokeStatic(SyntheticAddress.class, "decodeSliceIndex", int.class, leftPageAddress)));
Variable leftBlockPosition = context.declareVariable(int.class, "leftBlockPosition");
compareToMethod
.getBody()
.comment("int leftBlockPosition = decodePosition(leftPageAddress)")
.append(leftBlockPosition.set(invokeStatic(SyntheticAddress.class, "decodePosition", int.class, leftPageAddress)));
Variable rightPageAddress = context.declareVariable(long.class, "rightPageAddress");
compareToMethod
.getBody()
.comment("long rightPageAddress = valueAddresses.getLong(rightPosition);")
.append(rightPageAddress.set(valueAddresses.invoke("getLong", long.class, context.getVariable("rightPosition"))));
Variable rightBlockIndex = context.declareVariable(int.class, "rightBlockIndex");
compareToMethod
.getBody()
.comment("int rightBlockIndex = decodeSliceIndex(rightPageAddress)")
.append(rightBlockIndex.set(invokeStatic(SyntheticAddress.class, "decodeSliceIndex", int.class, rightPageAddress)));
Variable rightBlockPosition = context.declareVariable(int.class, "rightBlockPosition");
compareToMethod
.getBody()
.comment("int rightBlockPosition = decodePosition(rightPageAddress)")
.append(rightBlockPosition.set(invokeStatic(SyntheticAddress.class, "decodePosition", int.class, rightPageAddress)));
for (int i = 0; i < sortChannels.size(); i++) {
int sortChannel = sortChannels.get(i);
SortOrder sortOrder = sortOrders.get(i);
Block block = new Block(context)
.setDescription("compare channel " + sortChannel + " " + sortOrder);
Type sortType = sortTypes.get(i);
ByteCodeExpression leftBlock = context.getVariable("pagesIndex")
.invoke("getChannel", ObjectArrayList.class, constantInt(sortChannel))
.invoke("get", Object.class, leftBlockIndex)
.cast(com.facebook.presto.spi.block.Block.class);
ByteCodeExpression rightBlock = context.getVariable("pagesIndex")
.invoke("getChannel", ObjectArrayList.class, constantInt(sortChannel))
.invoke("get", Object.class, rightBlockIndex)
.cast(com.facebook.presto.spi.block.Block.class);
block.append(getStatic(SortOrder.class, sortOrder.name())
.invoke("compareBlockValue",
int.class,
ImmutableList.of(Type.class, com.facebook.presto.spi.block.Block.class, int.class, com.facebook.presto.spi.block.Block.class, int.class),
constantType(context, callSiteBinder, sortType),
leftBlock,
leftBlockPosition,
rightBlock,
rightBlockPosition));
LabelNode equal = new LabelNode("equal");
block.comment("if (compare != 0) return compare")
.dup()
.ifZeroGoto(equal)
.retInt()
.visitLabel(equal)
.pop(int.class);
compareToMethod.getBody().append(block);
}
// values are equal
compareToMethod.getBody()
.push(0)
.retInt();
}