@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { delegate1.deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels); delegate2.deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels); }
@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { getDelegate(tableRef).deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels); }
@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { delegate().deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels); }
@Test public void deleteTimestampRangesIncludingSentinelsIgnoresEmptyMap() { keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(), true); }
@Test public void deleteTimestampRangesIgnoresEmptyMap() { keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(), false); }
@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { try { delegate().deleteAllTimestamps(tableMapper.getMappedTableName(tableRef), maxTimestampExclusiveByCell, deleteSentinels); } catch (TableMappingNotFoundException e) { throw new IllegalArgumentException(e); } }
@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { maybeLog(() -> delegate.deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels), logTimeAndTable("deleteAllTimestamps", tableRef)); }
@Test public void deleteTimestampRangesLeavesSentinels() { long latestTs = 15L; keyValueService.addGarbageCollectionSentinelValues(TEST_TABLE, ImmutableSet.of(TEST_CELL)); keyValueService.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, val(1, 0)), latestTs); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, latestTs), false); assertThat(getAllTimestampsForTestCell(), contains(Value.INVALID_VALUE_TIMESTAMP, latestTs)); assertThat(keyValueService.get(TEST_TABLE, ImmutableMap.of(TEST_CELL, Value.INVALID_VALUE_TIMESTAMP + 1L)) .get(TEST_CELL), equalTo(Value.create(new byte[0], Value.INVALID_VALUE_TIMESTAMP))); }
@Test public void deleteTimestampRangesIncludingSentinelsDeletesSentinels() { long latestTs = 15L; keyValueService.addGarbageCollectionSentinelValues(TEST_TABLE, ImmutableSet.of(TEST_CELL)); keyValueService.put(TEST_TABLE, ImmutableMap.of(TEST_CELL, val(1, 0)), latestTs); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, latestTs), true); assertThat(getAllTimestampsForTestCell(), contains(latestTs)); }
@Override public void deleteAllTimestamps(TableReference tableRef, Map<Cell, Long> maxTimestampExclusiveByCell, boolean deleteSentinels) { //noinspection unused - try-with-resources closes trace try (CloseableTrace trace = startLocalTrace("deleteAllTimestamps({})", LoggingArgs.safeTableOrPlaceholder(tableRef))) { delegate().deleteAllTimestamps(tableRef, maxTimestampExclusiveByCell, deleteSentinels); } }
private Object doDeleteAllTimestamps(RegeneratingTable<Cell> table) { table.getKvs().deleteAllTimestamps(table.getTableRef(), ImmutableMap.of(table.getTableCells(), RegeneratingTable.CELL_VERSIONS), false); return table.getTableCells(); }
@Test public void sweepCellOnlyOnceWhenInLastPartitionBeforeSweepTs() { immutableTs = 2 * TS_COARSE_GRANULARITY - TS_FINE_GRANULARITY; verify(spiedKvs, never()).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); enqueueWriteCommitted(TABLE_CONS, immutableTs - 1); sweepQueue.sweepNextBatch(ShardAndStrategy.conservative(CONS_SHARD)); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); sweepQueue.sweepNextBatch(ShardAndStrategy.conservative(CONS_SHARD)); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); }
@Test public void deleteTimestampRangesEdgeCases() { long minTs = 0; keyValueService.addGarbageCollectionSentinelValues(TEST_TABLE, ImmutableSet.of(TEST_CELL)); keyValueService.putWithTimestamps(TEST_TABLE, ImmutableMultimap.of( TEST_CELL, Value.create(val(0, 5), minTs), TEST_CELL, Value.create(val(0, 7), TEST_TIMESTAMP - 1), TEST_CELL, Value.create(val(0, 9), TEST_TIMESTAMP))); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_TIMESTAMP), false); assertThat(getAllTimestampsForTestCell(), contains(Value.INVALID_VALUE_TIMESTAMP, TEST_TIMESTAMP)); }
@Test public void deleteTimestampRangesIncludingSentinelsEdgeCases() { long minTs = 0; keyValueService.addGarbageCollectionSentinelValues(TEST_TABLE, ImmutableSet.of(TEST_CELL)); keyValueService.putWithTimestamps(TEST_TABLE, ImmutableMultimap.of( TEST_CELL, Value.create(val(0, 5), minTs), TEST_CELL, Value.create(val(0, 7), TEST_TIMESTAMP - 1), TEST_CELL, Value.create(val(0, 9), TEST_TIMESTAMP))); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, TEST_TIMESTAMP), true); assertThat(getAllTimestampsForTestCell(), contains(TEST_TIMESTAMP)); }
@Test public void deleteTimestampRangesIncludingSentinelsDeletesForSingleColumn() { long ts1 = 5L; long ts2 = 10L; long latestTs = 15L; keyValueService.putWithTimestamps(TEST_TABLE, ImmutableMultimap.of( TEST_CELL, Value.create(val(0, 5), ts1), TEST_CELL, Value.create(val(0, 7), ts2), TEST_CELL, Value.create(val(0, 9), latestTs))); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, latestTs), true); assertThat(getAllTimestampsForTestCell(), contains(latestTs)); assertThat(keyValueService.get(TEST_TABLE, ImmutableMap.of(TEST_CELL, Long.MAX_VALUE)).get(TEST_CELL), equalTo(Value.create(val(0, 9), latestTs))); }
@Test public void deleteTimestampRangesDeletesForSingleColumn() { long ts1 = 5L; long ts2 = 10L; long latestTs = 15L; keyValueService.putWithTimestamps(TEST_TABLE, ImmutableMultimap.of( TEST_CELL, Value.create(val(0, 5), ts1), TEST_CELL, Value.create(val(0, 7), ts2), TEST_CELL, Value.create(val(0, 9), latestTs))); keyValueService.deleteAllTimestamps(TEST_TABLE, ImmutableMap.of(TEST_CELL, latestTs), false); assertThat(getAllTimestampsForTestCell(), contains(latestTs)); assertThat(keyValueService.get(TEST_TABLE, ImmutableMap.of(TEST_CELL, Long.MAX_VALUE)).get(TEST_CELL), equalTo(Value.create(val(0, 9), latestTs))); }
@Test public void deletesGetBatched() { TargetedSweeper sweeperConservative = getSingleShardSweeper(); int numberOfTimestamps = 5 * BATCH_SIZE_KVS / MAX_CELLS_GENERIC + 1; commitTransactionsWithWritesIntoUniqueCells(numberOfTimestamps, MAX_CELLS_GENERIC, sweeperConservative); sweeperConservative.sweepNextBatch(ShardAndStrategy.conservative(0)); ArgumentCaptor<Map> map = ArgumentCaptor.forClass(Map.class); verify(spiedKvs, times(6)).deleteAllTimestamps(eq(TABLE_CONS), map.capture(), eq(false)); assertThat(map.getAllValues().stream().map(Map::size).mapToInt(x -> x).sum()) .isEqualTo(5 * BATCH_SIZE_KVS + MAX_CELLS_GENERIC); assertThat(progress.getLastSweptTimestamp(ShardAndStrategy.conservative(0))) .isEqualTo(maxTsForFinePartition(0)); }
@Test public void conservativeSweepDeletesAllButLatestWithSingleDeleteAllTimestamps() { long lastWriteTs = TS_FINE_GRANULARITY - 1; for (long i = 1; i <= lastWriteTs; i++) { enqueueWriteCommitted(TABLE_CONS, i); } sweepQueue.sweepNextBatch(ShardAndStrategy.conservative(CONS_SHARD)); assertReadAtTimestampReturnsSentinel(TABLE_CONS, lastWriteTs); assertTestValueEnqueuedAtGivenTimestampStillPresent(TABLE_CONS, lastWriteTs); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); }
@Test public void doesNotGoBackwardsEvenIfSweepTimestampRegressesWithinBucket() { enqueueWriteCommitted(TABLE_CONS, LOW_TS); enqueueWriteCommitted(TABLE_CONS, LOW_TS2); enqueueWriteCommitted(TABLE_CONS, LOW_TS3); runConservativeSweepAtTimestamp(LOW_TS2 + 5); assertReadAtTimestampReturnsSentinel(TABLE_CONS, LOW_TS2); assertTestValueEnqueuedAtGivenTimestampStillPresent(TABLE_CONS, LOW_TS2); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); assertProgressUpdatedToTimestamp(LOW_TS2 + 5 - 1); runConservativeSweepAtTimestamp(LOW_TS2 - 5); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(false)); assertProgressUpdatedToTimestamp(LOW_TS2 + 5 - 1); }
@Test public void thoroughSweepDeletesAllButLatestWithSingleDeleteAllTimestampsIncludingSentinels() { long lastWriteTs = TS_FINE_GRANULARITY - 1; for (long i = 1; i <= lastWriteTs; i++) { enqueueWriteCommitted(TABLE_THOR, i); } sweepQueue.sweepNextBatch(ShardAndStrategy.thorough(THOR_SHARD)); assertReadAtTimestampReturnsNothing(TABLE_THOR, lastWriteTs); assertTestValueEnqueuedAtGivenTimestampStillPresent(TABLE_THOR, lastWriteTs); verify(spiedKvs, times(1)).deleteAllTimestamps(any(TableReference.class), anyMap(), eq(true)); }