use of org.apache.tephra.TransactionExecutor in project cdap by caskdata.
the class ReflectionTableTest method testStructuredRecordProjection.
@Test
public void testStructuredRecordProjection() throws Exception {
dsFrameworkUtil.createInstance("table", users, DatasetProperties.builder().build());
try {
final Table usersTable = dsFrameworkUtil.getInstance(users);
final byte[] rowKey = Bytes.toBytes(123);
final User2 projected = new User2("Samuel L.", 123L, ((Float) 50000000.02f).doubleValue(), Double.MAX_VALUE, ByteBuffer.wrap(new byte[] { 0, 1, 2 }));
final Schema fullSchema = new ReflectionSchemaGenerator().generate(User.class);
final Schema projSchema = new ReflectionSchemaGenerator().generate(User2.class);
// TableDataset is not accessible here, but we know that's the underlying implementation...
TransactionExecutor tx = dsFrameworkUtil.newTransactionExecutor((TransactionAware) usersTable);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Put put = new Put(rowKey);
ReflectionPutWriter<User> putWriter = new ReflectionPutWriter<>(fullSchema);
putWriter.write(SAMUEL, put);
usersTable.put(put);
Row row = usersTable.get(rowKey);
ReflectionRowRecordReader rowReader = new ReflectionRowRecordReader(projSchema, null);
StructuredRecord actual = rowReader.read(row, fullSchema);
assertRecordEqualsUser(projected, actual);
}
});
} finally {
dsFrameworkUtil.deleteInstance(users);
}
}
use of org.apache.tephra.TransactionExecutor in project cdap by caskdata.
the class IndexedTableTest method testMultipleIndexedColumns.
@Test
public void testMultipleIndexedColumns() throws Exception {
DatasetId multiColumnTabInstance = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("multicolumntab");
dsFrameworkUtil.createInstance("indexedTable", multiColumnTabInstance, DatasetProperties.builder().add(IndexedTable.INDEX_COLUMNS_CONF_KEY, "idx1,idx2,idx3").build());
final byte[] idxCol1 = Bytes.toBytes("idx1");
final byte[] idxCol2 = Bytes.toBytes("idx2");
final byte[] idxCol3 = Bytes.toBytes("idx3");
final IndexedTable mcTable = dsFrameworkUtil.getInstance(multiColumnTabInstance);
try {
TransactionExecutor tx = dsFrameworkUtil.newTransactionExecutor(mcTable);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// every row has idx3 = index mod 3
for (int i = 1; i < 10; i++) {
Put put = new Put(Bytes.toBytes("row" + i));
put.add(idxCol1, idx1);
if (i % 2 == 0) {
put.add(idxCol2, idx2);
}
put.add(idxCol3, Bytes.toBytes(i % 3));
put.add(valCol, valA);
mcTable.put(put);
}
}
});
final byte[][] allColumns = new byte[][] { idxCol1, idxCol2, idxCol3, valCol };
final byte[][] oddColumns = new byte[][] { idxCol1, idxCol3, valCol };
final byte[] zero = Bytes.toBytes(0);
final byte[] one = Bytes.toBytes(1);
final byte[] two = Bytes.toBytes(2);
// read by index 1
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Scanner scanner = mcTable.readByIndex(idxCol1, idx1);
try {
// should have all rows, all data
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row1"), oddColumns, new byte[][] { idx1, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row2"), allColumns, new byte[][] { idx1, idx2, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row3"), oddColumns, new byte[][] { idx1, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row4"), allColumns, new byte[][] { idx1, idx2, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row5"), oddColumns, new byte[][] { idx1, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row6"), allColumns, new byte[][] { idx1, idx2, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row7"), oddColumns, new byte[][] { idx1, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row8"), allColumns, new byte[][] { idx1, idx2, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row9"), oddColumns, new byte[][] { idx1, zero, valA });
// should be end of rows
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
// read by index 2
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Scanner scanner = mcTable.readByIndex(idxCol2, idx2);
try {
// Should have only even rows
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row2"), allColumns, new byte[][] { idx1, idx2, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row4"), allColumns, new byte[][] { idx1, idx2, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row6"), allColumns, new byte[][] { idx1, idx2, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row8"), allColumns, new byte[][] { idx1, idx2, two, valA });
// should be at the end
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
// read by index 3
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// 0 should have rows 3, 6, 9
Scanner scanner = mcTable.readByIndex(idxCol3, zero);
try {
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row3"), oddColumns, new byte[][] { idx1, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row6"), allColumns, new byte[][] { idx1, idx2, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row9"), oddColumns, new byte[][] { idx1, zero, valA });
// should be end of rows
assertEmpty(scanner);
} finally {
scanner.close();
}
// 1 should have rows 1, 4, 7
scanner = mcTable.readByIndex(idxCol3, one);
try {
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row1"), oddColumns, new byte[][] { idx1, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row4"), allColumns, new byte[][] { idx1, idx2, one, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row7"), oddColumns, new byte[][] { idx1, one, valA });
// should be end of rows
assertEmpty(scanner);
} finally {
scanner.close();
}
// 2 should have rows 2, 5, 8
scanner = mcTable.readByIndex(idxCol3, two);
try {
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row2"), allColumns, new byte[][] { idx1, idx2, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row5"), oddColumns, new byte[][] { idx1, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row8"), allColumns, new byte[][] { idx1, idx2, two, valA });
// should be end of rows
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
// update idx2 value for rows 2 & 4
final byte[] idx2b = new byte[] { '2', 'b' };
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
mcTable.put(Bytes.toBytes("row2"), idxCol2, idx2b);
mcTable.put(Bytes.toBytes("row4"), idxCol2, idx2b);
}
});
// only rows 6 & 8 should be returned for idx2 now
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Scanner scanner = mcTable.readByIndex(idxCol2, idx2);
try {
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row6"), allColumns, new byte[][] { idx1, idx2, zero, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row8"), allColumns, new byte[][] { idx1, idx2, two, valA });
assertEmpty(scanner);
} finally {
scanner.close();
}
scanner = mcTable.readByIndex(idxCol2, idx2b);
try {
Row row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row2"), allColumns, new byte[][] { idx1, idx2b, two, valA });
row = scanner.next();
TableAssert.assertRow(row, Bytes.toBytes("row4"), allColumns, new byte[][] { idx1, idx2b, one, valA });
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
// rows 2 & 4 should be returned for idx2b
} finally {
dsFrameworkUtil.deleteInstance(multiColumnTabInstance);
}
}
use of org.apache.tephra.TransactionExecutor in project cdap by caskdata.
the class KeyValueTableTest method testBatchReads.
@Test
public void testBatchReads() throws Exception {
DatasetId tBatch = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("tBatch");
dsFrameworkUtil.createInstance("keyValueTable", tBatch, DatasetProperties.EMPTY);
final KeyValueTable t = dsFrameworkUtil.getInstance(tBatch);
TransactionExecutor txnl = dsFrameworkUtil.newTransactionExecutor(t);
final SortedSet<Long> keysWritten = Sets.newTreeSet();
// start a transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// write 1000 random values to the table and remember them in a set
Random rand = new Random(451);
for (int i = 0; i < 1000; i++) {
long keyLong = rand.nextLong();
byte[] key = Bytes.toBytes(keyLong);
t.write(key, key);
keysWritten.add(keyLong);
}
}
});
// start a sync transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// get the splits for the table
List<Split> splits = t.getSplits();
// read each split and verify the keys
SortedSet<Long> keysToVerify = Sets.newTreeSet(keysWritten);
verifySplits(t, splits, keysToVerify);
}
});
// start a sync transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// get specific number of splits for a subrange
SortedSet<Long> keysToVerify = Sets.newTreeSet(keysWritten.subSet(0x10000000L, 0x40000000L));
List<Split> splits = t.getSplits(5, Bytes.toBytes(0x10000000L), Bytes.toBytes(0x40000000L));
Assert.assertTrue(splits.size() <= 5);
// read each split and verify the keys
verifySplits(t, splits, keysToVerify);
}
});
dsFrameworkUtil.deleteInstance(tBatch);
}
use of org.apache.tephra.TransactionExecutor in project cdap by caskdata.
the class KeyValueTableTest method testASyncWriteReadSwapDelete.
@Test
public void testASyncWriteReadSwapDelete() throws Exception {
TransactionExecutor txnl = dsFrameworkUtil.newTransactionExecutor(kvTable);
// defer all writes until commit
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// write a value
kvTable.write(KEY2, VAL1);
}
});
// verify synchronously
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// verify that the value is now visible
Assert.assertArrayEquals(VAL1, kvTable.read(KEY2));
}
});
// defer all writes until commit
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// update the value
kvTable.write(KEY2, VAL2);
}
});
// verify synchronously
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// verify that the value is now visible
Assert.assertArrayEquals(VAL2, kvTable.read(KEY2));
}
});
// defer all writes until commit
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// write a swap, this should fail
Assert.assertFalse(kvTable.compareAndSwap(KEY2, VAL1, VAL3));
Assert.assertArrayEquals(VAL2, kvTable.read(KEY2));
}
});
// defer all writes until commit
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// swap the value
Assert.assertTrue(kvTable.compareAndSwap(KEY2, VAL2, VAL3));
}
});
// verify synchronously
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// verify the value was swapped
Assert.assertArrayEquals(VAL3, kvTable.read(KEY2));
}
});
// defer all writes until commit
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// delete the value
kvTable.delete(KEY2);
}
});
// verify synchronously
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// verify it is gone now
Assert.assertNull(kvTable.read(KEY2));
}
});
}
use of org.apache.tephra.TransactionExecutor in project cdap by caskdata.
the class KeyValueTableTest method testTransactionAcrossTables.
@Test
public void testTransactionAcrossTables() throws Exception {
DatasetId t1 = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("t1");
DatasetId t2 = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("t2");
dsFrameworkUtil.createInstance("keyValueTable", t1, DatasetProperties.EMPTY);
dsFrameworkUtil.createInstance("keyValueTable", t2, DatasetProperties.EMPTY);
final KeyValueTable table1 = dsFrameworkUtil.getInstance(t1);
final KeyValueTable table2 = dsFrameworkUtil.getInstance(t2);
TransactionExecutor txnl = dsFrameworkUtil.newTransactionExecutor(table1, table2, kvTable);
// write a value to table1 and verify it
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
table1.write(KEY1, VAL1);
Assert.assertArrayEquals(VAL1, table1.read(KEY1));
table2.write(KEY2, VAL2);
Assert.assertArrayEquals(VAL2, table2.read(KEY2));
}
});
// start a new transaction
try {
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// add a write for table 1 to the transaction
table1.write(KEY1, VAL2);
// submit a delete for table 2
table2.delete(KEY2);
throw new RuntimeException("Cancel transaction");
}
});
Assert.fail("Transaction should have been cancelled");
} catch (TransactionFailureException e) {
Assert.assertEquals("Cancel transaction", e.getCause().getMessage());
}
// test a swap for a third row that should fail
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Assert.assertFalse(kvTable.compareAndSwap(KEY3, VAL1, VAL1));
}
});
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Assert.assertArrayEquals(VAL1, table1.read(KEY1));
Assert.assertArrayEquals(VAL2, table2.read(KEY2));
}
});
// verify synchronously that old value are still there
final KeyValueTable table1v2 = dsFrameworkUtil.getInstance(t1);
final KeyValueTable table2v2 = dsFrameworkUtil.getInstance(t2);
TransactionExecutor txnlv2 = dsFrameworkUtil.newTransactionExecutor(table1v2, table2v2);
txnlv2.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Assert.assertArrayEquals(VAL1, table1v2.read(KEY1));
Assert.assertArrayEquals(VAL2, table2v2.read(KEY2));
}
});
dsFrameworkUtil.deleteInstance(t1);
dsFrameworkUtil.deleteInstance(t2);
}
Aggregations