use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class AbstractTransactionTest method testRangeAfterTimestampReverse.
@Test
public void testRangeAfterTimestampReverse() {
if (!supportsReverse()) {
return;
}
putDirect("row1", "col2", "", 0);
putDirect("row2", "col2", "", 0);
putDirect("row3", "col2", "", 5);
RangeRequest rangeRequest = RangeRequest.reverseBuilder().batchHint(1).build();
Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ranges = keyValueService.getFirstBatchForRanges(TEST_TABLE, Collections.singleton(rangeRequest), 1);
assertEquals(1, ranges.keySet().size());
TokenBackedBasicResultsPage<RowResult<Value>, byte[]> page = ranges.values().iterator().next();
assertTrue(page.moreResultsAvailable());
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class AbstractTransactionTest method testRangePagingBatchSizeOne.
@Test
public void testRangePagingBatchSizeOne() {
int totalPuts = 100;
for (int i = 0; i < totalPuts; i++) {
putDirect("row" + i, "col1", "v1", 0);
}
RangeRequest rangeRequest = RangeRequest.builder().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("row0", PtBytes.toString(ranges.values().iterator().next().getResults().iterator().next().getRowName()));
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class CqlKeyValueService method getRangeWithPageCreator.
public <T> ClosableIterator<RowResult<T>> getRangeWithPageCreator(TableReference tableRef, RangeRequest rangeRequest, long timestamp, com.datastax.driver.core.ConsistencyLevel consistency, Supplier<ResultsExtractor<T>> resultsExtractor) {
if (rangeRequest.isReverse()) {
throw new UnsupportedOperationException();
}
if (rangeRequest.isEmptyRange()) {
return ClosableIterators.wrap(ImmutableList.<RowResult<T>>of().iterator());
}
final int batchHint = rangeRequest.getBatchHint() == null ? 100 : rangeRequest.getBatchHint();
final ColumnSelection selection = rangeRequest.getColumnNames().isEmpty() ? ColumnSelection.all() : ColumnSelection.create(rangeRequest.getColumnNames());
final byte[] endExclusive = rangeRequest.getEndExclusive();
final StringBuilder bindQuery = new StringBuilder();
bindQuery.append("SELECT * FROM " + getFullTableName(tableRef) + " WHERE token(" + fieldNameProvider.row() + ") >= token(?) ");
if (endExclusive.length > 0) {
bindQuery.append("AND token(" + fieldNameProvider.row() + ") < token(?) ");
}
bindQuery.append("LIMIT " + batchHint);
final String getLastRowQuery = "SELECT * FROM " + getFullTableName(tableRef) + " WHERE " + fieldNameProvider.row() + " = ?";
return ClosableIterators.wrap(new AbstractPagingIterable<RowResult<T>, TokenBackedBasicResultsPage<RowResult<T>, byte[]>>() {
@Override
protected TokenBackedBasicResultsPage<RowResult<T>, byte[]> getFirstPage() throws Exception {
return getPage(rangeRequest.getStartInclusive());
}
@Override
protected TokenBackedBasicResultsPage<RowResult<T>, byte[]> getNextPage(TokenBackedBasicResultsPage<RowResult<T>, byte[]> previous) throws Exception {
return getPage(previous.getTokenForNextPage());
}
TokenBackedBasicResultsPage<RowResult<T>, byte[]> getPage(final byte[] startKey) throws Exception {
BoundStatement boundStatement = getPreparedStatement(tableRef, bindQuery.toString(), session).setConsistencyLevel(consistency).bind();
boundStatement.setBytes(0, ByteBuffer.wrap(startKey));
if (endExclusive.length > 0) {
boundStatement.setBytes(1, ByteBuffer.wrap(endExclusive));
}
ResultSet resultSet = session.execute(boundStatement);
List<Row> rows = Lists.newArrayList(resultSet.all());
cqlKeyValueServices.logTracedQuery(bindQuery.toString(), resultSet, session, cqlStatementCache.normalQuery);
byte[] maxRow = null;
ResultsExtractor<T> extractor = resultsExtractor.get();
for (Row row : rows) {
byte[] rowName = getRowName(row);
if (maxRow == null) {
maxRow = rowName;
} else {
maxRow = PtBytes.BYTES_COMPARATOR.max(maxRow, rowName);
}
}
if (maxRow == null) {
return new SimpleTokenBackedResultsPage<>(endExclusive, ImmutableList.of(), false);
}
// get the rest of the last row
BoundStatement boundLastRow = getPreparedStatement(tableRef, getLastRowQuery, session).bind();
boundLastRow.setBytes(fieldNameProvider.row(), ByteBuffer.wrap(maxRow));
try {
resultSet = session.execute(boundLastRow);
} catch (com.datastax.driver.core.exceptions.UnavailableException e) {
throw new InsufficientConsistencyException("This operation requires all Cassandra" + " nodes to be up and available.", e);
}
rows.addAll(resultSet.all());
cqlKeyValueServices.logTracedQuery(getLastRowQuery, resultSet, session, cqlStatementCache.normalQuery);
for (Row row : rows) {
extractor.internalExtractResult(timestamp, selection, getRowName(row), getColName(row), getValue(row), getTs(row));
}
SortedMap<byte[], SortedMap<byte[], T>> resultsByRow = Cells.breakCellsUpByRow(extractor.asMap());
return ResultsExtractor.getRowResults(endExclusive, maxRow, resultsByRow);
}
}.iterator());
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class JdbcKeyValueService method getRange.
@Override
public ClosableIterator<RowResult<Value>> getRange(final TableReference tableRef, final RangeRequest rangeRequest, final long timestamp) {
Iterable<RowResult<Value>> iter = new AbstractPagingIterable<RowResult<Value>, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>>() {
@Override
protected TokenBackedBasicResultsPage<RowResult<Value>, byte[]> getFirstPage() {
return getPageWithValues(tableRef, rangeRequest, timestamp);
}
@Override
protected TokenBackedBasicResultsPage<RowResult<Value>, byte[]> getNextPage(TokenBackedBasicResultsPage<RowResult<Value>, byte[]> previous) {
byte[] startRow = previous.getTokenForNextPage();
RangeRequest newRange = rangeRequest.getBuilder().startRowInclusive(startRow).build();
return getPageWithValues(tableRef, newRange, timestamp);
}
};
return ClosableIterators.wrap(iter.iterator());
}
use of com.palantir.util.paging.TokenBackedBasicResultsPage in project atlasdb by palantir.
the class SnapshotTransaction method getRanges.
@Override
public Iterable<BatchingVisitable<RowResult<byte[]>>> getRanges(final TableReference tableRef, Iterable<RangeRequest> rangeRequests) {
checkGetPreconditions(tableRef);
if (perfLogger.isDebugEnabled()) {
perfLogger.debug("Passed {} ranges to getRanges({}, {})", Iterables.size(rangeRequests), tableRef, rangeRequests);
}
if (!Iterables.isEmpty(rangeRequests)) {
hasReads = true;
}
return FluentIterable.from(Iterables.partition(rangeRequests, BATCH_SIZE_GET_FIRST_PAGE)).transformAndConcat(input -> {
Timer.Context timer = getTimer("processedRangeMillis").time();
Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> firstPages = keyValueService.getFirstBatchForRanges(tableRef, input, getStartTimestamp());
validateExternalAndCommitLocksIfNecessary(tableRef, getStartTimestamp());
SortedMap<Cell, byte[]> postFiltered = postFilterPages(tableRef, firstPages.values());
List<BatchingVisitable<RowResult<byte[]>>> ret = Lists.newArrayListWithCapacity(input.size());
for (RangeRequest rangeRequest : input) {
TokenBackedBasicResultsPage<RowResult<Value>, byte[]> prePostFilter = firstPages.get(rangeRequest);
byte[] nextStartRowName = getNextStartRowName(rangeRequest, prePostFilter);
List<Entry<Cell, byte[]>> mergeIterators = getPostFilteredWithLocalWrites(tableRef, postFiltered, rangeRequest, prePostFilter.getResults(), nextStartRowName);
ret.add(new AbstractBatchingVisitable<RowResult<byte[]>>() {
@Override
protected <K extends Exception> void batchAcceptSizeHint(int batchSizeHint, ConsistentVisitor<RowResult<byte[]>, K> visitor) throws K {
checkGetPreconditions(tableRef);
final Iterator<RowResult<byte[]>> rowResults = Cells.createRowView(mergeIterators);
while (rowResults.hasNext()) {
if (!visitor.visit(ImmutableList.of(rowResults.next()))) {
return;
}
}
if ((nextStartRowName.length == 0) || !prePostFilter.moreResultsAvailable()) {
return;
}
RangeRequest newRange = rangeRequest.getBuilder().startRowInclusive(nextStartRowName).build();
getRange(tableRef, newRange).batchAccept(batchSizeHint, visitor);
}
});
}
long processedRangeMillis = TimeUnit.NANOSECONDS.toMillis(timer.stop());
log.trace("Processed {} range requests for {} in {}ms", SafeArg.of("numRequests", input.size()), LoggingArgs.tableRef(tableRef), SafeArg.of("millis", processedRangeMillis));
return ret;
});
}
Aggregations