private void put(Transaction txn, WriteReference write) { if (write.isTombstone()) { txn.delete(write.tableRef(), ImmutableSet.of(write.cell())); } else { txn.put(write.tableRef(), ImmutableMap.of(write.cell(), TEST_DATA)); } }
public static WriteReference tombstone(TableReference tableRef, Cell cell) { return WriteReference.of(tableRef, cell, true); }
private Collection<WriteInfo> getWritesToSweep(Multimap<Long, WriteInfo> writesByStartTs, SortedSet<Long> startTs) { Map<CellReference, WriteInfo> writesToSweepFor = new HashMap<>(); startTs.stream() .map(writesByStartTs::get) .flatMap(Collection::stream) .forEach(write -> writesToSweepFor .putIfAbsent(write.writeRef().cellReference(), write)); return writesToSweepFor.values(); }
default Cell cell() { return writeRef().cell(); }
default TableReference tableRef() { return writeRef().tableRef(); }
default long timestampToDeleteAtExclusive(Sweeper sweeper) { if (sweeper.shouldSweepLastCommitted() && writeRef().isTombstone()) { return timestamp() + 1L; } return timestamp(); }
@Test public void committedWritesAreAddedToSweepQueue() { List<WriteReference> table1Writes = ImmutableList.of( WriteReference.write(TABLE_CONS, Cell.create("a".getBytes(), "b".getBytes())), WriteReference.write(TABLE_CONS, Cell.create("a".getBytes(), "c".getBytes())), WriteReference.tombstone(TABLE_CONS, Cell.create("a".getBytes(), "d".getBytes())), WriteReference.write(TABLE_CONS, Cell.create("b".getBytes(), "d".getBytes()))); List<WriteReference> table2Writes = ImmutableList.of( WriteReference.write(TABLE_THOR, Cell.create("w".getBytes(), "x".getBytes())), WriteReference.write(TABLE_THOR, Cell.create("y".getBytes(), "z".getBytes())), WriteReference.tombstone(TABLE_THOR, Cell.create("z".getBytes(), "z".getBytes()))); long startTimestamp = txManager.runTaskWithRetry(txn -> { table1Writes.forEach(write -> put(txn, write)); table2Writes.forEach(write -> put(txn, write)); return txn.getTimestamp(); }); List<WriteInfo> expectedWrites = Stream.concat(table1Writes.stream(), table2Writes.stream()) .map(writeRef -> WriteInfo.of(writeRef, startTimestamp)) .collect(Collectors.toList()); assertThat(getEnqueuedWritesNumber(1)).hasSameElementsAs(expectedWrites); verify(sweepQueue, times(1)).enqueue(anyList()); }
default Cell cell() { return writeRef().cell(); }
default TableReference tableRef() { return writeRef().tableRef(); }
default long timestampToDeleteAtExclusive(Sweeper sweeper) { if (sweeper.shouldSweepLastCommitted() && writeRef().isTombstone()) { return timestamp() + 1L; } return timestamp(); }
@Test public void sweepDeletesAllIfLatestCommittedTombstoneInThorough() { useOneSweepQueueShard(); WriteReference writeToThorough = WriteReference.write(TABLE_THOR, TEST_CELL); WriteReference tombstoneToThorough = WriteReference.tombstone(TABLE_THOR, TEST_CELL); long firstStart = writeInTransactionAndGetStartTimestamp(writeToThorough); long secondStart = writeInTransactionAndGetStartTimestamp(tombstoneToThorough); assertLatestEntryBeforeTsIs(Long.MAX_VALUE, TABLE_THOR, TEST_CELL, PtBytes.EMPTY_BYTE_ARRAY, secondStart); assertLatestEntryBeforeTsIs(secondStart, TABLE_THOR, TEST_CELL, TEST_DATA, firstStart); serializableTxManager.setUnreadableTimestamp(secondStart + 1); sweepQueue.sweepNextBatch(ShardAndStrategy.thorough(0)); assertNoEntryForCellInKvs(TABLE_THOR, TEST_CELL); }
public StoredWriteReference persist(WriteReference writeReference) { byte[] tableId = EncodingUtils.encodeUnsignedVarLong(tableIndices.getTableId(writeReference.tableRef())); byte[] row = EncodingUtils.encodeSizedBytes(writeReference.cell().getRowName()); byte[] column = EncodingUtils.encodeSizedBytes(writeReference.cell().getColumnName()); byte[] isTombstone = EncodingUtils.encodeUnsignedVarLong(writeReference.isTombstone() ? 1 : 0); return ImmutableStoredWriteReference.of(EncodingUtils.add(writePrefix, tableId, row, column, isTombstone)); } }
public static WriteReference write(TableReference tableRef, Cell cell) { return WriteReference.of(tableRef, cell, false); }
default int toShard(int numShards) { return IntMath.mod(writeRef().cellReference().hashCode(), numShards); }
public StoredWriteReference persist(WriteReference writeReference) { byte[] tableId = EncodingUtils.encodeUnsignedVarLong(tableIndices.getTableId(writeReference.tableRef())); byte[] row = EncodingUtils.encodeSizedBytes(writeReference.cell().getRowName()); byte[] column = EncodingUtils.encodeSizedBytes(writeReference.cell().getColumnName()); byte[] isTombstone = EncodingUtils.encodeUnsignedVarLong(writeReference.isTombstone() ? 1 : 0); return ImmutableStoredWriteReference.of(EncodingUtils.add(writePrefix, tableId, row, column, isTombstone)); } }
public static WriteInfo toWriteInfo(TableReference tableRef, Map.Entry<Cell, byte[]> write, long timestamp) { Cell cell = write.getKey(); boolean isTombstone = Arrays.equals(write.getValue(), PtBytes.EMPTY_BYTE_ARRAY); return WriteInfo.of(WriteReference.of(tableRef, cell, isTombstone), timestamp); }
@Test public void cellReferenceIgnoresTombstoneStatus() { assertThat(getWriteAt(ONE)).isNotEqualTo(getTombstoneAt(ONE)); assertThat(getWriteAt(ONE).writeRef().cellReference()) .isEqualTo(getTombstoneAt(ONE).writeRef().cellReference()); }
static WriteInfo tombstone(TableReference tableRef, Cell cell, long timestamp) { return WriteInfo.of(WriteReference.of(tableRef, cell, true), timestamp); }