use of co.cask.cdap.api.dataset.table.Scanner in project cdap by caskdata.
the class BufferingTableTest method testChangingParamsAndReturnValues.
@Test
public void testChangingParamsAndReturnValues() throws Exception {
// The test verifies that one can re-use byte arrays passed as parameters to write methods of a table without
// affecting the stored data.
// Also, one can re-use (modify) returned data from the table without affecting the stored data.
DatasetProperties props = TableProperties.builder().setReadlessIncrementSupport(isReadlessIncrementSupported()).build();
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE, props);
admin.create();
try {
// writing some data: we'll need it to test delete later
Transaction tx = txClient.startShort();
BufferingTable table = getTable(CONTEXT1, MY_TABLE, props);
table.startTx(tx);
table.put(new byte[] { 0 }, new byte[] { 9 }, new byte[] { 8 });
table.commitTx();
txClient.commit(tx);
// start new for in-mem buffer behavior testing
tx = txClient.startShort();
table.startTx(tx);
// write some data but not commit
byte[] rowParam = new byte[] { 1 };
byte[] colParam = new byte[] { 2 };
byte[] valParam = Bytes.toBytes(3L);
table.put(rowParam, colParam, valParam);
verify123(table);
// change passed earlier byte arrays in place, this should not affect stored previously values
rowParam[0]++;
colParam[0]++;
valParam[0]++;
verify123(table);
// try get row and change returned values in place, which should not affect the data stored
Row getRow = table.get(new byte[] { 1 });
Map<byte[], byte[]> getRowResult = getRow.getColumns();
Assert.assertEquals(1, getRowResult.size());
byte[] colFromGetRow = getRowResult.keySet().iterator().next();
byte[] valFromGetRow = getRowResult.get(colFromGetRow);
getRowResult.remove(new byte[] { 2 });
Assert.assertArrayEquals(new byte[] { 2 }, colFromGetRow);
Assert.assertArrayEquals(Bytes.toBytes(3L), valFromGetRow);
colFromGetRow[0]++;
valFromGetRow[0]++;
verify123(table);
// try get set of columns in a row and change returned values in place, which should not affect the data stored
Row getColumnSetRow = table.get(new byte[] { 1 });
Map<byte[], byte[]> getColumnSetResult = getColumnSetRow.getColumns();
Assert.assertEquals(1, getColumnSetResult.size());
byte[] colFromGetColumnSet = getColumnSetResult.keySet().iterator().next();
byte[] valFromGetColumnSet = getColumnSetResult.values().iterator().next();
getColumnSetResult.remove(new byte[] { 2 });
Assert.assertArrayEquals(new byte[] { 2 }, colFromGetColumnSet);
Assert.assertArrayEquals(Bytes.toBytes(3L), valFromGetColumnSet);
colFromGetColumnSet[0]++;
valFromGetColumnSet[0]++;
verify123(table);
// try get column and change returned value in place, which should not affect the data stored
byte[] valFromGetColumn = table.get(new byte[] { 1 }, new byte[] { 2 });
Assert.assertArrayEquals(Bytes.toBytes(3L), valFromGetColumn);
valFromGetColumn[0]++;
verify123(table);
// try scan and change returned value in place, which should not affect the data stored
Scanner scan = table.scan(new byte[] { 1 }, null);
Row next = scan.next();
Assert.assertNotNull(next);
byte[] rowFromScan = next.getRow();
Assert.assertArrayEquals(new byte[] { 1 }, rowFromScan);
Map<byte[], byte[]> cols = next.getColumns();
Assert.assertEquals(1, cols.size());
byte[] colFromScan = cols.keySet().iterator().next();
Assert.assertArrayEquals(new byte[] { 2 }, colFromScan);
byte[] valFromScan = next.get(new byte[] { 2 });
Assert.assertNotNull(valFromScan);
Assert.assertArrayEquals(Bytes.toBytes(3L), valFromScan);
Assert.assertNull(scan.next());
cols.remove(new byte[] { 2 });
rowFromScan[0]++;
colFromScan[0]++;
valFromScan[0]++;
verify123(table);
// try delete and change params in place: this should not affect stored data
rowParam = new byte[] { 1 };
colParam = new byte[] { 2 };
table.delete(rowParam, colParam);
Assert.assertNull(table.get(new byte[] { 1 }, new byte[] { 2 }));
Assert.assertArrayEquals(new byte[] { 8 }, table.get(new byte[] { 0 }, new byte[] { 9 }));
rowParam[0] = 0;
colParam[0] = 9;
Assert.assertNull(table.get(new byte[] { 1 }, new byte[] { 2 }));
Assert.assertArrayEquals(new byte[] { 8 }, table.get(new byte[] { 0 }, new byte[] { 9 }));
// try increment column and change params in place: this should not affect stored data
byte[] rowIncParam = new byte[] { 1 };
byte[] colIncParam = new byte[] { 2 };
table.increment(rowIncParam, colIncParam, 3);
verify123(table);
rowIncParam[0]++;
colIncParam[0]++;
verify123(table);
// try increment set of columns and change params in place, try also to change values in returned map: this all
// should not affect stored data.
rowIncParam = new byte[] { 1 };
colIncParam = new byte[] { 2 };
table.increment(rowIncParam, colIncParam, -1);
table.increment(rowIncParam, new byte[][] { colIncParam }, new long[] { 1 });
verify123(table);
rowIncParam[0]++;
colIncParam[0]++;
verify123(table);
// try increment and change returned values: should not affect the stored data
rowIncParam = new byte[] { 1 };
colIncParam = new byte[] { 2 };
table.increment(rowIncParam, colIncParam, -1);
Row countersRow = table.incrementAndGet(rowIncParam, new byte[][] { colIncParam }, new long[] { 1 });
Map<byte[], byte[]> counters = countersRow.getColumns();
Assert.assertEquals(1, counters.size());
byte[] colFromInc = counters.keySet().iterator().next();
Assert.assertArrayEquals(new byte[] { 2 }, colFromInc);
Assert.assertEquals(3, Bytes.toLong(counters.get(colFromInc)));
counters.remove(new byte[] { 2 });
colFromInc[0]++;
verify123(table);
// try increment write and change params in place: this should not affect stored data
rowIncParam = new byte[] { 1 };
colIncParam = new byte[] { 2 };
table.increment(rowIncParam, colIncParam, -1);
table.increment(rowIncParam, new byte[][] { colIncParam }, new long[] { 1 });
verify123(table);
rowIncParam[0]++;
colIncParam[0]++;
verify123(table);
// try compareAndSwap and change params in place: this should not affect stored data
byte[] rowSwapParam = new byte[] { 1 };
byte[] colSwapParam = new byte[] { 2 };
byte[] valSwapParam = Bytes.toBytes(3L);
table.compareAndSwap(rowSwapParam, colSwapParam, Bytes.toBytes(3L), Bytes.toBytes(4L));
table.compareAndSwap(rowSwapParam, colSwapParam, Bytes.toBytes(4L), valSwapParam);
verify123(table);
rowSwapParam[0]++;
colSwapParam[0]++;
valSwapParam[0]++;
verify123(table);
// We don't care to persist changes and commit tx here: we tested what we wanted
} finally {
admin.drop();
}
}
use of co.cask.cdap.api.dataset.table.Scanner in project cdap by caskdata.
the class BufferingTableTest method verify.
private void verify(BufferingTable table, byte[] row, byte[] col, byte[] val) throws Exception {
// get column
Assert.assertArrayEquals(val, table.get(row, col));
// get set of columns
Row getColSetRow = table.get(row, new byte[][] { col });
Map<byte[], byte[]> getColSetResult = getColSetRow.getColumns();
Assert.assertEquals(1, getColSetResult.size());
Assert.assertArrayEquals(val, getColSetResult.get(col));
// get row
Row getRow = table.get(row);
Map<byte[], byte[]> getRowResult = getRow.getColumns();
Assert.assertEquals(1, getRowResult.size());
Assert.assertArrayEquals(val, getRowResult.get(col));
// scan
Scanner scan = table.scan(row, null);
Row next = scan.next();
Assert.assertNotNull(next);
Assert.assertArrayEquals(row, next.getRow());
Assert.assertArrayEquals(val, next.get(col));
Assert.assertNull(scan.next());
}
use of co.cask.cdap.api.dataset.table.Scanner in project cdap by caskdata.
the class MetricsTableTest method countRange.
private static int countRange(MetricsTable table, Integer start, Integer stop) throws Exception {
Scanner scanner = table.scan(start == null ? null : Bytes.toBytes(start), stop == null ? null : Bytes.toBytes(stop), null);
int count = 0;
while (scanner.next() != null) {
count++;
}
return count;
}
use of co.cask.cdap.api.dataset.table.Scanner in project cdap by caskdata.
the class IndexedTable method readByIndex.
/**
* Reads table rows by the given secondary index key. If no rows are indexed by the given key, then a
* {@link co.cask.cdap.api.dataset.table.Scanner} with no results will be returned.
*
* @return a Scanner returning rows from the data table, whose stored value for the given column matches the
* given value.
* @throws java.lang.IllegalArgumentException if the given column is not configured for indexing.
*/
@ReadOnly
public Scanner readByIndex(byte[] column, byte[] value) {
assertIndexedColumn(column);
byte[] rowKeyPrefix = Bytes.concat(column, KEY_DELIMITER, value, KEY_DELIMITER);
byte[] stopRow = Bytes.stopKeyForPrefix(rowKeyPrefix);
Scanner indexScan = index.scan(rowKeyPrefix, stopRow);
return new IndexScanner(indexScan, column, value);
}
use of co.cask.cdap.api.dataset.table.Scanner in project cdap by caskdata.
the class IndexedTable method scanByIndex.
/**
* Reads table rows within the given secondary index key range. If no rows are indexed, falling within the given
* range, then a {@link co.cask.cdap.api.dataset.table.Scanner} with no results will be returned.
*
* @param column the column to use for the index lookup
* @param startValue the inclusive start of the range for which rows must fall within to be returned in the scan.
* {@code null} means start from first row of the table
* @param endValue the exclusive end of the range for which rows must fall within to be returned in the scan
* {@code null} means end with the last row of the table
* @return a Scanner returning rows from the data table, whose stored value for the given column is within the the
* given range.
* @throws java.lang.IllegalArgumentException if the given column is not configured for indexing.
*/
@ReadOnly
public Scanner scanByIndex(byte[] column, @Nullable byte[] startValue, @Nullable byte[] endValue) {
assertIndexedColumn(column);
// KEY_DELIMITER is not used at the end of the rowKeys, because they are used for a range scan,
// instead of a fixed-match lookup
byte[] startRow = startValue == null ? Bytes.concat(column, KEY_DELIMITER) : Bytes.concat(column, KEY_DELIMITER, startValue);
byte[] stopRow = endValue == null ? Bytes.stopKeyForPrefix(Bytes.concat(column, KEY_DELIMITER)) : Bytes.concat(column, KEY_DELIMITER, endValue);
Scanner indexScan = index.scan(startRow, stopRow);
return new IndexRangeScanner(indexScan, column, startValue, endValue);
}
Aggregations