ScanAdapter implements ReadOperationAdapter<Scan> { @Override public void adapt(Scan scan, ReadHooks readHooks, Query query) { throwIfUnsupportedScan(scan); toByteStringRange(scan, query); query.filter(buildFilter(scan, readHooks)); if (LIMIT_AVAILABLE && scan.getLimit() > 0) { query.limit(scan.getLimit()); } } ScanAdapter(FilterAdapter filterAdapter, RowRangeAdapter rowRangeAdapter); void throwIfUnsupportedScan(Scan scan); Filters.Filter buildFilter(Scan scan, ReadHooks hooks); @Override void adapt(Scan scan, ReadHooks readHooks, Query query);  }
@Test public void testNewScan() { Scan scan = new Scan(); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( toRowSet(RowRange.getDefaultInstance()), query.toProto(requestContext).getRows()); }
@Test public void testStartDefault() { byte[] startKey = Bytes.toBytes(START_KEY); Scan scan = new Scan().withStartRow(startKey); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setStartKeyClosed(ByteString.copyFrom(startKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStartInclusive() { byte[] startKey = Bytes.toBytes(START_KEY); Scan scan = new Scan().withStartRow(startKey, true); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setStartKeyClosed(ByteString.copyFrom(startKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStartExclusive() { byte[] startKey = Bytes.toBytes(START_KEY); Scan scan = new Scan().withStartRow(startKey, false); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setStartKeyOpen(ByteString.copyFrom(startKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStopDefault() { byte[] stopKey = Bytes.toBytes(STOP_KEY); Scan scan = new Scan().withStopRow(stopKey); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setEndKeyOpen(ByteString.copyFrom(stopKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStopInclusive() { byte[] stopKey = Bytes.toBytes(STOP_KEY); Scan scan = new Scan().withStopRow(stopKey, true); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setEndKeyClosed(ByteString.copyFrom(stopKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStopExclusive() { byte[] stopKey = Bytes.toBytes(STOP_KEY); Scan scan = new Scan().withStopRow(stopKey, false); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = toRowSet(RowRange.newBuilder().setEndKeyOpen(ByteString.copyFrom(stopKey)).build()); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testStartAndEndKeysAreSet() { byte[] startKey = Bytes.toBytes(START_KEY); byte[] stopKey = Bytes.toBytes(STOP_KEY); Scan scan = new Scan().withStartRow(startKey).withStopRow(stopKey); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( toRowSet(toRange(startKey, stopKey)), query.toProto(requestContext).getRows()); }
@Test public void testStartAndEndKeysNonDefault() { byte[] startKey = Bytes.toBytes(START_KEY); byte[] stopKey = Bytes.toBytes(STOP_KEY); Scan scan = new Scan().withStartRow(startKey, false).withStopRow(stopKey, true); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( toRowSet( RowRange.newBuilder() .setStartKeyOpen(ByteStringer.wrap(startKey)) .setEndKeyClosed(ByteStringer.wrap(stopKey)) .build()), query.toProto(requestContext).getRows()); }
@Test public void testPrefix() { byte[] prefix = Bytes.toBytes("prefix"); byte[] prefixEnd = calculatePrefixEnd(prefix); Scan scan = new Scan(); scan.setRowPrefixFilter(prefix); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( toRowSet(toRange(prefix, prefixEnd)), query.toProto(requestContext).getRows()); }
@Test public void maxVersionsIsSet() { Scan scan = new Scan(); scan.setMaxVersions(10); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( FILTERS.limit().cellsPerColumn(10).toProto(), query.toProto(requestContext).getFilter()); }
@Test public void testExtendedScan() { byte[] row1 = Bytes.toBytes("row1"); byte[] row2 = Bytes.toBytes("row2"); byte[] startRow = Bytes.toBytes(START_KEY); byte[] stopRow = Bytes.toBytes(STOP_KEY); byte[] prefix = Bytes.toBytes("prefix"); byte[] prefixEnd = calculatePrefixEnd(prefix); BigtableExtendedScan scan = new BigtableExtendedScan(); scan.addRowKey(row1); scan.addRowKey(row2); scan.addRange(startRow, stopRow); scan.addRangeWithPrefix(prefix); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet expected = RowSet.newBuilder() .addRowKeys(ByteStringer.wrap(row1)) .addRowKeys(ByteStringer.wrap(row2)) .addRowRanges(toRange(prefix, prefixEnd)) .addRowRanges(toRange(startRow, stopRow)) .build(); Assert.assertEquals(expected, query.toProto(requestContext).getRows()); }
@Test public void testNarrowedScan() throws IOException { FilterAdapter filterAdapter = Mockito.mock(FilterAdapter.class); ScanAdapter scanAdapter = new ScanAdapter(filterAdapter, new RowRangeAdapter()); Filter fakeFilter = new FilterBase() { @Override public ReturnCode filterKeyValue(Cell v) throws IOException { return ReturnCode.INCLUDE; } }; RangeSet<RowKeyWrapper> rangeSet = ImmutableRangeSet.of( Range.closedOpen( new RowKeyWrapper(ByteString.copyFromUtf8("b")), new RowKeyWrapper(ByteString.copyFromUtf8("d")))); Mockito.when(filterAdapter.getIndexScanHint(any(Filter.class))).thenReturn(rangeSet); Mockito.when(filterAdapter.adaptFilter(any(FilterAdapterContext.class), eq(fakeFilter))) .thenReturn(Optional.of(Filters.FILTERS.pass())); Scan scan = new Scan().withStartRow("a".getBytes()).withStopRow("z".getBytes()).setFilter(fakeFilter); scanAdapter.adapt(scan, throwingReadHooks, query); Assert.assertEquals( RowSet.newBuilder() .addRowRanges( RowRange.newBuilder() .setStartKeyClosed(ByteString.copyFromUtf8("b")) .setEndKeyOpen(ByteString.copyFromUtf8("d"))) .build(), query.toProto(requestContext).getRows()); }
@Test public void testNarrowedScanWithoutFilter() { Scan scan = new Scan().withStartRow("a".getBytes()).withStopRow("z".getBytes()); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet result = query.toProto(requestContext).getRows(); RowSet expected = RowSet.newBuilder() .addRowRanges( RowRange.newBuilder() .setStartKeyClosed(ByteString.copyFromUtf8("a")) .setEndKeyOpen(ByteString.copyFromUtf8("z"))) .build(); Assert.assertEquals(expected, result); }
@Test public void testEmptyFilterList() { Scan scan = new Scan() .setFilter(new FilterList()) .withStartRow("a".getBytes()) .withStopRow("z".getBytes()); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet result = query.toProto(requestContext).getRows(); RowSet expected = RowSet.newBuilder() .addRowRanges( RowRange.newBuilder() .setStartKeyClosed(ByteString.copyFromUtf8("a")) .setEndKeyOpen(ByteString.copyFromUtf8("z"))) .build(); Assert.assertEquals(expected, result); }
@Test public void testLimit() { Scan scan = new Scan().setLimit(10); scanAdapter.adapt(scan, throwingReadHooks, query); int adaptedLimit = (int) query.toProto(requestContext).getRowsLimit(); Assert.assertEquals(scan.getLimit(), adaptedLimit); }
@Test public void testIsGetScan() throws IOException { byte[] key = Bytes.toBytes("key"); Get get = new Get(key); get.setMaxVersions(Integer.MAX_VALUE); Scan scan = new Scan(get); scanAdapter.adapt(scan, throwingReadHooks, query); RowSet actual = query.toProto(requestContext).getRows(); RowSet expected = RowSet.newBuilder().addRowKeys(ByteString.copyFrom(key)).build(); Assert.assertEquals(expected, actual); }
@Test public void testColFamilyTimeRange() throws IOException { String colFamily1 = "cf1", colFamily2 = "cf2"; long rangeStart = 10000L, rangeEnd = 99999L, secRangeStart = 100L, secRangeEnd = 999L; Scan scan = new Scan() .setColumnFamilyTimeRange(colFamily1.getBytes(), rangeStart, rangeEnd) .setColumnFamilyTimeRange(colFamily2.getBytes(), secRangeStart, secRangeEnd); scanAdapter.adapt(scan, throwingReadHooks, query); Filters.Filter expected = FILTERS .chain() .filter(FILTERS.limit().cellsPerColumn(1)) .filter( FILTERS .interleave() .filter( FILTERS .chain() .filter(FILTERS.family().regex(colFamily1)) .filter( FILTERS.timestamp().range().of(rangeStart * 1000, rangeEnd * 1000))) .filter( FILTERS .chain() .filter(FILTERS.family().regex(colFamily2)) .filter( FILTERS .timestamp() .range() .of(secRangeStart * 1000, secRangeEnd * 1000)))); Assert.assertEquals(expected.toProto(), query.toProto(requestContext).getFilter()); }