/** * Set the start row of the scan. * <p> * If the specified row does not exist, the Scanner will start from the next closest row after the * specified row. * @param startRow row to start scanner at or after * @return this * @throws IllegalArgumentException if startRow does not meet criteria for a row key (when length * exceeds {@link HConstants#MAX_ROW_LENGTH}) */ public Scan withStartRow(byte[] startRow) { return withStartRow(startRow, true); }
private void completeWithNextStartRow(byte[] row, boolean inclusive) { scan.withStartRow(row, inclusive); future.complete(true); }
/** * Create a new Scan with a cursor. It only set the position information like start row key. * The others (like cfs, stop row, limit) should still be filled in by the user. * {@link Result#isCursor()} * {@link Result#getCursor()} * {@link Cursor} */ public static Scan createScanFromCursor(Cursor cursor) { return new Scan().withStartRow(cursor.getRow()); } }
@Override protected boolean setNewStartKey() { if (noMoreResultsForReverseScan(scan, currentRegion)) { return false; } scan.withStartRow(currentRegion.getStartKey(), false); return true; }
@Override protected boolean setNewStartKey() { if (noMoreResultsForScan(scan, currentRegion)) { return false; } scan.withStartRow(currentRegion.getEndKey(), true); return true; }
/** * Set the start row for the replica callable based on the state of the last result received. * @param callable The callable to set the start row on */ private void setStartRowForReplicaCallable(ScannerCallable callable) { if (this.lastResult == null || callable == null) { return; } // 1. The last result was a partial result which means we have not received all of the cells // for this row. Thus, use the last result's row as the start row. If a replica switch // occurs, the scanner will ensure that any accumulated partial results are cleared, // and the scan can resume from this row. // 2. The last result was not a partial result which means it contained all of the cells for // that row (we no longer need any information from it). Set the start row to the next // closest row that could be seen. callable.getScan().withStartRow(this.lastResult.getRow(), this.lastResult.mayHaveMoreCellsInRow()); }
private void completeWhenError(boolean closeScanner) { incRPCRetriesMetrics(scanMetrics, closeScanner); resultCache.clear(); if (closeScanner) { closeScanner(); } if (nextStartRowWhenError != null) { scan.withStartRow(nextStartRowWhenError, includeNextStartRowWhenError); } future.complete(true); }
static Scan createScanForOrigBulkLoadedFiles(TableName table) { Scan scan = new Scan(); byte[] startRow = rowkey(BULK_LOAD_PREFIX, table.toString(), BLK_LD_DELIM); byte[] stopRow = Arrays.copyOf(startRow, startRow.length); stopRow[stopRow.length - 1] = (byte) (stopRow[stopRow.length - 1] + 1); scan.withStartRow(startRow); scan.withStopRow(stopRow); scan.addFamily(BackupSystemTable.META_FAMILY); scan.setMaxVersions(1); return scan; }
/** * Creates a {@link Scan} which returns only {@link SpaceQuotaSnapshot} from the quota table for a * specific table. * @param tn Optionally, a table name to limit the scan's rowkey space. Can be null. */ public static Scan makeQuotaSnapshotScanForTable(TableName tn) { Scan s = new Scan(); // Limit to "u:v" column s.addColumn(QUOTA_FAMILY_USAGE, QUOTA_QUALIFIER_POLICY); if (null == tn) { s.setRowPrefixFilter(QUOTA_TABLE_ROW_KEY_PREFIX); } else { byte[] row = getTableRowKey(tn); // Limit rowspace to the "t:" prefix s.withStartRow(row, true).withStopRow(row, true); } return s; }
static Scan createScanForSpaceSnapshotSizes(TableName table) { Scan s = new Scan(); if (null == table) { // Read all tables, just look at the row prefix s.setRowPrefixFilter(QUOTA_TABLE_ROW_KEY_PREFIX); } else { // Fetch the exact row for the table byte[] rowkey = getTableRowKey(table); // Fetch just this one row s.withStartRow(rowkey).withStopRow(rowkey, true); } // Just the usage family and only the snapshot size qualifiers return s.addFamily(QUOTA_FAMILY_USAGE).setFilter( new ColumnPrefixFilter(QUOTA_SNAPSHOT_SIZE_QUALIFIER)); }
@Test public void testScanNoStopKey() throws Exception { int start = 345; List<Result> results = doScan(createScan().withStartRow(Bytes.toBytes(String.format("%03d", start)))); assertEquals(COUNT - start, results.size()); IntStream.range(0, COUNT - start).forEach(i -> assertResultEquals(results.get(i), start + i)); }
private boolean isInBloom(StoreFileScanner scanner, byte[] row, byte[] qualifier) { Scan scan = new Scan().withStartRow(row).withStopRow(row, true); scan.addColumn(Bytes.toBytes(RandomKeyValueUtil.COLUMN_FAMILY_NAME), qualifier); HStore store = mock(HStore.class); when(store.getColumnFamilyDescriptor()) .thenReturn(ColumnFamilyDescriptorBuilder.of(RandomKeyValueUtil.COLUMN_FAMILY_NAME)); return scanner.shouldUseScanner(scan, store, Long.MIN_VALUE); }
@Test public void testReverseScanNoStopKey() throws Exception { int start = 765; List<Result> results = doScan( createScan().withStartRow(Bytes.toBytes(String.format("%03d", start))).setReversed(true)); assertEquals(start + 1, results.size()); IntStream.range(0, start + 1).forEach(i -> assertResultEquals(results.get(i), start - i)); }
private void testScan(int start, boolean startInclusive, int stop, boolean stopInclusive, int limit) throws Exception { Scan scan = createScan().withStartRow(Bytes.toBytes(String.format("%03d", start)), startInclusive) .withStopRow(Bytes.toBytes(String.format("%03d", stop)), stopInclusive); if (limit > 0) { scan.setLimit(limit); } List<Result> results = doScan(scan); int actualStart = startInclusive ? start : start + 1; int actualStop = stopInclusive ? stop + 1 : stop; int count = actualStop - actualStart; if (limit > 0) { count = Math.min(count, limit); } assertEquals(count, results.size()); IntStream.range(0, count).forEach(i -> assertResultEquals(results.get(i), actualStart + i)); }
private List<Cell> performScan(byte[] row1, byte[] fam1) throws IOException { Scan scan = new Scan().withStartRow(row1).addFamily(fam1).readVersions(MAX_VERSIONS); List<Cell> actual = new ArrayList<>(); InternalScanner scanner = region.getScanner(scan); boolean hasNext = scanner.next(actual); assertEquals(false, hasNext); return actual; }
@Override protected ScannerCallable createScannerCallable() { if (!scan.includeStartRow() && !isEmptyStartRow(scan.getStartRow())) { // we have not implemented locate to next row for sync client yet, so here we change the // inclusive of start row to true. scan.withStartRow(createClosestRowAfter(scan.getStartRow()), true); } return new ScannerCallable(getConnection(), getTable(), scan, this.scanMetrics, this.rpcControllerFactory); } }
/** * Tries to scan a row from passed region */ private void isSuccessfulScan(RegionInfo region) throws IOException { Scan scan = new Scan().withStartRow(region.getStartKey()).setRaw(true).setOneRowLimit() .setMaxResultSize(1L).setCaching(1).setFilter(new FirstKeyOnlyFilter()) .setCacheBlocks(false); try (Table table = conn.getTable(region.getTable()); ResultScanner scanner = table.getScanner(scan)) { scanner.next(); } catch (IOException e) { LOG.error("Could not scan region:" + region.getEncodedName(), e); throw e; } }
@Test public void testWildCardOneVersionScan() throws IOException { KeyValue [] kvs = new KeyValue [] { create("R1", "cf", "a", 2, KeyValue.Type.Put, "dont-care"), create("R1", "cf", "b", 1, KeyValue.Type.Put, "dont-care"), create("R1", "cf", "a", 1, KeyValue.Type.DeleteColumn, "dont-care"), }; List<KeyValueScanner> scanners = scanFixture(kvs); try (StoreScanner scan = new StoreScanner(new Scan().withStartRow(Bytes.toBytes("R1")), scanInfo, null, scanners)) { List<Cell> results = new ArrayList<>(); assertEquals(true, scan.next(results)); assertEquals(2, results.size()); assertEquals(kvs[0], results.get(0)); assertEquals(kvs[1], results.get(1)); } }
@Test public void testDeleteVersionSameTimestamp() throws IOException { KeyValue [] kvs = new KeyValue [] { create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"), create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"), }; List<KeyValueScanner> scanners = scanFixture(kvs); Scan scanSpec = new Scan().withStartRow(Bytes.toBytes("R1")); try (StoreScanner scan = new StoreScanner(scanSpec, scanInfo, getCols("a"), scanners)) { List<Cell> results = new ArrayList<>(); assertFalse(scan.next(results)); assertEquals(0, results.size()); } }
@Test @Ignore("this fails, since we don't handle deletions, etc, in peek") public void testPeek() throws Exception { KeyValue[] kvs = new KeyValue [] { create("R1", "cf", "a", 1, KeyValue.Type.Put, "dont-care"), create("R1", "cf", "a", 1, KeyValue.Type.Delete, "dont-care"), }; List<KeyValueScanner> scanners = scanFixture(kvs); Scan scanSpec = new Scan().withStartRow(Bytes.toBytes("R1")); try (StoreScanner scan = new StoreScanner(scanSpec, scanInfo, getCols("a"), scanners)) { assertNull(scan.peek()); } }