private void updateNextStartRowWhenError(Result result) { nextStartRowWhenError = result.getRow(); includeNextStartRowWhenError = result.mayHaveMoreCellsInRow(); }
private void recordLastResult(Result result) { lastCell = result.rawCells()[result.rawCells().length - 1]; lastResultPartial = result.mayHaveMoreCellsInRow(); }
/** * 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 recordLastResult(Result result) { lastCell = result.rawCells()[result.rawCells().length - 1]; lastResultPartial = result.mayHaveMoreCellsInRow(); }
private List<Result> assertAndCreateCompleteResults(List<Result> results) throws IOException { if ((!batch && !allowPartial) || (allowPartial && !batch && !smallResultSize)) { for (Result result : results) { assertFalse("Should not have partial result", result.mayHaveMoreCellsInRow()); } return results; } List<Result> completeResults = new ArrayList<>(); List<Result> partialResults = new ArrayList<>(); for (Result result : results) { if (!result.mayHaveMoreCellsInRow()) { assertFalse("Should have partial result", partialResults.isEmpty()); partialResults.add(result); completeResults.add(Result.createCompleteResult(partialResults)); partialResults.clear(); } else { partialResults.add(result); } } assertTrue("Should not have orphan partial result", partialResults.isEmpty()); return completeResults; }
private void assertResultEquals(Result result, int key, int start, int to) { assertEquals(to - start, result.size()); for (int i = start; i < to; i++) { assertEquals(key, Bytes.toInt(result.getValue(CF, Bytes.toBytes("cq" + i)))); } assertEquals(to - start == 4, result.mayHaveMoreCellsInRow()); }
private void addResults(ScanResponse.Builder builder, List<Result> results, HBaseRpcController controller, boolean isDefaultRegion, boolean clientCellBlockSupported) { builder.setStale(!isDefaultRegion); if (results.isEmpty()) { return; } if (clientCellBlockSupported) { for (Result res : results) { builder.addCellsPerResult(res.size()); builder.addPartialFlagPerResult(res.mayHaveMoreCellsInRow()); } controller.setCellScanner(CellUtil.createCellScanner(results)); } else { for (Result res : results) { ClientProtos.Result pbr = ProtobufUtil.toResult(res); builder.addResults(pbr); } } }
@Test public void testAllowPartial() throws InterruptedException, ExecutionException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setMaxResultSize(1) .setAllowPartialResults(true).setLimit(limit); List<Result> results = TABLE.scanAll(scan).get(); assertEquals(2 * limit, results.size()); IntStream.range(0, 2 * limit).forEach(i -> { int key = i / 2; Result result = results.get(i); assertEquals(key, Bytes.toInt(result.getRow())); assertEquals(1, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); int cqIndex = i % 2; assertEquals(key * (cqIndex + 1), Bytes.toInt(result.getValue(FAMILY, CQS[cqIndex]))); }); }
@Test public void testCompleteResult() throws InterruptedException, ExecutionException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setMaxResultSize(1).setLimit(limit); List<Result> results = TABLE.scanAll(scan).get(); assertEquals(limit, results.size()); IntStream.range(0, limit).forEach(i -> { Result result = results.get(i); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(2, result.size()); assertFalse(result.mayHaveMoreCellsInRow()); assertEquals(i, Bytes.toInt(result.getValue(FAMILY, CQS[0]))); assertEquals(2 * i, Bytes.toInt(result.getValue(FAMILY, CQS[1]))); }); }
@Test public void testBatch() throws InterruptedException, ExecutionException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setBatch(2).setMaxResultSize(1) .setLimit(limit); List<Result> results = TABLE.scanAll(scan).get(); assertEquals(limit, results.size()); IntStream.range(0, limit).forEach(i -> { Result result = results.get(i); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(2, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); assertEquals(i, Bytes.toInt(result.getValue(FAMILY, CQS[0]))); assertEquals(2 * i, Bytes.toInt(result.getValue(FAMILY, CQS[1]))); }); }
@Test public void testBatchAllowPartial() throws InterruptedException, ExecutionException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(3)).setBatch(2).setMaxResultSize(1) .setAllowPartialResults(true).setLimit(limit); List<Result> results = TABLE.scanAll(scan).get(); assertEquals(3 * limit, results.size()); IntStream.range(0, 3 * limit).forEach(i -> { int key = i / 3; Result result = results.get(i); assertEquals(key, Bytes.toInt(result.getRow())); assertEquals(1, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); int cqIndex = i % 3; assertEquals(key * (cqIndex + 1), Bytes.toInt(result.getValue(FAMILY, CQS[cqIndex]))); }); }
@Test public void testBatchAndFilterDiffer() throws InterruptedException, ExecutionException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(3)).setBatch(2).setMaxResultSize(1) .setLimit(limit); List<Result> results = TABLE.scanAll(scan).get(); assertEquals(2 * limit, results.size()); IntStream.range(0, limit).forEach(i -> { Result result = results.get(2 * i); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(2, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); assertEquals(i, Bytes.toInt(result.getValue(FAMILY, CQS[0]))); assertEquals(2 * i, Bytes.toInt(result.getValue(FAMILY, CQS[1]))); result = results.get(2 * i + 1); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(1, result.size()); assertFalse(result.mayHaveMoreCellsInRow()); assertEquals(3 * i, Bytes.toInt(result.getValue(FAMILY, CQS[2]))); }); } }
/** * Convert a client Result to a protocol buffer Result * * @param result the client Result to convert * @return the converted protocol buffer Result */ public static ClientProtos.Result toResult(final Result result) { if (result.getExists() != null) { return toResult(result.getExists(), result.isStale()); } Cell[] cells = result.rawCells(); if (cells == null || cells.length == 0) { return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; } ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); for (Cell c : cells) { builder.addCell(toCell(c)); } builder.setStale(result.isStale()); builder.setPartial(result.mayHaveMoreCellsInRow()); return builder.build(); }
/** * Convert a client Result to a protocol buffer Result * * @param result the client Result to convert * @return the converted protocol buffer Result */ public static ClientProtos.Result toResult(final Result result) { if (result.getExists() != null) { return toResult(result.getExists(), result.isStale()); } Cell[] cells = result.rawCells(); if (cells == null || cells.length == 0) { return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; } ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); for (Cell c : cells) { builder.addCell(toCell(c)); } builder.setStale(result.isStale()); builder.setPartial(result.mayHaveMoreCellsInRow()); return builder.build(); }
/** * When a scan has a filter where {@link org.apache.hadoop.hbase.filter.Filter#hasFilterRow()} is * true, the scanner should not return partial results. The scanner cannot return partial results * because the entire row needs to be read for the include/exclude decision to be made */ @Test public void testNoPartialResultsWhenRowFilterPresent() throws Exception { Scan scan = new Scan(); scan.setMaxResultSize(1); scan.setAllowPartialResults(true); // If a filter hasFilter() is true then partial results should not be returned else filter // application server side would break. scan.setFilter(new RandomRowFilter(1.0f)); ResultScanner scanner = TABLE.getScanner(scan); Result r = null; while ((r = scanner.next()) != null) { assertFalse(r.mayHaveMoreCellsInRow()); } scanner.close(); }
public void testExpectedValuesOfPartialResults(boolean reversed) throws Exception { Scan partialScan = new Scan(); partialScan.setMaxVersions(); // Max result size of 1 ensures that each RPC request will return a single cell. The scanner // will need to reconstruct the results into a complete result before returning to the caller partialScan.setMaxResultSize(1); partialScan.setReversed(reversed); ResultScanner partialScanner = TABLE.getScanner(partialScan); final int startRow = reversed ? ROWS.length - 1 : 0; final int endRow = reversed ? -1 : ROWS.length; final int loopDelta = reversed ? -1 : 1; String message; for (int row = startRow; row != endRow; row = row + loopDelta) { message = "Ensuring the expected keyValues are present for row " + row; List<Cell> expectedKeyValues = createKeyValuesForRow(ROWS[row], FAMILIES, QUALIFIERS, VALUE); Result result = partialScanner.next(); assertFalse(result.mayHaveMoreCellsInRow()); verifyResult(result, expectedKeyValues, message); } partialScanner.close(); }
@Test public void testCompleteResult() throws IOException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setMaxResultSize(1).setLimit(limit); try (Table table = UTIL.getConnection().getTable(TABLE_NAME); ResultScanner scanner = table.getScanner(scan)) { for (int i = 0; i < limit; i++) { Result result = scanner.next(); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(2, result.size()); assertFalse(result.mayHaveMoreCellsInRow()); assertEquals(i, Bytes.toInt(result.getValue(FAMILY, CQS[0]))); assertEquals(2 * i, Bytes.toInt(result.getValue(FAMILY, CQS[1]))); } assertNull(scanner.next()); } }
@Test public void testBatch() throws IOException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setBatch(2).setMaxResultSize(1) .setLimit(limit); try (Table table = UTIL.getConnection().getTable(TABLE_NAME); ResultScanner scanner = table.getScanner(scan)) { for (int i = 0; i < limit; i++) { Result result = scanner.next(); assertEquals(i, Bytes.toInt(result.getRow())); assertEquals(2, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); assertEquals(i, Bytes.toInt(result.getValue(FAMILY, CQS[0]))); assertEquals(2 * i, Bytes.toInt(result.getValue(FAMILY, CQS[1]))); } assertNull(scanner.next()); } }
@Test public void testAllowPartial() throws IOException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(2)).setMaxResultSize(1) .setAllowPartialResults(true).setLimit(limit); try (Table table = UTIL.getConnection().getTable(TABLE_NAME); ResultScanner scanner = table.getScanner(scan)) { for (int i = 0; i < 2 * limit; i++) { int key = i / 2; Result result = scanner.next(); assertEquals(key, Bytes.toInt(result.getRow())); assertEquals(1, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); int cqIndex = i % 2; assertEquals(key * (cqIndex + 1), Bytes.toInt(result.getValue(FAMILY, CQS[cqIndex]))); } assertNull(scanner.next()); } }
@Test public void testBatchAllowPartial() throws IOException { int limit = 5; Scan scan = new Scan().setFilter(new ColumnCountOnRowFilter(3)).setBatch(2).setMaxResultSize(1) .setAllowPartialResults(true).setLimit(limit); try (Table table = UTIL.getConnection().getTable(TABLE_NAME); ResultScanner scanner = table.getScanner(scan)) { for (int i = 0; i < 3 * limit; i++) { int key = i / 3; Result result = scanner.next(); assertEquals(key, Bytes.toInt(result.getRow())); assertEquals(1, result.size()); assertTrue(result.mayHaveMoreCellsInRow()); int cqIndex = i % 3; assertEquals(key * (cqIndex + 1), Bytes.toInt(result.getValue(FAMILY, CQS[cqIndex]))); } assertNull(scanner.next()); } }