use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class IndexedTableTest method testIncrementIndexing.
@Test
public void testIncrementIndexing() throws Exception {
DatasetId incrTabInstance = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("incrtab");
dsFrameworkUtil.createInstance("indexedTable", incrTabInstance, DatasetProperties.builder().add(IndexedTable.INDEX_COLUMNS_CONF_KEY, "idx1,idx2,idx3").build());
final IndexedTable iTable = dsFrameworkUtil.getInstance(incrTabInstance);
final byte[] idxCol1 = Bytes.toBytes("idx1");
final byte[] idxCol2 = Bytes.toBytes("idx2");
final byte[] idxCol3 = Bytes.toBytes("idx3");
final byte[] row1 = Bytes.toBytes("row1");
try {
TransactionExecutor tx = dsFrameworkUtil.newTransactionExecutor(iTable);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
long result = iTable.incrementAndGet(row1, idxCol1, 1);
assertEquals(1L, result);
}
});
final byte[] oneBytes = Bytes.toBytes(1L);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
try (Scanner scanner = iTable.readByIndex(idxCol1, oneBytes)) {
Row row = scanner.next();
TableAssert.assertRow(row, row1, new byte[][] { idxCol1 }, new byte[][] { oneBytes });
assertEmpty(scanner);
}
}
});
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
long result = iTable.incrementAndGet(row1, idxCol1, 1);
assertEquals(2L, result);
}
});
final byte[] twoBytes = Bytes.toBytes(2L);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// previous index by value 1 should be gone
Scanner scanner = iTable.readByIndex(idxCol1, oneBytes);
try {
assertEmpty(scanner);
} finally {
scanner.close();
}
// should now be indexed by value 2
scanner = iTable.readByIndex(idxCol1, twoBytes);
try {
Row row = scanner.next();
TableAssert.assertRow(row, row1, new byte[][] { idxCol1 }, new byte[][] { twoBytes });
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
final byte[] threeBytes = Bytes.toBytes(3L);
final byte[][] idxCols = new byte[][] { idxCol1, idxCol2, idxCol3 };
final byte[][] expectedValues = new byte[][] { threeBytes, oneBytes, oneBytes };
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row result = iTable.incrementAndGet(row1, idxCols, new long[] { 1, 1, 1 });
assertNotNull(result);
TableAssert.assertColumns(result, idxCols, expectedValues);
}
});
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Scanner scanner = iTable.readByIndex(idxCol1, threeBytes);
try {
Row row = scanner.next();
TableAssert.assertRow(row, row1, idxCols, expectedValues);
assertEmpty(scanner);
} finally {
scanner.close();
}
scanner = iTable.readByIndex(idxCol2, oneBytes);
try {
Row row = scanner.next();
TableAssert.assertRow(row, row1, idxCols, expectedValues);
assertEmpty(scanner);
} finally {
scanner.close();
}
scanner = iTable.readByIndex(idxCol3, oneBytes);
try {
Row row = scanner.next();
TableAssert.assertRow(row, row1, idxCols, expectedValues);
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
final byte[] row2 = Bytes.toBytes("row2");
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// read-less increment on an indexed column should throw an exception
try {
iTable.increment(row2, idxCol1, 1L);
fail("Expected IllegalArgumentException performing increment on indexed column");
} catch (IllegalArgumentException iae) {
// expected
}
// read-less increment on a non-indexed column should succeed
iTable.increment(row2, valCol, 1L);
byte[] result = iTable.get(row2, valCol);
assertArrayEquals(oneBytes, result);
}
});
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
iTable.put(row2, valCol, valA);
}
});
// increment against a column with non-long value should fail
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
try {
iTable.incrementAndGet(row2, valCol, 1L);
fail("Expected NumberFormatException from increment on a column with non-long value");
} catch (NumberFormatException nfe) {
// expected
}
}
});
} finally {
dsFrameworkUtil.deleteInstance(incrTabInstance);
}
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class IndexedTableTest method testIndexedOperations.
@Test
public void testIndexedOperations() throws Exception {
TransactionExecutor txnl = dsFrameworkUtil.newTransactionExecutor(table);
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// add a value c with idx = 1, and b with idx = 2
table.put(new Put(keyC).add(idxCol, idx1).add(valCol, valC));
table.put(new Put(keyB).add(idxCol, idx2).add(valCol, valB));
}
});
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// read by key c
Row row = table.get(new Get(keyC, colIdxVal));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx1, valC });
// read by key b
row = table.get(new Get(keyB, colIdxVal));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx2, valB });
// read by idx 1 -> c
row = readFirst(table.readByIndex(idxCol, idx1));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx1, valC });
// read by idx 2 -> b
row = readFirst(table.readByIndex(idxCol, idx2));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx2, valB });
// test read over empty index (idx 3)
assertEmpty(table.readByIndex(idxCol, idx3));
}
});
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// add a value a with idx = 1
table.put(new Put(keyA).add(idxCol, idx1).add(valCol, valA));
}
});
// read by idx 1 -> a
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx1));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx1, valA });
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// delete value a
table.delete(new Delete(keyA, colIdxVal));
}
});
// read by idx 1 -> c
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx1));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx1, valC });
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// add a value aa with idx 2
table.put(new Put(keyAA).add(idxCol, idx2).add(valCol, valAA));
}
});
// read by idx 2 -> aa
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx2));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx2, valAA });
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// swap value for aa to ab
Assert.assertTrue(table.compareAndSwap(keyAA, valCol, valAA, valAB));
}
});
// read by idx 2 -> ab
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx2));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx2, valAB });
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// swap value for aa to bb
Assert.assertTrue(table.compareAndSwap(keyAA, valCol, valAB, valBB));
}
});
// read by idx 2 -> bb (value of key aa)
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx2));
TableAssert.assertColumns(row, colIdxVal, new byte[][] { idx2, valBB });
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// swap value for aa to null
Assert.assertTrue(table.compareAndSwap(keyAA, valCol, valBB, null));
}
});
// read by idx 2 -> null (value of b)
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
Row row = readFirst(table.readByIndex(idxCol, idx2));
TableAssert.assertColumn(row, idxCol, idx2);
}
});
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// swap idx for c to 3
Assert.assertTrue(table.compareAndSwap(keyC, idxCol, idx1, idx3));
}
});
// read by idx 1 -> null (no row has that any more)
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
assertEmpty(table.readByIndex(idxCol, idx1));
// read by idx 3 > c
Row row = readFirst(table.readByIndex(idxCol, idx3));
TableAssert.assertColumns(row, new byte[][] { idxCol, valCol }, new byte[][] { idx3, valC });
}
});
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class IndexedTableTest method testIndexedRangeLookups.
@Test
public void testIndexedRangeLookups() throws Exception {
DatasetId indexRangedLookupDs = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("rangeLookup");
dsFrameworkUtil.createInstance("indexedTable", indexRangedLookupDs, DatasetProperties.builder().add(IndexedTable.INDEX_COLUMNS_CONF_KEY, idxColString).build());
final IndexedTable iTable = dsFrameworkUtil.getInstance(indexRangedLookupDs);
TransactionExecutor txnl = dsFrameworkUtil.newTransactionExecutor(iTable);
try {
// start a new transaction
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// perform 5 puts, using idx values 1,2,3,4,5
iTable.put(new Put(keyE).add(idxCol, idx4).add(valCol, valE));
iTable.put(new Put(keyC).add(idxCol, idx1).add(valCol, valC));
iTable.put(new Put(keyD).add(idxCol, idx5).add(valCol, valA));
iTable.put(new Put(keyB).add(idxCol, idx2).add(valCol, valB));
iTable.put(new Put(keyA).add(idxCol, idx3).add(valCol, valD));
}
});
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// do a scan using idx value range [idx2, idx5). Assert that we retrieve idx2, idx3, idx4.
Scanner scanner = iTable.scanByIndex(idxCol, idx2, idx5);
Row next = scanner.next();
Assert.assertNotNull(next);
Assert.assertTrue(Bytes.equals(keyB, next.getRow()));
Assert.assertTrue(Bytes.equals(valB, next.get(valCol)));
next = scanner.next();
Assert.assertNotNull(next);
Assert.assertTrue(Bytes.equals(keyA, next.getRow()));
Assert.assertTrue(Bytes.equals(valD, next.get(valCol)));
next = scanner.next();
Assert.assertNotNull(next);
Assert.assertTrue(Bytes.equals(keyE, next.getRow()));
Assert.assertTrue(Bytes.equals(valE, next.get(valCol)));
assertEmpty(scanner);
}
});
txnl.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// do a scan using idx value range [null (first row), idx3). Assert that we retrieve the values corresponding
// to idx1, idx2.
Scanner scanner = iTable.scanByIndex(idxCol, null, idx3);
Row next = scanner.next();
Assert.assertNotNull(next);
Assert.assertTrue(Bytes.equals(keyC, next.getRow()));
Assert.assertTrue(Bytes.equals(valC, next.get(valCol)));
next = scanner.next();
Assert.assertNotNull(next);
Assert.assertTrue(Bytes.equals(keyB, next.getRow()));
Assert.assertTrue(Bytes.equals(valB, next.get(valCol)));
assertEmpty(scanner);
}
});
} finally {
dsFrameworkUtil.deleteInstance(indexRangedLookupDs);
}
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class IndexedTableTest method testIndexKeyDelimiterAmbiguity.
@Test
public void testIndexKeyDelimiterAmbiguity() throws Exception {
final byte[] a = { 'a' };
final byte[] ab = { 'a', 0, 'b' };
final byte[] abc = { 'a', 0, 'b', 0, 'c' };
final byte[] bc = { 'b', 0, 'c' };
final byte[] bcd = { 'b', 0, 'c', 'd' };
final byte[] c = { 'c' };
final byte[] d = { 'd' };
final byte[] w = { 'w' };
final byte[] x = { 'x' };
final byte[] y = { 'y' };
final byte[] z = { 'z' };
DatasetId delimTabInstance = DatasetFrameworkTestUtil.NAMESPACE_ID.dataset("delimtab");
dsFrameworkUtil.createInstance("indexedTable", delimTabInstance, DatasetProperties.builder().add(IndexedTable.INDEX_COLUMNS_CONF_KEY, Bytes.toString(a) + "," + Bytes.toString(ab)).build());
final IndexedTable iTable = dsFrameworkUtil.getInstance(delimTabInstance);
try {
TransactionExecutor tx = dsFrameworkUtil.newTransactionExecutor(iTable);
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
iTable.put(x, a, bc);
iTable.put(y, ab, c);
iTable.put(w, a, bcd);
iTable.put(z, abc, d);
}
});
tx.execute(new TransactionExecutor.Subroutine() {
@Override
public void apply() throws Exception {
// ensure that readByIndex filters teh false positive rows in index
Scanner scanner = iTable.readByIndex(a, bc);
try {
Row row = scanner.next();
Assert.assertNotNull(row);
Assert.assertArrayEquals(x, row.getRow());
Assert.assertArrayEquals(bc, row.get(a));
assertEmpty(scanner);
} finally {
scanner.close();
}
scanner = iTable.readByIndex(ab, c);
try {
Row row = scanner.next();
Assert.assertNotNull(row);
Assert.assertArrayEquals(y, row.getRow());
Assert.assertArrayEquals(c, row.get(ab));
assertEmpty(scanner);
} finally {
scanner.close();
}
// ensure that scanByIndex filters the false positive rows in index
scanner = iTable.scanByIndex(a, bcd, null);
try {
Row row = scanner.next();
Assert.assertNotNull(row);
Assert.assertArrayEquals(w, row.getRow());
Assert.assertArrayEquals(bcd, row.get(a));
assertEmpty(scanner);
} finally {
scanner.close();
}
scanner = iTable.scanByIndex(a, null, bcd);
try {
Row row = scanner.next();
Assert.assertNotNull(row);
Assert.assertArrayEquals(x, row.getRow());
Assert.assertArrayEquals(bc, row.get(a));
assertEmpty(scanner);
} finally {
scanner.close();
}
}
});
} finally {
dsFrameworkUtil.deleteInstance(delimTabInstance);
}
}
use of co.cask.cdap.api.dataset.table.Row in project cdap by caskdata.
the class ReflectionTableTest method testStructuredRecordRepresentation.
@Test
public void testStructuredRecordRepresentation() throws Exception {
dsFrameworkUtil.createInstance("table", users, DatasetProperties.builder().build());
try {
final Table usersTable = dsFrameworkUtil.getInstance(users);
final byte[] rowKey = Bytes.toBytes(123);
final Schema schema = new ReflectionSchemaGenerator().generate(User.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<>(schema);
putWriter.write(SAMUEL, put);
usersTable.put(put);
Row row = usersTable.get(rowKey);
ReflectionRowRecordReader rowReader = new ReflectionRowRecordReader(schema, null);
StructuredRecord actual = rowReader.read(row, schema);
assertRecordEqualsUser(SAMUEL, actual);
}
});
} finally {
dsFrameworkUtil.deleteInstance(users);
}
}
Aggregations