use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.
the class InMemoryKeyValueService method getRows.
@Override
// Consume all remaining values of iterator.
@SuppressWarnings({ "CheckReturnValue" })
public Map<Cell, Value> getRows(TableReference tableRef, Iterable<byte[]> rows, ColumnSelection columnSelection, long timestamp) {
Map<Cell, Value> result = Maps.newHashMap();
ConcurrentSkipListMap<Key, byte[]> table = getTableMap(tableRef).entries;
for (byte[] row : rows) {
Cell rowBegin = Cells.createSmallestCellForRow(row);
Cell rowEnd = Cells.createLargestCellForRow(row);
PeekingIterator<Entry<Key, byte[]>> entries = Iterators.peekingIterator(table.subMap(new Key(rowBegin, Long.MIN_VALUE), new Key(rowEnd, timestamp)).entrySet().iterator());
while (entries.hasNext()) {
Entry<Key, byte[]> entry = entries.peek();
Key key = entry.getKey();
Iterator<Entry<Key, byte[]>> cellIter = takeCell(entries, key);
if (columnSelection.contains(key.col)) {
getLatestVersionOfCell(row, key, cellIter, timestamp, result);
}
Iterators.size(cellIter);
}
}
return result;
}
use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.
the class KeyValueServices method getFirstBatchForRangesUsingGetRangeConcurrent.
@SuppressWarnings("checkstyle:LineLength")
public static Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> getFirstBatchForRangesUsingGetRangeConcurrent(ExecutorService executor, final KeyValueService kv, final TableReference tableRef, Iterable<RangeRequest> rangeRequests, final long timestamp, int maxConcurrentRequests) {
final Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ret = Maps.newConcurrentMap();
BlockingWorkerPool pool = new BlockingWorkerPool(executor, maxConcurrentRequests);
try {
for (final RangeRequest request : rangeRequests) {
pool.submitTask(() -> getFirstBatchForRangeUsingGetRange(kv, tableRef, request, timestamp, ret));
}
pool.waitForSubmittedTasks();
return ret;
} catch (InterruptedException e) {
throw Throwables.rewrapAndThrowUncheckedException(e);
}
}
use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.
the class KeyValueServices method getFirstBatchForRangeUsingGetRange.
public static void getFirstBatchForRangeUsingGetRange(KeyValueService kv, TableReference tableRef, RangeRequest request, long timestamp, @Output Map<RangeRequest, TokenBackedBasicResultsPage<RowResult<Value>, byte[]>> ret) {
if (ret.containsKey(request)) {
return;
}
RangeRequest requestWithHint = request;
if (request.getBatchHint() == null) {
requestWithHint = request.withBatchHint(100);
}
final ClosableIterator<RowResult<Value>> range = kv.getRange(tableRef, requestWithHint, timestamp);
try {
int batchSize = requestWithHint.getBatchHint();
final Iterator<RowResult<Value>> withLimit = Iterators.limit(range, batchSize);
ImmutableList<RowResult<Value>> results = ImmutableList.copyOf(withLimit);
if (results.size() != batchSize) {
ret.put(request, SimpleTokenBackedResultsPage.create(request.getEndExclusive(), results, false));
return;
}
RowResult<Value> last = results.get(results.size() - 1);
byte[] lastRowName = last.getRowName();
if (RangeRequests.isTerminalRow(request.isReverse(), lastRowName)) {
ret.put(request, SimpleTokenBackedResultsPage.create(lastRowName, results, false));
return;
}
byte[] nextStartRow = RangeRequests.getNextStartRow(request.isReverse(), lastRowName);
if (Arrays.equals(request.getEndExclusive(), nextStartRow)) {
ret.put(request, SimpleTokenBackedResultsPage.create(nextStartRow, results, false));
} else {
ret.put(request, SimpleTokenBackedResultsPage.create(nextStartRow, results, true));
}
} finally {
range.close();
}
}
use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.
the class KeyValueServices method filterGetRowsToColumnRange.
// TODO(gsheasby): kill this when we can properly implement this on all KVSes
public static Map<byte[], RowColumnRangeIterator> filterGetRowsToColumnRange(KeyValueService kvs, TableReference tableRef, Iterable<byte[]> rows, BatchColumnRangeSelection columnRangeSelection, long timestamp) {
log.warn("Using inefficient postfiltering for getRowsColumnRange because the KVS doesn't support it natively. " + "Production environments should use a KVS with a proper implementation.");
Map<Cell, Value> allValues = kvs.getRows(tableRef, rows, ColumnSelection.all(), timestamp);
Map<Sha256Hash, byte[]> hashesToBytes = Maps.newHashMap();
Map<Sha256Hash, ImmutableSortedMap.Builder<byte[], Value>> rowsToColumns = Maps.newHashMap();
for (byte[] row : rows) {
Sha256Hash rowHash = Sha256Hash.computeHash(row);
hashesToBytes.put(rowHash, row);
ImmutableSortedMap.Builder<byte[], Value> builder = ImmutableSortedMap.<byte[], Value>orderedBy(UnsignedBytes.lexicographicalComparator());
rowsToColumns.put(rowHash, builder);
}
for (Map.Entry<Cell, Value> e : allValues.entrySet()) {
Sha256Hash rowHash = Sha256Hash.computeHash(e.getKey().getRowName());
rowsToColumns.get(rowHash).put(e.getKey().getColumnName(), e.getValue());
}
Map<byte[], RowColumnRangeIterator> results = Maps.newHashMap();
for (Map.Entry<Sha256Hash, ImmutableSortedMap.Builder<byte[], Value>> row : rowsToColumns.entrySet()) {
SortedMap<byte[], Value> map = row.getValue().build();
Set<Map.Entry<byte[], Value>> subMap;
if ((columnRangeSelection.getStartCol().length == 0) && (columnRangeSelection.getEndCol().length == 0)) {
subMap = map.entrySet();
} else if (columnRangeSelection.getStartCol().length == 0) {
subMap = map.headMap(columnRangeSelection.getEndCol()).entrySet();
} else if (columnRangeSelection.getEndCol().length == 0) {
subMap = map.tailMap(columnRangeSelection.getStartCol()).entrySet();
} else {
subMap = map.subMap(columnRangeSelection.getStartCol(), columnRangeSelection.getEndCol()).entrySet();
}
byte[] rowName = hashesToBytes.get(row.getKey());
results.put(hashesToBytes.get(row.getKey()), new LocalRowColumnRangeIterator(Iterators.transform(subMap.iterator(), e -> Pair.<Cell, Value>of(Cell.create(rowName, e.getKey()), e.getValue()))));
}
return results;
}
use of com.palantir.atlasdb.keyvalue.api.Value in project atlasdb by palantir.
the class CleanTransactionRange method executeTimestampCommand.
@Override
protected int executeTimestampCommand(AtlasDbServices services) {
KeyValueService kvs = services.getKeyValueService();
ClosableIterator<RowResult<Value>> range = kvs.getRange(TransactionConstants.TRANSACTION_TABLE, RangeRequest.all(), Long.MAX_VALUE);
Multimap<Cell, Long> toDelete = HashMultimap.create();
while (range.hasNext()) {
RowResult<Value> row = range.next();
byte[] rowName = row.getRowName();
long startTs = TransactionConstants.getTimestampForValue(rowName);
Value value;
try {
value = row.getOnlyColumnValue();
} catch (IllegalStateException e) {
// this should never happen
printer.error("Found a row in the transactions table that didn't have 1" + " and only 1 column value: start={}", SafeArg.of("startTs", startTs));
continue;
}
long commitTs = TransactionConstants.getTimestampForValue(value.getContents());
if (commitTs <= timestamp) {
// this is a valid transaction
continue;
}
printer.info("Found and cleaning possibly inconsistent transaction: [start={}, commit={}]", SafeArg.of("startTs", startTs), SafeArg.of("commitTs", commitTs));
Cell key = Cell.create(rowName, TransactionConstants.COMMIT_TS_COLUMN);
// value.getTimestamp() should always be 0L
toDelete.put(key, value.getTimestamp());
}
if (!toDelete.isEmpty()) {
kvs.delete(TransactionConstants.TRANSACTION_TABLE, toDelete);
printer.info("Delete completed.");
} else {
printer.info("Found no transactions after the given timestamp to delete.");
}
return 0;
}
Aggregations