default CandidateCellForSweeping toSweepCandidate( Predicate<Long> shouldSweepTimestampPredicate, boolean latestValueEmpty) { List<Long> filteredTimestamps = sortedTimestamps().stream() .filter(shouldSweepTimestampPredicate) .collect(Collectors.toList()); return ImmutableCandidateCellForSweeping.builder() .cell(cell()) .sortedTimestamps(filteredTimestamps) .isLatestValueEmpty(latestValueEmpty) .build(); } }
@Before @SuppressWarnings("unchecked") public void setup() { Map<Long, Long> startTsToCommitTs = new HashMap<>(); COMMITTED_BEFORE.forEach(startTs -> startTsToCommitTs.put(startTs, startTs)); COMMITTED_AFTER.forEach(startTs -> startTsToCommitTs.put(startTs, startTs + SWEEP_TS)); ABORTED_TS.forEach(startTs -> startTsToCommitTs.put(startTs, TransactionConstants.FAILED_COMMIT_TS)); startTsToCommitTs.put(LAST_TS, status.commitTs); when(mockTransactionService.get(anyCollection())).thenReturn(startTsToCommitTs); candidate = ImmutableList.of(ImmutableCandidateCellForSweeping.builder() .cell(SINGLE_CELL) .sortedTimestamps(ImmutableList.sortedCopyOf(startTsToCommitTs.keySet())) .isLatestValueEmpty(lastIsTombstone) .build()); }
@Test public void thorough_getTimestampsToSweep_oneSentinel_returnsIt() { List<CandidateCellForSweeping> candidate = ImmutableList.of( ImmutableCandidateCellForSweeping.builder() .cell(SINGLE_CELL) .sortedTimestamps(ImmutableList.of(Value.INVALID_VALUE_TIMESTAMP)) .isLatestValueEmpty(true) .build()); when(mockTransactionService.get(anyCollection())) .thenReturn(ImmutableMap.of()); SweepableCellFilter filter = new SweepableCellFilter( commitTsCache, Sweeper.THOROUGH, HIGH_START_TS); List<CellToSweep> cells = filter.getCellsToSweep(candidate).cells(); assertThat(cells.size()).isEqualTo(1); assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).containsExactly(Value.INVALID_VALUE_TIMESTAMP); }
default CandidateCellForSweeping toSweepCandidate( Predicate<Long> shouldSweepTimestampPredicate, boolean latestValueEmpty) { List<Long> filteredTimestamps = sortedTimestamps().stream() .filter(shouldSweepTimestampPredicate) .collect(Collectors.toList()); return ImmutableCandidateCellForSweeping.builder() .cell(cell()) .sortedTimestamps(filteredTimestamps) .isLatestValueEmpty(latestValueEmpty) .build(); } }
private Optional<CandidateCellForSweeping> getCurrentCandidate() { if (currentCellTimestamps.isEmpty()) { return Optional.empty(); } else { return Optional.of(ImmutableCandidateCellForSweeping.builder() .cell(Cell.create(currentRowName, currentColName)) .sortedTimestamps(toList(currentCellTimestamps)) .isLatestValueEmpty(currentIsLatestValueEmpty) .build()); } }
static CandidateCellForSweeping of(Cell cell, Collection<Long> sortedTimestamps) { return ImmutableCandidateCellForSweeping.builder() .sortedTimestamps(sortedTimestamps) .cell(cell) .build(); }
candidateBatch.add(ImmutableCandidateCellForSweeping.builder() .cell(cell) .sortedTimestamps(sortedTimestamps) .isLatestValueEmpty(latestValEmpty) .build());
@Test public void reportLatestEmptyValueLessThanSweepTs() { new TestDataBuilder() .put(1, 1, 5L) .putEmpty(1, 1, 10L) .putEmpty(2, 2, 5L) .put(2, 2, 10L) .store(); assertThat(getAllCandidates(thoroughRequest(PtBytes.EMPTY_BYTE_ARRAY, 8L, 100))) .containsExactly( ImmutableCandidateCellForSweeping.builder() .cell(cell(1, 1)) .sortedTimestamps(ImmutableList.of(5L)) .isLatestValueEmpty(false) .build(), ImmutableCandidateCellForSweeping.builder() .cell(cell(2, 2)) .sortedTimestamps(ImmutableList.of(5L)) .isLatestValueEmpty(true) .build()); }
@Test public void reportLatestEmptyValue() { new TestDataBuilder() .putEmpty(1, 1, 10L) .put(1, 1, 5L) .put(2, 2, 9L) .putEmpty(2, 2, 4L) .store(); assertThat(getAllCandidates(thoroughRequest(PtBytes.EMPTY_BYTE_ARRAY, 40L, 100))) .containsExactly( ImmutableCandidateCellForSweeping.builder() .cell(cell(1, 1)) .sortedTimestamps(ImmutableList.of(5L, 10L)) .isLatestValueEmpty(true) .build(), ImmutableCandidateCellForSweeping.builder() .cell(cell(2, 2)) .sortedTimestamps(ImmutableList.of(4L, 9L)) .isLatestValueEmpty(false) .build()); }
@Test public void singleCellSpanningSeveralPages() { new TestDataBuilder() .put(10, 1, 1000L) .put(10, 1, 1001L) .put(10, 1, 1002L) .put(10, 1, 1003L) .put(10, 1, 1004L) .store(); List<CandidateCellForSweeping> cells = getAllCandidates( conservativeRequest(PtBytes.EMPTY_BYTE_ARRAY, 2000L, 2)); assertEquals(ImmutableList.of(ImmutableCandidateCellForSweeping.builder() .cell(cell(10, 1)) .isLatestValueEmpty(false) .sortedTimestamps(ImmutableList.of(1000L, 1001L, 1002L, 1003L, 1004L)) .build()), cells); }
@Test public void testTwoCandidates() { long sweepTimestampHigherThanCommitTimestamp = HIGH_COMMIT_TS + 1; CandidateCellForSweeping snd = ImmutableCandidateCellForSweeping.builder() .cell(ANOTHER_CELL) .sortedTimestamps(ImmutableList.of(HIGH_START_TS)) .isLatestValueEmpty(true) .build(); List<CandidateCellForSweeping> candidates = ImmutableList.of(twoCommittedTimestampsForSingleCell().get(0), snd); SweepableCellFilter filter = new SweepableCellFilter( commitTsCache, Sweeper.THOROUGH, sweepTimestampHigherThanCommitTimestamp); BatchOfCellsToSweep result = filter.getCellsToSweep(candidates); assertThat(result.lastCellExamined()).isEqualTo(ANOTHER_CELL); assertThat(result.cells().size()).isEqualTo(2); assertThat(result.numCellTsPairsExamined()).isEqualTo(3L); assertThat(result.cells().get(0).sortedTimestamps()).containsExactly(LOW_START_TS); assertThat(result.cells().get(1).sortedTimestamps()).containsExactly(HIGH_START_TS); }
@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( commitTsCache, Sweeper.THOROUGH, HIGH_START_TS); List<CellToSweep> cells = filter.getCellsToSweep(candidate).cells(); assertThat(cells.size()).isEqualTo(1); assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).containsExactly(LOW_START_TS); }
@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( commitTsCache, Sweeper.CONSERVATIVE, HIGH_START_TS); List<CellToSweep> cells = filter.getCellsToSweep(candidate).cells(); assertThat(cells.size()).isEqualTo(1); assertThat(Iterables.getOnlyElement(cells).sortedTimestamps()).containsExactly(LOW_START_TS); }
@Test public void testNoCandidates() { List<CandidateCellForSweeping> candidate = ImmutableList.of( ImmutableCandidateCellForSweeping.builder() .cell(SINGLE_CELL) .sortedTimestamps(ImmutableList.of()) .isLatestValueEmpty(true) .build()); SweepableCellFilter filter = new SweepableCellFilter( commitTsCache, Sweeper.CONSERVATIVE, 100L); BatchOfCellsToSweep result = filter.getCellsToSweep(candidate); assertThat(result.lastCellExamined()).isEqualTo(SINGLE_CELL); assertThat(result.cells()).isEmpty(); assertThat(result.numCellTsPairsExamined()).isEqualTo(0L); }
private List<CandidateCellForSweeping> twoCommittedTimestampsForSingleCell() { List<CandidateCellForSweeping> ret = ImmutableList.of( ImmutableCandidateCellForSweeping.builder() .cell(SINGLE_CELL) .sortedTimestamps(ImmutableList.of(LOW_START_TS, HIGH_START_TS)) .isLatestValueEmpty(false) .build()); when(mockTransactionService.get(anyCollection())) .thenReturn(ImmutableMap.of( LOW_START_TS, LOW_COMMIT_TS, HIGH_START_TS, HIGH_COMMIT_TS)); return ret; } }
private static CandidateCellForSweeping candidate(String rowName, String colName, long numCellTsPairsExamined, boolean latestValEmpty, Long... ts) { Arrays.sort(ts); return ImmutableCandidateCellForSweeping.builder() .cell(Cell.create(bytes(rowName), bytes(colName))) .isLatestValueEmpty(latestValEmpty) .sortedTimestamps(Arrays.asList(ts)) .build(); }
@Test public void returnCandidateIfTwoCommittedTimestamps() { new TestDataBuilder().put(1, 1, 10L).put(1, 1, 20L).store(); assertThat(getAllCandidates(conservativeRequest(PtBytes.EMPTY_BYTE_ARRAY, 40L, 1))) .containsExactly(ImmutableCandidateCellForSweeping.builder() .cell(cell(1, 1)) .sortedTimestamps(ImmutableList.of(10L, 20L)) .isLatestValueEmpty(false) .build()); } }
@Test public void returnCandidateIfPossiblyUncommittedTimestamp() { new TestDataBuilder().put(1, 1, 10L).store(); assertThat(getAllCandidates(conservativeRequest(PtBytes.EMPTY_BYTE_ARRAY, 40L, 1))) .containsExactly(ImmutableCandidateCellForSweeping.builder() .cell(cell(1, 1)) .sortedTimestamps(ImmutableList.of(10L)) .isLatestValueEmpty(false) .build()); }
static CandidateCellForSweeping of(Cell cell, Collection<Long> sortedTimestamps) { return ImmutableCandidateCellForSweeping.builder() .sortedTimestamps(sortedTimestamps) .cell(cell) .build(); }
private Optional<CandidateCellForSweeping> getCurrentCandidate() { if (currentCellTimestamps.isEmpty()) { return Optional.empty(); } else { return Optional.of(ImmutableCandidateCellForSweeping.builder() .cell(Cell.create(currentRowName, currentColName)) .sortedTimestamps(toList(currentCellTimestamps)) .isLatestValueEmpty(currentIsLatestValueEmpty) .build()); } }