/** * @return the first element or null if the visitable is empty */ @Nullable public static <T> T getFirst(BatchingVisitable<T> visitable) { return getFirst(visitable, null); }
/** * Gets the first element in the visitable. * * If a default value of <code>null</code> is wanted, then consider * calling {@link BatchingVisitableView#getFirst()} instead. * * @return the first element or <code>defaultElement</code> if the visitable is empty */ @Nullable public T getFirst(@Nullable T defaultElement) { return BatchingVisitables.getFirst(delegate(), defaultElement); }
/** * Gets the first element in the visitable. * * @return the first element or <code>null</code> if the visitable is empty */ @Nullable public T getFirst() { return BatchingVisitables.getFirst(delegate()); }
@Test public void testColumnRangeReadWriteNoConflict() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col1", "v0_0"); t2.commit(); t1.commit(); }
@Test public void testColumnRangeReadWriteEmptyRange() { byte[] row = PtBytes.toBytes("row1"); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.toBytes("col0"), 1)); assertNull(BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values()))); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col", "v0"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
@Test public void testColumnRangeReadWriteConflict() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col0", "v0_0"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
@Test public void testColumnRangeReadWriteConflictOnNewCell() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); // Write on the start of the range. put(t2, "row1", "col", "v"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
/** * @return the first element or null if the visitable is empty */ @Nullable public static <T> T getFirst(BatchingVisitable<T> visitable) { return getFirst(visitable, null); }
@Test public void testNonPhantomRead() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); RowResult<byte[]> first = BatchingVisitables.getFirst(t1.getRange(TEST_TABLE, RangeRequest.builder().build())); put(t1, "row22", "col1", initialValue); Transaction t2 = startTransaction(); put(t2, "row11", "col1", initialValue); t2.commit(); t1.commit(); }
@Test public void testPhantomReadFail() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); RowResult<byte[]> first = BatchingVisitables.getFirst(t1.getRange(TEST_TABLE, RangeRequest.builder().build())); put(t1, "row22", "col1", initialValue); Transaction t2 = startTransaction(); put(t2, "row0", "col1", initialValue); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // this is expectecd to throw because it is a write skew } }
/** * Gets the first element in the visitable. * * @return the first element or <code>null</code> if the visitable is empty */ @Nullable public T getFirst() { return BatchingVisitables.getFirst(delegate()); }
/** * Gets the first element in the visitable. * * If a default value of <code>null</code> is wanted, then consider * calling {@link BatchingVisitableView#getFirst()} instead. * * @return the first element or <code>defaultElement</code> if the visitable is empty */ @Nullable public T getFirst(@Nullable T defaultElement) { return BatchingVisitables.getFirst(delegate(), defaultElement); }
@Test public void testColumnRangeReadWriteNoConflict() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col1", "v0_0"); t2.commit(); t1.commit(); }
@Test public void testColumnRangeReadWriteConflict() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col0", "v0_0"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
@Test public void testColumnRangeReadWriteConflictOnNewCell() { byte[] row = PtBytes.toBytes("row1"); writeColumns(); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.EMPTY_BYTE_ARRAY, PtBytes.EMPTY_BYTE_ARRAY, 1)); // Serializable transaction records only the first column as read. Map.Entry<Cell, byte[]> read = BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values())); assertEquals(Cell.create(row, PtBytes.toBytes("col0")), read.getKey()); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); // Write on the start of the range. put(t2, "row1", "col", "v"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
@Test public void testColumnRangeReadWriteEmptyRange() { byte[] row = PtBytes.toBytes("row1"); Transaction t1 = startTransaction(); Map<byte[], BatchingVisitable<Map.Entry<Cell, byte[]>>> columnRange = t1.getRowsColumnRange(TEST_TABLE, ImmutableList.of(row), BatchColumnRangeSelection.create(PtBytes.toBytes("col"), PtBytes.toBytes("col0"), 1)); assertNull(BatchingVisitables.getFirst(Iterables.getOnlyElement(columnRange.values()))); // Write to avoid the read only path. put(t1, "row1_1", "col0", "v0"); Transaction t2 = startTransaction(); put(t2, "row1", "col", "v0"); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // expected } }
@Test public void testNonPhantomRead() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); RowResult<byte[]> first = BatchingVisitables.getFirst(t1.getRange(TEST_TABLE, RangeRequest.builder().build())); put(t1, "row22", "col1", initialValue); Transaction t2 = startTransaction(); put(t2, "row11", "col1", initialValue); t2.commit(); t1.commit(); }
@Test public void testPhantomReadFail() { String initialValue = "100"; Transaction t0 = startTransaction(); put(t0, "row1", "col1", initialValue); put(t0, "row2", "col1", initialValue); t0.commit(); Transaction t1 = startTransaction(); RowResult<byte[]> first = BatchingVisitables.getFirst(t1.getRange(TEST_TABLE, RangeRequest.builder().build())); put(t1, "row22", "col1", initialValue); Transaction t2 = startTransaction(); put(t2, "row0", "col1", initialValue); t2.commit(); try { t1.commit(); fail(); } catch (TransactionSerializableConflictException e) { // this is expectecd to throw because it is a write skew } }