public static Page getHashPage(Page page, List<? extends Type> types, List<Integer> hashChannels) { ImmutableList.Builder<Type> hashTypes = ImmutableList.builder(); Block[] hashBlocks = new Block[hashChannels.size()]; int hashBlockIndex = 0; for (int channel : hashChannels) { hashTypes.add(types.get(channel)); hashBlocks[hashBlockIndex++] = page.getBlock(channel); } return page.appendColumn(getHashBlock(hashTypes.build(), hashBlocks)); }
private int getHashPosition(int position) { int hashPosition = getMaskedHash(hashPosition(type, block, position)); while (true) { if (positionByHash[hashPosition] == EMPTY_SLOT) { return hashPosition; } else if (positionEqualsPosition(type, block, positionByHash[hashPosition], block, position)) { return hashPosition; } hashPosition = getMaskedHash(hashPosition + 1); } }
private boolean onlyCastsUnknown(ApplicableFunction applicableFunction, List<Type> actualParameters) { List<Type> boundTypes = resolveTypes(applicableFunction.getBoundSignature().getArgumentTypes(), typeManager); checkState(actualParameters.size() == boundTypes.size(), "type lists are of different lengths"); for (int i = 0; i < actualParameters.size(); i++) { if (!boundTypes.get(i).equals(actualParameters.get(i)) && actualParameters.get(i) != UNKNOWN) { return false; } } return true; }
ImmutableList.Builder<Block> hashChannelBuilder = ImmutableList.builder(); for (Block block : channel) { hashChannelBuilder.add(TypeUtils.getHashBlock(joinTypes, block)); assertEquals(hashStrategy.hashPosition(leftBlockIndex, leftBlockPosition), hashPosition(VARCHAR, leftBlock, leftBlockPosition)); Block rightBlock = channel.get(rightBlockIndex); for (int rightBlockPosition = 0; rightBlockPosition < rightBlock.getPositionCount(); rightBlockPosition++) { boolean expected = positionEqualsPosition(VARCHAR, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition); assertEquals(hashStrategy.positionEqualsRow(leftBlockIndex, leftBlockPosition, rightBlockPosition, new Page(rightBlock)), expected); assertEquals(hashStrategy.rowEqualsRow(leftBlockPosition, new Page(leftBlock), rightBlockPosition, new Page(rightBlock)), expected); Block rightBlock = channel.get(rightBlockIndex); for (int rightBlockPosition = 0; rightBlockPosition < rightBlock.getPositionCount(); rightBlockPosition++) { boolean expected = positionEqualsPosition(VARCHAR, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition); assertEquals(hashStrategy.positionEqualsRow(leftBlockIndex, leftBlockPosition, rightBlockPosition, new Page(rightBlock)), expected); assertEquals(hashStrategy.rowEqualsRow(leftBlockPosition, new Page(leftBlock), rightBlockPosition, new Page(rightBlock)), expected);
@Override public long hashRow(int position, Page page) { long result = 0; for (int i = 0; i < hashChannels.size(); i++) { int hashChannel = hashChannels.get(i); Type type = types.get(hashChannel); Block block = page.getBlock(i); result = result * 31 + TypeUtils.hashPosition(type, block, position); } return result; }
protected static int compare( RowType rowType, List<MethodHandle> comparisonFunctions, Block leftRow, Block rightRow) { for (int i = 0; i < leftRow.getPositionCount(); i++) { checkElementNotNull(leftRow.isNull(i), "null value at position " + i); checkElementNotNull(rightRow.isNull(i), "null value at position " + i); Type type = rowType.getTypeParameters().get(i); Object leftElement = readNativeValue(type, leftRow, i); Object rightElement = readNativeValue(type, rightRow, i); try { if ((boolean) comparisonFunctions.get(i).invoke(leftElement, rightElement)) { return 1; } if ((boolean) comparisonFunctions.get(i).invoke(rightElement, leftElement)) { return -1; } } catch (Throwable t) { throw internalError(t); } } return 0; } }
@Override public boolean positionEqualsPosition(int leftBlockIndex, int leftPosition, int rightBlockIndex, int rightPosition) { for (int hashChannel : hashChannels) { Type type = types.get(hashChannel); List<Block> channel = channels.get(hashChannel); Block leftBlock = channel.get(leftBlockIndex); Block rightBlock = channel.get(rightBlockIndex); if (!TypeUtils.positionEqualsPosition(type, leftBlock, leftPosition, rightBlock, rightPosition)) { return false; } } return true; }
@TypeParameter("T") @SqlType(StandardTypes.BIGINT) public static long anotherHash( @OperatorDependency(operator = HASH_CODE, returnType = StandardTypes.BIGINT, argumentTypes = "T") MethodHandle hashFunction, @TypeParameter("T") Type type, @SqlType("array(T)") Block block) { int hash = 0; for (int i = 0; i < block.getPositionCount(); i++) { checkElementNotNull(block.isNull(i), ARRAY_NULL_ELEMENT_MSG); hash = (int) getHash(hash, hashPosition(hashFunction, type, block, i)); } return hash; } }
public SingleMultimapAggregationState(Type keyType, Type valueType) { this.keyType = requireNonNull(keyType); this.valueType = requireNonNull(valueType); keyBlockBuilder = keyType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(keyType, EXPECTED_ENTRY_SIZE)); valueBlockBuilder = valueType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(valueType, EXPECTED_ENTRY_SIZE)); }
private List<Page> pagesWithHash(List<Page> pages) { ImmutableList.Builder<Page> resultPages = ImmutableList.builder(); for (Page page : pages) { resultPages.add(TypeUtils.getHashPage(page, types, hashChannels.get())); } return resultPages.build(); }
ImmutableList.Builder<Block> hashChannelBuilder = ImmutableList.builder(); for (Block block : channel) { hashChannelBuilder.add(TypeUtils.getHashBlock(joinTypes, block)); assertEquals(hashStrategy.hashPosition(leftBlockIndex, leftBlockPosition), hashPosition(VARCHAR, leftBlock, leftBlockPosition)); Block rightBlock = channel.get(rightBlockIndex); for (int rightBlockPosition = 0; rightBlockPosition < rightBlock.getPositionCount(); rightBlockPosition++) { boolean expected = positionEqualsPosition(VARCHAR, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition); assertEquals(hashStrategy.positionEqualsRow(leftBlockIndex, leftBlockPosition, rightBlockPosition, rightBlock), expected); assertEquals(hashStrategy.rowEqualsRow(leftBlockPosition, new Block[] {leftBlock}, rightBlockPosition, new Block[] {rightBlock}), expected); Block rightBlock = channel.get(rightBlockIndex); for (int rightBlockPosition = 0; rightBlockPosition < rightBlock.getPositionCount(); rightBlockPosition++) { boolean expected = positionEqualsPosition(VARCHAR, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition); assertEquals(hashStrategy.positionEqualsRow(leftBlockIndex, leftBlockPosition, rightBlockPosition, rightBlock), expected); assertEquals(hashStrategy.rowEqualsRow(leftBlockPosition, new Block[] {leftBlock}, rightBlockPosition, new Block[] {rightBlock}), expected);
@UsedByGeneratedCode public static long hash(MethodHandle keyHashCodeFunction, MethodHandle valueHashCodeFunction, Type keyType, Type valueType, Block block) { long result = 0; for (int position = 0; position < block.getPositionCount(); position += 2) { result += hashPosition(keyHashCodeFunction, keyType, block, position) ^ hashPosition(valueHashCodeFunction, valueType, block, position + 1); } return result; } }
@TypeParameter("T") @SqlType(StandardTypes.BOOLEAN) public static boolean greaterThan( @OperatorDependency(operator = GREATER_THAN, returnType = StandardTypes.BOOLEAN, argumentTypes = {"T", "T"}) MethodHandle greaterThanFunction, @TypeParameter("T") Type type, @SqlType("array(T)") Block leftArray, @SqlType("array(T)") Block rightArray) { int len = Math.min(leftArray.getPositionCount(), rightArray.getPositionCount()); int index = 0; while (index < len) { checkElementNotNull(leftArray.isNull(index), ARRAY_NULL_ELEMENT_MSG); checkElementNotNull(rightArray.isNull(index), ARRAY_NULL_ELEMENT_MSG); Object leftElement = readNativeValue(type, leftArray, index); Object rightElement = readNativeValue(type, rightArray, index); try { if ((boolean) greaterThanFunction.invoke(leftElement, rightElement)) { return true; } if ((boolean) greaterThanFunction.invoke(rightElement, leftElement)) { return false; } } catch (Throwable t) { throw internalError(t); } index++; } return leftArray.getPositionCount() > rightArray.getPositionCount(); }
@Override public boolean positionEqualsRow(int leftBlockIndex, int leftPosition, int rightPosition, Page page, int[] rightHashChannels) { for (int i = 0; i < hashChannels.size(); i++) { int hashChannel = hashChannels.get(i); Type type = types.get(hashChannel); Block leftBlock = channels.get(hashChannel).get(leftBlockIndex); Block rightBlock = page.getBlock(rightHashChannels[i]); if (!TypeUtils.positionEqualsPosition(type, leftBlock, leftPosition, rightBlock, rightPosition)) { return false; } } return true; }
public KeyValuePairs(Type keyType, Type valueType) { this.keyType = requireNonNull(keyType, "keyType is null"); this.valueType = requireNonNull(valueType, "valueType is null"); keyBlockBuilder = this.keyType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(keyType, EXPECTED_ENTRY_SIZE)); valueBlockBuilder = this.valueType.createBlockBuilder(null, EXPECTED_ENTRIES, expectedValueSize(valueType, EXPECTED_ENTRY_SIZE)); hashCapacity = arraySize(EXPECTED_ENTRIES, FILL_RATIO); this.maxFill = calculateMaxFill(hashCapacity); this.hashMask = hashCapacity - 1; keyPositionByHash = new int[hashCapacity]; Arrays.fill(keyPositionByHash, EMPTY_SLOT); }
private List<Page> pagesWithHash(List<Page> pages) { ImmutableList.Builder<Page> resultPages = ImmutableList.builder(); for (Page page : pages) { resultPages.add(TypeUtils.getHashPage(page, types, hashChannels.get())); } return resultPages.build(); }
private int getHashPositionOfKey(Block key, int position) { int hashPosition = getMaskedHash(hashPosition(keyType, key, position)); while (true) { if (keyPositionByHash[hashPosition] == EMPTY_SLOT) { return hashPosition; } else if (positionEqualsPosition(keyType, keyBlockBuilder, keyPositionByHash[hashPosition], key, position)) { return hashPosition; } hashPosition = getMaskedHash(hashPosition + 1); } }
@Test public void testContains() { Block valuesBlock = BlockAssertions.createDoubleSequenceBlock(0, 10); Block hashBlock = TypeUtils.getHashBlock(ImmutableList.of(DOUBLE), valuesBlock); GroupByHash groupByHash = createGroupByHash(TEST_SESSION, ImmutableList.of(DOUBLE), new int[] {0}, Optional.of(1), 100, JOIN_COMPILER); groupByHash.getGroupIds(new Page(valuesBlock, hashBlock)).process(); Block testBlock = BlockAssertions.createDoublesBlock((double) 3); Block testHashBlock = TypeUtils.getHashBlock(ImmutableList.of(DOUBLE), testBlock); assertTrue(groupByHash.contains(0, new Page(testBlock, testHashBlock), CONTAINS_CHANNELS)); testBlock = BlockAssertions.createDoublesBlock(11.0); testHashBlock = TypeUtils.getHashBlock(ImmutableList.of(DOUBLE), testBlock); assertFalse(groupByHash.contains(0, new Page(testBlock, testHashBlock), CONTAINS_CHANNELS)); }
public long hashPosition(int position, IntFunction<Block> blockProvider) { long result = HashGenerationOptimizer.INITIAL_HASH_VALUE; for (int i = 0; i < hashChannels.length; i++) { Type type = hashChannelTypes.get(i); result = CombineHashFunction.getHash(result, TypeUtils.hashPosition(type, blockProvider.apply(hashChannels[i]), position)); } return result; }
int index = 0; while (index < len) { checkElementNotNull(leftArray.isNull(index), ARRAY_NULL_ELEMENT_MSG); checkElementNotNull(rightArray.isNull(index), ARRAY_NULL_ELEMENT_MSG); Object leftElement = readNativeValue(type, leftArray, index); Object rightElement = readNativeValue(type, rightArray, index);