use of com.palantir.atlasdb.keyvalue.api.CandidateCellForSweeping in project atlasdb by palantir.
the class GetCandidateCellsForSweepingShim method getCandidateCellsForSweeping.
public ClosableIterator<List<CandidateCellForSweeping>> getCandidateCellsForSweeping(TableReference tableRef, CandidateCellForSweepingRequest request) {
RangeRequest range = RangeRequest.builder().startRowInclusive(request.startRowInclusive()).batchHint(request.batchSizeHint().orElse(AtlasDbConstants.DEFAULT_SWEEP_CANDIDATE_BATCH_HINT)).build();
try (ReleasableCloseable<ClosableIterator<RowResult<Value>>> valueResults = new ReleasableCloseable<>(getValues(tableRef, range, request.maxTimestampExclusive(), request.shouldCheckIfLatestValueIsEmpty()));
ReleasableCloseable<ClosableIterator<RowResult<Set<Long>>>> tsResults = new ReleasableCloseable<>(keyValueService.getRangeOfTimestamps(tableRef, range, request.maxTimestampExclusive()))) {
PeekingIterator<RowResult<Value>> peekingValues = Iterators.peekingIterator(valueResults.get());
Iterator<List<RowResult<Set<Long>>>> tsBatches = Iterators.partition(tsResults.get(), range.getBatchHint());
Iterator<List<CandidateCellForSweeping>> candidates = Iterators.transform(tsBatches, tsBatch -> {
List<CandidateCellForSweeping> candidateBatch = Lists.newArrayList();
for (RowResult<Set<Long>> rr : tsBatch) {
for (Map.Entry<byte[], Set<Long>> e : rr.getColumns().entrySet()) {
byte[] colName = e.getKey();
List<Long> sortedTimestamps = e.getValue().stream().filter(request::shouldSweep).sorted().collect(Collectors.toList());
Cell cell = Cell.create(rr.getRowName(), colName);
boolean latestValEmpty = isLatestValueEmpty(cell, peekingValues);
candidateBatch.add(ImmutableCandidateCellForSweeping.builder().cell(cell).sortedTimestamps(sortedTimestamps).isLatestValueEmpty(latestValEmpty).build());
}
}
return candidateBatch;
});
Closer closer = createCloserAndRelease(valueResults, tsResults);
return ClosableIterators.wrap(candidates, closer);
}
}
use of com.palantir.atlasdb.keyvalue.api.CandidateCellForSweeping in project atlasdb by palantir.
the class SweepableCellFilterTest method thorough_getTimestampsToSweep_oneTransaction_emptyValue_returnsIt.
@Test
public void thorough_getTimestampsToSweep_oneTransaction_emptyValue_returnsIt() {
List<CandidateCellForSweeping> candidate = ImmutableList.of(ImmutableCandidateCellForSweeping.builder().cell(SINGLE_CELL).sortedTimestamps(ImmutableList.of(LOW_START_TS)).isLatestValueEmpty(true).build());
when(mockTransactionService.get(anyCollection())).thenReturn(ImmutableMap.of(LOW_START_TS, LOW_COMMIT_TS));
SweepableCellFilter filter = new SweepableCellFilter(mockTransactionService, Sweeper.THOROUGH, HIGH_START_TS);
List<CellToSweep> cells = filter.getCellsToSweep(candidate).cells();
assertThat(cells.size()).isEqualTo(1);
assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).isEqualTo(new TLongArrayList(new long[] { LOW_START_TS }));
}
use of com.palantir.atlasdb.keyvalue.api.CandidateCellForSweeping in project atlasdb by palantir.
the class SweepableCellFilterTest method conservative_getTimestampsToSweep_twoEntriesBelowSweepTimestamp_returnsLowerOne.
@Test
public void conservative_getTimestampsToSweep_twoEntriesBelowSweepTimestamp_returnsLowerOne() {
long sweepTimestampHigherThanCommitTimestamp = HIGH_COMMIT_TS + 1;
List<CandidateCellForSweeping> candidates = twoCommittedTimestampsForSingleCell();
SweepableCellFilter filter = new SweepableCellFilter(mockTransactionService, Sweeper.CONSERVATIVE, sweepTimestampHigherThanCommitTimestamp);
List<CellToSweep> cells = filter.getCellsToSweep(candidates).cells();
assertThat(cells.size()).isEqualTo(1);
assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).isEqualTo(new TLongArrayList(new long[] { LOW_START_TS }));
}
use of com.palantir.atlasdb.keyvalue.api.CandidateCellForSweeping in project atlasdb by palantir.
the class SweepableCellFilterTest method getTimestampsToSweep_onlyTransactionUncommitted_returnsIt.
@Test
public void getTimestampsToSweep_onlyTransactionUncommitted_returnsIt() {
List<CandidateCellForSweeping> candidate = ImmutableList.of(ImmutableCandidateCellForSweeping.builder().cell(SINGLE_CELL).sortedTimestamps(ImmutableList.of(LOW_START_TS)).isLatestValueEmpty(false).build());
when(mockTransactionService.get(anyCollection())).thenReturn(ImmutableMap.of(LOW_START_TS, TransactionConstants.FAILED_COMMIT_TS));
SweepableCellFilter filter = new SweepableCellFilter(mockTransactionService, Sweeper.CONSERVATIVE, HIGH_START_TS);
List<CellToSweep> cells = filter.getCellsToSweep(candidate).cells();
assertThat(cells.size()).isEqualTo(1);
assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).isEqualTo(new TLongArrayList(new long[] { LOW_START_TS }));
}
use of com.palantir.atlasdb.keyvalue.api.CandidateCellForSweeping in project atlasdb by palantir.
the class SweepableCellFilter method getCellsToSweep.
// For a given list of candidates, decide which ones we should actually sweep.
// Here we need to load the commit timestamps, and it's important to do that in bulk
// to reduce the number of round trips to the database.
public BatchOfCellsToSweep getCellsToSweep(List<CandidateCellForSweeping> candidates) {
Preconditions.checkArgument(!candidates.isEmpty(), "Got an empty collection of candidates. This is a programming error.");
CommitTsLoader commitTss = CommitTsLoader.create(transactionService, getAllTimestamps(candidates));
ImmutableBatchOfCellsToSweep.Builder builder = ImmutableBatchOfCellsToSweep.builder();
long numCellTsPairsExamined = 0;
Cell lastCellExamined = null;
for (CandidateCellForSweeping candidate : candidates) {
if (candidate.sortedTimestamps().size() > 0) {
CellToSweep cellToSweep = getCellToSweep(candidate, commitTss);
if (cellToSweep != null) {
builder.addCells(cellToSweep);
}
}
numCellTsPairsExamined += candidate.sortedTimestamps().size();
lastCellExamined = candidate.cell();
}
return builder.numCellTsPairsExamined(numCellTsPairsExamined).lastCellExamined(lastCellExamined).build();
}
Aggregations