private void verifyCells(Transaction readOnlyTransaction) { for (Entry<TableReference, Set<Cell>> tableAndCellsEntry : cellsRead.entrySet()) { TableReference table = tableAndCellsEntry.getKey(); Set<Cell> cells = tableAndCellsEntry.getValue(); final ConcurrentNavigableMap<Cell, byte[]> readsForTable = getReadsForTable(table); for (Iterable<Cell> batch : Iterables.partition(cells, BATCH_SIZE)) { // We don't want to verify any reads that we wrote to cause we will just read our own values. // NB: If the value has changed between read and write, our normal SI checking handles this case Iterable<Cell> batchWithoutWrites = writesByTable.get(table) != null ? Iterables.filter(batch, Predicates.not(Predicates.in(writesByTable.get(table).keySet()))) : batch; ImmutableSet<Cell> batchWithoutWritesSet = ImmutableSet.copyOf(batchWithoutWrites); Map<Cell, byte[]> currentBatch = readOnlyTransaction.get(table, batchWithoutWritesSet); ImmutableMap<Cell, byte[]> originalReads = Maps.toMap( Sets.intersection(batchWithoutWritesSet, readsForTable.keySet()), Functions.forMap(readsForTable)); if (!areMapsEqual(currentBatch, originalReads)) { handleTransactionConflict(table); } } } }
.isEqual(readsInRange.entrySet()); if (!isEqual) { handleTransactionConflict(table);
private void verifyRanges(Transaction readOnlyTransaction) { // verify each set of reads to ensure they are the same. for (Entry<TableReference, ConcurrentMap<RangeRequest, byte[]>> tableAndRange : rangeEndByTable.entrySet()) { TableReference table = tableAndRange.getKey(); Map<RangeRequest, byte[]> rangeEnds = tableAndRange.getValue(); for (Entry<RangeRequest, byte[]> rangeAndRangeEndEntry : rangeEnds.entrySet()) { RangeRequest range = rangeAndRangeEndEntry.getKey(); byte[] rangeEnd = rangeAndRangeEndEntry.getValue(); if (rangeEnd.length != 0 && !RangeRequests.isTerminalRow(range.isReverse(), rangeEnd)) { range = range.getBuilder() .endRowExclusive(RangeRequests.getNextStartRow(range.isReverse(), rangeEnd)) .build(); } ConcurrentNavigableMap<Cell, byte[]> writes = writesByTable.get(table); BatchingVisitableView<RowResult<byte[]>> bv = BatchingVisitableView.of( readOnlyTransaction.getRange(table, range)); NavigableMap<Cell, ByteBuffer> readsInRange = Maps.transformValues( getReadsInRange(table, range), ByteBuffer::wrap); if (!bv.transformBatch(input -> filterWritesFromRows(input, writes)).isEqual(readsInRange.entrySet())) { handleTransactionConflict(table); } } } }
private void verifyCells(Transaction readOnlyTransaction) { for (Entry<TableReference, Set<Cell>> tableAndCellsEntry : cellsRead.entrySet()) { TableReference table = tableAndCellsEntry.getKey(); Set<Cell> cells = tableAndCellsEntry.getValue(); final ConcurrentNavigableMap<Cell, byte[]> readsForTable = getReadsForTable(table); for (Iterable<Cell> batch : Iterables.partition(cells, BATCH_SIZE)) { // We don't want to verify any reads that we wrote to cause we will just read our own values. // NB: If the value has changed between read and write, our normal SI checking handles this case Iterable<Cell> batchWithoutWrites = writesByTable.get(table) != null ? Iterables.filter(batch, Predicates.not(Predicates.in(writesByTable.get(table).keySet()))) : batch; ImmutableSet<Cell> batchWithoutWritesSet = ImmutableSet.copyOf(batchWithoutWrites); Map<Cell, byte[]> currentBatch = readOnlyTransaction.get(table, batchWithoutWritesSet); ImmutableMap<Cell, byte[]> originalReads = Maps.toMap( Sets.intersection(batchWithoutWritesSet, readsForTable.keySet()), Functions.forMap(readsForTable)); if (!areMapsEqual(currentBatch, originalReads)) { handleTransactionConflict(table); } } } }
.isEqual(readsInRange.entrySet()); if (!isEqual) { handleTransactionConflict(table);
handleTransactionConflict(table); handleTransactionConflict(table);
private void verifyRanges(Transaction readOnlyTransaction) { // verify each set of reads to ensure they are the same. for (Entry<TableReference, ConcurrentMap<RangeRequest, byte[]>> tableAndRange : rangeEndByTable.entrySet()) { TableReference table = tableAndRange.getKey(); Map<RangeRequest, byte[]> rangeEnds = tableAndRange.getValue(); for (Entry<RangeRequest, byte[]> rangeAndRangeEndEntry : rangeEnds.entrySet()) { RangeRequest range = rangeAndRangeEndEntry.getKey(); byte[] rangeEnd = rangeAndRangeEndEntry.getValue(); if (rangeEnd.length != 0 && !RangeRequests.isTerminalRow(range.isReverse(), rangeEnd)) { range = range.getBuilder() .endRowExclusive(RangeRequests.getNextStartRow(range.isReverse(), rangeEnd)) .build(); } ConcurrentNavigableMap<Cell, byte[]> writes = writesByTable.get(table); BatchingVisitableView<RowResult<byte[]>> bv = BatchingVisitableView.of( readOnlyTransaction.getRange(table, range)); NavigableMap<Cell, ByteBuffer> readsInRange = Maps.transformValues( getReadsInRange(table, range), ByteBuffer::wrap); if (!bv.transformBatch(input -> filterWritesFromRows(input, writes)).isEqual(readsInRange.entrySet())) { handleTransactionConflict(table); } } } }