use of io.cdap.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 io.cdap.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 io.cdap.cdap.api.dataset.table.Row in project cdap by caskdata.
the class NoSqlStructuredTable method read.
@Override
public Optional<StructuredRow> read(Collection<Field<?>> keys) throws InvalidFieldException {
LOG.trace("Table {}: Read with keys {}", schema.getTableId(), keys);
Row row = table.get(convertKeyToBytes(keys, false));
return row.isEmpty() ? Optional.empty() : Optional.of(new NoSqlStructuredRow(row, schema));
}
use of io.cdap.cdap.api.dataset.table.Row in project cdap by caskdata.
the class NoSqlStructuredTable method read.
@Override
public Optional<StructuredRow> read(Collection<Field<?>> keys, Collection<String> columns) throws InvalidFieldException {
LOG.trace("Table {}: Read with keys {} and columns {}", schema.getTableId(), keys, columns);
if (columns == null || columns.isEmpty()) {
throw new IllegalArgumentException("No columns are specified to read");
}
Row row = table.get(convertKeyToBytes(keys, false), convertColumnsToBytes(columns));
return row.isEmpty() ? Optional.empty() : Optional.of(new NoSqlStructuredRow(row, schema));
}
use of io.cdap.cdap.api.dataset.table.Row in project cdap by caskdata.
the class LevelDBTableCore method deleteRange.
public void deleteRange(byte[] startRow, byte[] stopRow, @Nullable FuzzyRowFilter filter, @Nullable byte[][] columns) throws IOException {
if (columns != null) {
if (columns.length == 0) {
return;
}
columns = Arrays.copyOf(columns, columns.length);
Arrays.sort(columns, Bytes.BYTES_COMPARATOR);
}
DB db = getDB();
DBIterator iterator = db.iterator();
seekToStart(iterator, startRow);
byte[] endKey = stopRow == null ? null : createStartKey(stopRow);
DBIterator deleteIterator = db.iterator();
seekToStart(deleteIterator, startRow);
// todo make configurable
final int deletesPerRound = 1024;
try (Scanner scanner = new LevelDBScanner(iterator, endKey, filter, columns, null)) {
Row rowValues;
WriteBatch batch = db.createWriteBatch();
int deletesInBatch = 0;
// go through all matching cells and delete them in batches.
while ((rowValues = scanner.next()) != null) {
byte[] row = rowValues.getRow();
for (byte[] column : rowValues.getColumns().keySet()) {
addToDeleteBatch(batch, deleteIterator, row, column);
deletesInBatch++;
// perform the deletes when we have built up a batch.
if (deletesInBatch >= deletesPerRound) {
// delete all the entries that were found
db.write(batch, getWriteOptions());
batch = db.createWriteBatch();
deletesInBatch = 0;
}
}
}
// perform any outstanding deletes
if (deletesInBatch > 0) {
db.write(batch, getWriteOptions());
}
} finally {
deleteIterator.close();
}
}
Aggregations