public static int setKey(RowKeySchema schema, List<List<KeyRange>> slots, int[] position, Bound bound, byte[] key, int byteOffset, int slotStartIndex, int slotEndIndex) { return setKey(schema, slots, position, bound, key, byteOffset, slotStartIndex, slotEndIndex, slotStartIndex); }
private int setKey(Bound bound, byte[] key, int keyOffset, int slotStartIndex) { return ScanUtil.setKey(schema, slots, position, bound, key, keyOffset, slotStartIndex, position.length); }
private static byte[] getKey(RowKeySchema schema, List<List<KeyRange>> slots, Bound bound) { if (slots.isEmpty()) { return null; } int[] position = new int[slots.size()]; int maxLength = 0; for (int i = 0; i < position.length; i++) { position[i] = bound == Bound.LOWER ? 0 : slots.get(i).size()-1; KeyRange range = slots.get(i).get(position[i]); maxLength += range.getRange(bound).length + (schema.getField(i).getDataType().isFixedWidth() ? 0 : 1); } byte[] key = new byte[maxLength]; int length = setKey(schema, slots, position, bound, key, 0, 0, position.length); if (length == 0) { return null; } if (length == maxLength) { return key; } byte[] keyCopy = new byte[length]; System.arraycopy(key, 0, keyCopy, 0, length); return keyCopy; }
public static List<List<KeyRange>> flattenRanges(List<List<KeyRange>> ranges, RowKeySchema schema, int bucketNum) { if (ranges == null || ranges.isEmpty()) { return ScanRanges.NOTHING.getRanges(); } int count = 1; // Skip salt byte range in the first position for (int i = 1; i < ranges.size(); i++) { count *= ranges.get(i).size(); } KeyRange[] expandedRanges = new KeyRange[count]; int[] position = new int[ranges.size()]; int estimatedKeyLength = ScanUtil.estimateMaximumKeyLength(schema, 1, ranges); int idx = 0, length; byte saltByte; byte[] key = new byte[estimatedKeyLength]; do { length = ScanUtil.setKey(schema, ranges, position, Bound.LOWER, key, 1, 0, ranges.size(), 1); saltByte = SaltingUtil.getSaltingByte(key, 1, length, bucketNum); key[0] = saltByte; byte[] saltedKey = Arrays.copyOf(key, length + 1); KeyRange range = PDataType.VARBINARY.getKeyRange(saltedKey, true, saltedKey, true); expandedRanges[idx++] = range; } while (incrementKey(ranges, position)); // The comparator is imperfect, but sufficient for all single keys. Arrays.sort(expandedRanges, KeyRange.COMPARATOR); List<KeyRange> expandedRangesList = Arrays.asList(expandedRanges); return Collections.singletonList(expandedRangesList); }
@Test public void test() { byte[] key = new byte[1024]; int[] position = new int[slots.size()]; int offset = ScanUtil.setKey(schema, slots, position, bound, key, 0, 0, slots.size()); byte[] actualKey = new byte[offset]; System.arraycopy(key, 0, actualKey, 0, offset); assertArrayEquals(expectedKey, actualKey); }