use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class DbKvs method getRangeOfTimestamps.
/**
* @param tableRef the name of the table to read from.
* @param rangeRequest the range to load.
* @param timestamp the maximum timestamp to load.
*
* @return Each row that has fewer than maxRangeOfTimestampsBatchSize entries is guaranteed to be returned in a
* single RowResult. If a row has more than maxRangeOfTimestampsBatchSize results, it will potentially be split
* into multiple RowResults, by finishing the current column; see example below. Note that:
* 1) this may cause a RowResult to have more than maxRangeOfTimestampsBatchSize entries
* 2) this may still finish a row, in which case there is going to be only one RowResult for that row.
* It is, furthermore, guaranteed that the columns will be read in ascending order
*
* E.g., for the following table, rangeRequest taking all rows in ascending order,
* maxRangeOfTimestampsBatchSize == 5, and timestamp 10:
*
* a | b | c | d
* ------------------------------------------------
* a | (1, 2, 3) | (1, 2, 3) | (4, 5, 6) | (4, 5, 6)|
* ------------------------------------------------
* b | (1, 3, 5) | - | (1) | - |
* ------------------------------------------------
* c | (1, 2) | (1, 2) | (4, 5, 6) | (4, 5, 6)|
* ------------------------------------------------
* d | (1, 3, 5) | - | (1, 2, 3) | - |
* ------------------------------------------------
* e | (1, 3) | - | - | - |
* ------------------------------------------------
*
* The RowResults will be:
* 1. (a, (a -> 1, 2, 3; b -> 1, 2, 3))
* 2. (a, (c -> 4, 5, 6; d -> 4, 5, 6))
*
* 3. (b, (a -> 1, 3, 5; b -> 1))
*
* 4. (c, (a -> 1, 2, b -> 1, 2; c -> 4, 5, 6))
* 5. (c, (d -> 4, 5, 6))
*
* 6. (d, (a -> 1, 3, 5, c -> 1, 2, 3))
*
* 7. (e, (a -> 1, 3))
*/
@Override
public ClosableIterator<RowResult<Set<Long>>> getRangeOfTimestamps(TableReference tableRef, RangeRequest rangeRequest, long timestamp) {
Iterable<RowResult<Set<Long>>> rows = new AbstractPagingIterable<RowResult<Set<Long>>, TokenBackedBasicResultsPage<RowResult<Set<Long>>, Token>>() {
@Override
protected TokenBackedBasicResultsPage<RowResult<Set<Long>>, Token> getFirstPage() {
return getTimestampsPage(tableRef, rangeRequest, timestamp, maxRangeOfTimestampsBatchSize, Token.INITIAL);
}
@Override
protected TokenBackedBasicResultsPage<RowResult<Set<Long>>, Token> getNextPage(TokenBackedBasicResultsPage<RowResult<Set<Long>>, Token> previous) {
Token token = previous.getTokenForNextPage();
RangeRequest newRange = rangeRequest.getBuilder().startRowInclusive(token.row()).build();
return getTimestampsPage(tableRef, newRange, timestamp, maxRangeOfTimestampsBatchSize, token);
}
};
return ClosableIterators.wrap(rows.iterator());
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class DbKvs method getRowColumnRange.
private Iterator<Map.Entry<Cell, Value>> getRowColumnRange(TableReference tableRef, byte[] row, BatchColumnRangeSelection batchColumnRangeSelection, long timestamp) {
List<byte[]> rowList = ImmutableList.of(row);
return ClosableIterators.wrap(new AbstractPagingIterable<Entry<Cell, Value>, TokenBackedBasicResultsPage<Entry<Cell, Value>, byte[]>>() {
@Override
protected TokenBackedBasicResultsPage<Entry<Cell, Value>, byte[]> getFirstPage() throws Exception {
return page(batchColumnRangeSelection.getStartCol());
}
@Override
protected TokenBackedBasicResultsPage<Map.Entry<Cell, Value>, byte[]> getNextPage(TokenBackedBasicResultsPage<Map.Entry<Cell, Value>, byte[]> previous) throws Exception {
return page(previous.getTokenForNextPage());
}
TokenBackedBasicResultsPage<Map.Entry<Cell, Value>, byte[]> page(byte[] startCol) throws Exception {
BatchColumnRangeSelection range = BatchColumnRangeSelection.create(startCol, batchColumnRangeSelection.getEndCol(), batchColumnRangeSelection.getBatchHint());
List<Map.Entry<Cell, Value>> nextPage = Iterables.getOnlyElement(extractRowColumnRangePage(tableRef, range, timestamp, rowList).values());
if (nextPage.isEmpty()) {
return SimpleTokenBackedResultsPage.create(startCol, ImmutableList.<Entry<Cell, Value>>of(), false);
}
byte[] lastCol = nextPage.get(nextPage.size() - 1).getKey().getColumnName();
if (isEndOfColumnRange(lastCol, batchColumnRangeSelection.getEndCol())) {
return SimpleTokenBackedResultsPage.create(lastCol, nextPage, false);
}
byte[] nextCol = RangeRequests.nextLexicographicName(lastCol);
return SimpleTokenBackedResultsPage.create(nextCol, nextPage, true);
}
}.iterator());
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class DbKvsGetRanges method breakUpByBatch.
/**
* This tablehod expects the input to be sorted by rowname ASC for both rowsForBatches and
* cellsByRow.
*/
private Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> breakUpByBatch(List<RangeRequest> requests, SortedSetMultimap<Integer, byte[]> rowsForBatches, NavigableMap<byte[], SortedMap<byte[], Value>> cellsByRow) {
Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ret = Maps.newHashMap();
for (int i = 0; i < requests.size(); i++) {
RangeRequest request = requests.get(i);
if (ret.containsKey(request)) {
continue;
}
SortedSet<byte[]> rowNames = rowsForBatches.get(i);
SortedMap<byte[], SortedMap<byte[], Value>> cellsForBatch = Maps.filterKeys(request.isReverse() ? cellsByRow.descendingMap() : cellsByRow, Predicates.in(rowNames));
validateRowNames(cellsForBatch.keySet(), request.getStartInclusive(), request.getEndExclusive(), request.isReverse());
IterableView<RowResult<Value>> rows = RowResults.viewOfMap(cellsForBatch);
if (!request.getColumnNames().isEmpty()) {
rows = filterColumnSelection(rows, request);
}
if (rowNames.isEmpty()) {
assert rows.isEmpty();
ret.put(request, SimpleTokenBackedResultsPage.create(request.getEndExclusive(), rows, false));
} else {
byte[] last = rowNames.last();
if (request.isReverse()) {
last = rowNames.first();
}
if (RangeRequests.isTerminalRow(request.isReverse(), last)) {
ret.put(request, SimpleTokenBackedResultsPage.create(last, rows, false));
} else {
// If rowNames isn't a whole batch we know we don't have any more results.
boolean hasMore = request.getBatchHint() == null || request.getBatchHint() <= rowNames.size();
byte[] nextStartRow = RangeRequests.getNextStartRow(request.isReverse(), last);
ret.put(request, SimpleTokenBackedResultsPage.create(nextStartRow, rows, hasMore));
}
}
}
return ret;
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class AbstractTransactionTest method testRangePagingBatchSizeOneReverse.
@Test
public void testRangePagingBatchSizeOneReverse() {
if (!supportsReverse()) {
return;
}
int totalPuts = 100;
for (int i = 0; i < totalPuts; i++) {
putDirect("row" + i, "col1", "v1", 0);
}
RangeRequest rangeRequest = RangeRequest.reverseBuilder().batchHint(1).build();
Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ranges = keyValueService.getFirstBatchForRanges(TEST_TABLE, Iterables.limit(Iterables.cycle(rangeRequest), 100), 1);
assertEquals(1, ranges.keySet().size());
assertEquals(1, ranges.values().iterator().next().getResults().size());
assertEquals("row99", PtBytes.toString(ranges.values().iterator().next().getResults().iterator().next().getRowName()));
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class AbstractTransactionTest method testKeyValueRanges2.
@Test
public void testKeyValueRanges2() {
putDirect("row1", "col1", "", 0);
putDirect("row2", "col1", "", 0);
putDirect("row2", "col2", "", 0);
final RangeRequest allRange = RangeRequest.builder().build();
final RangeRequest oneRange = RangeRequest.builder().startRowInclusive("row2".getBytes()).build();
final RangeRequest allRangeBatch = RangeRequest.builder().batchHint(3).build();
Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ranges = keyValueService.getFirstBatchForRanges(TEST_TABLE, ImmutableList.of(allRange, oneRange, allRangeBatch), 1);
assertTrue(ranges.get(allRange).getResults().size() >= 1);
assertEquals(2, ranges.get(allRangeBatch).getResults().size());
assertFalse(ranges.get(allRangeBatch).moreResultsAvailable());
assertEquals(1, ranges.get(oneRange).getResults().size());
}
Aggregations