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); }
public static byte[] getMaxKey(RowKeySchema schema, List<List<KeyRange>> slots) { return getKey(schema, slots, Bound.UPPER); }
/** * Intersects the scan start/stop row with the startKey and stopKey * @param scan * @param startKey * @param stopKey * @return false if the Scan cannot possibly return rows and true otherwise */ public static boolean intersectScanRange(Scan scan, byte[] startKey, byte[] stopKey) { return intersectScanRange(scan, startKey, stopKey, false); }
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); }
if (ScanUtil.intersectScanRange(splitScan, split.getLowerRange(), split.getUpperRange(), this.context.getScanRanges().useSkipScanFilter())) { ScanUtil.swapStartStopRowIfReversed(splitScan); Future<PeekingResultIterator> future = executor.submit(new JobCallable<PeekingResultIterator>() { final int factor = ScanUtil.isReversed(this.context.getScan()) ? -1 : 1;
public void setScanStartStopRow(Scan scan) { if (isEverything()) { return; } if (isDegenerate()) { scan.setStartRow(KeyRange.EMPTY_RANGE.getLowerRange()); scan.setStopRow(KeyRange.EMPTY_RANGE.getUpperRange()); return; } byte[] expectedKey; expectedKey = ScanUtil.getMinKey(schema, ranges); if (expectedKey != null) { scan.setStartRow(expectedKey); } expectedKey = ScanUtil.getMaxKey(schema, ranges); if (expectedKey != null) { scan.setStopRow(expectedKey); } }
public ParallelIterators(StatementContext context, TableRef tableRef, FilterableStatement statement, RowProjector projector, GroupBy groupBy, Integer limit, ParallelIteratorFactory iteratorFactory) throws SQLException { super(context, tableRef, groupBy); this.splits = getSplits(context, tableRef, statement.getHint()); this.iteratorFactory = iteratorFactory; Scan scan = context.getScan(); PTable table = tableRef.getTable(); if (projector.isProjectEmptyKeyValue()) { Map<byte [], NavigableSet<byte []>> familyMap = scan.getFamilyMap(); // If nothing projected into scan and we only have one column family, just allow everything // to be projected and use a FirstKeyOnlyFilter to skip from row to row. This turns out to // be quite a bit faster. if (familyMap.isEmpty() && table.getColumnFamilies().size() == 1) { // Project the one column family. We must project a column family since it's possible // that there are other non declared column families that we need to ignore. scan.addFamily(table.getColumnFamilies().get(0).getName().getBytes()); ScanUtil.andFilterAtBeginning(scan, new FirstKeyOnlyFilter()); } else { byte[] ecf = SchemaUtil.getEmptyColumnFamily(table.getColumnFamilies()); // Project empty key value unless the column family containing it has // been projected in its entirety. if (!familyMap.containsKey(ecf) || familyMap.get(ecf) != null) { scan.addColumn(ecf, QueryConstants.EMPTY_COLUMN_BYTES); } } } if (limit != null) { ScanUtil.andFilterAtEnd(scan, new PageFilter(limit)); } }
env, ScanUtil.getTenantId(scan), aggregators, estDistVals);
} else if (ScanUtil.isAllSingleRowScan(cnf, table.getRowKeySchema())) { cnf.addFirst(SALT_PLACEHOLDER); ranges = SaltingUtil.flattenRanges(cnf, table.getRowKeySchema(), table.getBucketNum());
boolean forcedRangeScan = statement.getHint().hasHint(Hint.RANGE_SCAN); if (forcedSkipScan || (scanRanges.useSkipScanFilter() && !forcedRangeScan)) { ScanUtil.andFilterAtBeginning(scan, scanRanges.getSkipScanFilter());
@Override protected RegionScanner doPostScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, final Scan scan, final RegionScanner s) throws Throwable { byte[] isScanQuery = scan.getAttribute(NON_AGGREGATE_QUERY); if (isScanQuery == null || Bytes.compareTo(PDataType.FALSE_BYTES, isScanQuery) == 0) { return s; } final ScanProjector p = ScanProjector.deserializeProjectorFromScan(scan); final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan); final ImmutableBytesWritable tenantId = ScanUtil.getTenantId(scan); RegionScanner innerScanner = s; if (p != null || j != null) { innerScanner = new HashJoinRegionScanner(s, p, j, tenantId, c.getEnvironment()); } final OrderedResultIterator iterator = deserializeFromScan(scan,innerScanner); if (iterator == null) { return getWrappedScanner(c, innerScanner); } return getTopNScanner(c, innerScanner, iterator, tenantId); }
private int setKey(Bound bound, byte[] key, int keyOffset, int slotStartIndex) { return ScanUtil.setKey(schema, slots, position, bound, key, keyOffset, slotStartIndex, position.length); }
RegionScanner theScanner = s; if (p != null || j != null) { theScanner = new HashJoinRegionScanner(s, p, j, ScanUtil.getTenantId(scan), c.getEnvironment());
public static byte[] getMinKey(RowKeySchema schema, List<List<KeyRange>> slots) { return getKey(schema, slots, Bound.LOWER); }
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; }
if (p != null || j != null) { innerScanner = new HashJoinRegionScanner(s, p, j, ScanUtil.getTenantId(scan), c.getEnvironment());
@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); }