/** * This creates a one time use visitable. The only proper use of the returned class is to call * accept on it directly and never reference it again. */ @SuppressWarnings("unchecked") public static <T> BatchingVisitable<T> create(final Iterator<? extends T> iterator) { return SingleCallProxy.newProxyInstance(BatchingVisitable.class, create((Iterable<T>) () -> IteratorUtils.wrap(iterator)) ); }
public static <T> BatchingVisitable<T> create(Iterable<? extends T> iterable) { return new BatchingVisitableFromIterable<T>(iterable); }
@Override public Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> getRowsColumnRange( TableReference tableRef, Iterable<byte[]> rows, BatchColumnRangeSelection columnRangeSelection) { checkGetPreconditions(tableRef); if (Iterables.isEmpty(rows)) { return ImmutableMap.of(); } hasReads = true; Map<byte[], RowColumnRangeIterator> rawResults = keyValueService.getRowsColumnRange(tableRef, rows, columnRangeSelection, getStartTimestamp()); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> postFilteredResults = Maps.newHashMapWithExpectedSize(rawResults.size()); for (Entry<byte[], RowColumnRangeIterator> e : rawResults.entrySet()) { byte[] row = e.getKey(); RowColumnRangeIterator rawIterator = e.getValue(); Iterator<Map.Entry<Cell, byte[]>> postFilteredIterator = getPostFilteredColumns(tableRef, columnRangeSelection, row, rawIterator); postFilteredResults.put(row, BatchingVisitableFromIterable.create(postFilteredIterator)); } return postFilteredResults; }
public static <T> BatchingVisitable<T> create(Iterable<? extends T> iterable) { return new BatchingVisitableFromIterable<T>(iterable); }
@Override protected <K extends Exception> void batchAcceptSizeHint( int batchSizeHint, ConsistentVisitor<SortedMap<Long, Multimap<TableReference, Cell>>, K> visitor) throws K { ClosableIterator<RowResult<Value>> iterator = getIteratorToScrub(batchSizeHint, maxScrubTimestamp, startRow, endRow); try { BatchingVisitableFromIterable.create(iterator).batchAccept( batchSizeHint, batch -> visitor.visitOne(transformRows(batch))); } finally { iterator.close(); } } };
@Test public void testFlatten() { List<String> firstChars = Lists.newArrayList(); for (int i = 0; i < 10; i++) { firstChars.add("" + (char) ('a' + i)); } BatchingVisitable<String> outerVisitable = BatchingVisitableFromIterable.create(firstChars); BatchingVisitableView<BatchingVisitable<String>> bv = BatchingVisitables.transform(outerVisitable, (prefix) -> { List<String> innerChars = Lists.newArrayList(); for (int i = 0; i < 10; i++) { innerChars.add(prefix + (char) ('0' + i)); } return BatchingVisitableFromIterable.create(innerChars); }); UnmodifiableIterator<String> iter = BatchingVisitables.flatten(7, bv).immutableCopy().iterator(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { assertEquals("unexpected flattened result", "" + (char) ('a' + i) + (char) ('0' + j), iter.next()); } } } }
private <K extends Exception> boolean getBatchingVisitableFromIterator( TableReference tableRef, RangeRequest range, int userRequestedSize, AbortingVisitor<List<RowResult<byte[]>>, K> visitor, int preFilterBatchSize) throws K { ClosableIterator<RowResult<byte[]>> postFilterIterator = postFilterIterator(tableRef, range, preFilterBatchSize, Value.GET_VALUE); try { Iterator<RowResult<byte[]>> localWritesInRange = Cells.createRowView( getLocalWritesForRange(tableRef, range.getStartInclusive(), range.getEndExclusive()).entrySet()); Iterator<RowResult<byte[]>> mergeIterators = mergeInLocalWritesRows(postFilterIterator, localWritesInRange, range.isReverse()); return BatchingVisitableFromIterable.create(mergeIterators).batchAccept(userRequestedSize, visitor); } finally { postFilterIterator.close(); } }
@Test public void testRowRangeSecondColumn() { AbstractTransaction transaction = mock(AbstractTransaction.class); Cell expectedCell = getCell(TEST_ROW_KEY, SECOND_COL_SHORT_NAME); Cell anotherExpectedCell = getCell(TEST_ROW_KEY2, SECOND_COL_SHORT_NAME); RangeRequest expectedRange = RangeRequest.builder() .startRowInclusive(TEST_ROW_KEY.getBytes()) .endRowExclusive(RANGE_END_ROW_KEY.getBytes()) .retainColumns(SECOND_COLUMN_SELECTION) .build(); when(transaction.getRange(tableRef, expectedRange)).thenReturn( BatchingVisitableFromIterable.create(Arrays.asList( RowResult.of(expectedCell, STRING_VALUE_PERSISTER.persistToBytes(TEST_VALUE_STRING)), RowResult.of(anotherExpectedCell, STRING_VALUE_PERSISTER.persistToBytes(TEST_VALUE_STRING2)) )) ); Map<String, StringValue> result = getRangeSecondColumn(transaction, TEST_ROW_KEY, RANGE_END_ROW_KEY); assertThat(result) .isEqualTo(ImmutableMap.of(TEST_ROW_KEY, TEST_VALUE_STRING, TEST_ROW_KEY2, TEST_VALUE_STRING2)); verify(transaction, times(1)).getRange(tableRef, expectedRange); }
@Test public void testRowRangeSecondColumnFirstTwoResults() { AbstractTransaction transaction = mock(AbstractTransaction.class); Cell expectedCell = getCell(TEST_ROW_KEY, SECOND_COL_SHORT_NAME); Cell anotherExpectedCell = getCell(TEST_ROW_KEY2, SECOND_COL_SHORT_NAME); Cell cellToBeDroppedFromResults = getCell(TEST_ROW_KEY3, SECOND_COL_SHORT_NAME); RangeRequest expectedRange = RangeRequest.builder() .startRowInclusive(TEST_ROW_KEY.getBytes()) .endRowExclusive(RANGE_END_ROW_KEY.getBytes()) .retainColumns(SECOND_COLUMN_SELECTION) .batchHint(2) .build(); when(transaction.getRange(tableRef, expectedRange)).thenReturn( BatchingVisitableFromIterable.create(Arrays.asList( RowResult.of(expectedCell, STRING_VALUE_PERSISTER.persistToBytes(TEST_VALUE_STRING)), RowResult.of(anotherExpectedCell, STRING_VALUE_PERSISTER.persistToBytes(TEST_VALUE_STRING2)), RowResult.of(cellToBeDroppedFromResults, STRING_VALUE_PERSISTER.persistToBytes(TEST_VALUE_STRING3)) )) ); Map<String, StringValue> result = getRangeSecondColumnOnlyFirstTwoResults(transaction, TEST_ROW_KEY, RANGE_END_ROW_KEY); assertThat(result) .isEqualTo(ImmutableMap.of(TEST_ROW_KEY, TEST_VALUE_STRING, TEST_ROW_KEY2, TEST_VALUE_STRING2)); verify(transaction, times(1)).getRange(tableRef, expectedRange); }
/** * This creates a one time use visitable. The only proper use of the returned class is to call * accept on it directly and never reference it again. */ @SuppressWarnings("unchecked") public static <T> BatchingVisitable<T> create(final Iterator<? extends T> iterator) { return SingleCallProxy.newProxyInstance(BatchingVisitable.class, create((Iterable<T>) () -> IteratorUtils.wrap(iterator)) ); }
@Override public Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> getRowsColumnRange( TableReference tableRef, Iterable<byte[]> rows, BatchColumnRangeSelection columnRangeSelection) { checkGetPreconditions(tableRef); if (Iterables.isEmpty(rows)) { return ImmutableMap.of(); } hasReads = true; Map<byte[], RowColumnRangeIterator> rawResults = keyValueService.getRowsColumnRange(tableRef, rows, columnRangeSelection, getStartTimestamp()); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> postFilteredResults = Maps.newHashMapWithExpectedSize(rawResults.size()); for (Entry<byte[], RowColumnRangeIterator> e : rawResults.entrySet()) { byte[] row = e.getKey(); RowColumnRangeIterator rawIterator = e.getValue(); Iterator<Map.Entry<Cell, byte[]>> postFilteredIterator = getPostFilteredColumns(tableRef, columnRangeSelection, row, rawIterator); postFilteredResults.put(row, BatchingVisitableFromIterable.create(postFilteredIterator)); } return postFilteredResults; }
@Override protected <K extends Exception> void batchAcceptSizeHint( int batchSizeHint, ConsistentVisitor<SortedMap<Long, Multimap<TableReference, Cell>>, K> visitor) throws K { ClosableIterator<RowResult<Value>> iterator = getIteratorToScrub(batchSizeHint, maxScrubTimestamp, startRow, endRow); try { BatchingVisitableFromIterable.create(iterator).batchAccept( batchSizeHint, batch -> visitor.visitOne(transformRows(batch))); } finally { iterator.close(); } } };
private <K extends Exception> boolean getBatchingVisitableFromIterator( TableReference tableRef, RangeRequest range, int userRequestedSize, AbortingVisitor<List<RowResult<byte[]>>, K> visitor, int preFilterBatchSize) throws K { ClosableIterator<RowResult<byte[]>> postFilterIterator = postFilterIterator(tableRef, range, preFilterBatchSize, Value.GET_VALUE); try { Iterator<RowResult<byte[]>> localWritesInRange = Cells.createRowView( getLocalWritesForRange(tableRef, range.getStartInclusive(), range.getEndExclusive()).entrySet()); Iterator<RowResult<byte[]>> mergeIterators = mergeInLocalWritesRows(postFilterIterator, localWritesInRange, range.isReverse()); return BatchingVisitableFromIterable.create(mergeIterators).batchAccept(userRequestedSize, visitor); } finally { postFilterIterator.close(); } }