use of io.cdap.cdap.api.dataset.table.Delete in project cdap by caskdata.
the class MetadataDataset method removeMetadata.
/**
* Removes all keys that satisfy a given predicate from the metadata of the specified {@link MetadataEntity}.
* @param metadataEntity the {@link MetadataEntity} for which keys are to be removed
* @param filter the {@link Predicate} that should be satisfied to remove a key
*/
private Change removeMetadata(MetadataEntity metadataEntity, Predicate<String> filter) {
MDSKey mdsKey = MetadataKey.createValueRowKey(metadataEntity, null);
byte[] prefix = mdsKey.getKey();
byte[] stopKey = Bytes.stopKeyForPrefix(prefix);
Map<String, String> existingMetadata = new HashMap<>();
Map<String, String> deletedMetadata = new HashMap<>();
try (Scanner scan = indexedTable.scan(prefix, stopKey)) {
Row next;
while ((next = scan.next()) != null) {
String value = next.getString(VALUE_COLUMN);
if (value == null) {
continue;
}
String metadataKey = MetadataKey.extractMetadataKey(next.getRow());
// put all the metadata for this entity as existing
existingMetadata.put(metadataKey, value);
if (filter.test(metadataKey)) {
// if the key matches the key to be deleted delete it and put it in deleted
indexedTable.delete(new Delete(next.getRow()));
// store the key to delete its indexes later
deletedMetadata.put(metadataKey, value);
}
}
}
// current metadata is existing - deleted
Map<String, String> currentMetadata = new HashMap<>(existingMetadata);
// delete all the indexes for all deleted metadata key
for (String deletedMetadataKey : deletedMetadata.keySet()) {
deleteIndexes(metadataEntity, deletedMetadataKey);
currentMetadata.remove(deletedMetadataKey);
}
Record changedMetadata = getMetadata(metadataEntity, currentMetadata);
writeHistory(changedMetadata);
return new Change(getMetadata(metadataEntity, existingMetadata), changedMetadata);
}
use of io.cdap.cdap.api.dataset.table.Delete in project cdap by caskdata.
the class TableTest method testEmptyDelete.
@Test
public void testEmptyDelete() throws Exception {
DatasetAdmin admin = getTableAdmin(CONTEXT1, MY_TABLE);
admin.create();
try (Table myTable = getTable(CONTEXT1, MY_TABLE)) {
Transaction tx = txClient.startShort();
((TransactionAware) myTable).startTx(tx);
myTable.put(R1, C1, V1);
myTable.put(R1, C2, V2);
myTable.put(R1, C3, V3);
// specifying empty columns means to delete nothing
myTable.delete(R1, new byte[][] {});
myTable.delete(new Delete(R1, new byte[][] {}));
myTable.delete(new Delete(R1, ImmutableList.<byte[]>of()));
myTable.delete(new Delete(Bytes.toString(R1), new String[] {}));
myTable.delete(new Delete(Bytes.toString(R1), ImmutableList.<String>of()));
// verify the above delete calls deleted none of the rows
Row row = myTable.get(R1);
Assert.assertEquals(3, row.getColumns().size());
Assert.assertArrayEquals(R1, row.getRow());
Assert.assertArrayEquals(V1, row.get(C1));
Assert.assertArrayEquals(V2, row.get(C2));
Assert.assertArrayEquals(V3, row.get(C3));
// test deletion of only one column
Delete delete = new Delete(R1);
Assert.assertNull(delete.getColumns());
delete.add(C1);
Assert.assertNotNull(delete.getColumns());
myTable.delete(delete);
row = myTable.get(R1);
Assert.assertEquals(2, row.getColumns().size());
Assert.assertArrayEquals(R1, row.getRow());
Assert.assertArrayEquals(V2, row.get(C2));
Assert.assertArrayEquals(V3, row.get(C3));
// test delete of all columns
myTable.delete(new Delete(R1));
Assert.assertEquals(0, myTable.get(R1).getColumns().size());
txClient.abort(tx);
} finally {
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.table.Delete in project cdap by caskdata.
the class TableTest method testMetrics.
private void testMetrics(boolean readless) throws Exception {
final String tableName = "survive";
DatasetProperties props = TableProperties.builder().setReadlessIncrementSupport(readless).build();
DatasetAdmin admin = getTableAdmin(CONTEXT1, tableName, props);
admin.create();
try (Table table = getTable(CONTEXT1, tableName, props)) {
final Map<String, Long> metrics = Maps.newHashMap();
((MeteredDataset) table).setMetricsCollector(new MetricsCollector() {
@Override
public void increment(String metricName, long value) {
Long old = metrics.get(metricName);
metrics.put(metricName, old == null ? value : old + value);
}
@Override
public void gauge(String metricName, long value) {
metrics.put(metricName, value);
}
});
// Note that we don't need to finish tx for metrics to be reported
Transaction tx0 = txClient.startShort();
((TransactionAware) table).startTx(tx0);
int writes = 0;
int reads = 0;
table.put(new Put(R1, C1, V1));
verifyDatasetMetrics(metrics, ++writes, reads);
table.compareAndSwap(R1, C1, V1, V2);
verifyDatasetMetrics(metrics, ++writes, ++reads);
// note: will not write anything as expected value will not match
table.compareAndSwap(R1, C1, V1, V2);
verifyDatasetMetrics(metrics, writes, ++reads);
table.increment(new Increment(R2, C2, 1L));
if (readless) {
verifyDatasetMetrics(metrics, ++writes, reads);
} else {
verifyDatasetMetrics(metrics, ++writes, ++reads);
}
table.incrementAndGet(new Increment(R2, C2, 1L));
verifyDatasetMetrics(metrics, ++writes, ++reads);
table.get(new Get(R1, C1, V1));
verifyDatasetMetrics(metrics, writes, ++reads);
Scanner scanner = table.scan(new Scan(null, null));
while (scanner.next() != null) {
verifyDatasetMetrics(metrics, writes, ++reads);
}
table.delete(new Delete(R1, C1, V1));
verifyDatasetMetrics(metrics, ++writes, reads);
} finally {
// drop table
admin.drop();
}
}
use of io.cdap.cdap.api.dataset.table.Delete in project cdap by caskdata.
the class IndexedTable method compareAndSwap.
/**
* Perform a swap operation by primary key.
* Parameters are as if they were on a non-indexed table.
* Note that if the swap is on the secondary key column,
* then the index must be updated; otherwise, this is a
* pass-through to the underlying table.
*/
@ReadWrite
@Override
public boolean compareAndSwap(byte[] row, byte[] column, byte[] expected, byte[] newValue) {
// is the same as the new value, then the index is not affected either.
if (!indexedColumns.contains(column) || Arrays.equals(expected, newValue)) {
return table.compareAndSwap(row, column, expected, newValue);
}
// the swap is on the index column. it will only succeed if the current
// value matches the expected value of the swap. if that value is not null,
// then we must remove the row key from the index for that value.
Delete idxDelete = null;
if (expected != null) {
idxDelete = new Delete(createIndexKey(row, column, expected), IDX_COL);
}
// if the new value is not null, then we must add the rowkey to the index
// for that value.
Put idxPut = null;
if (newValue != null) {
idxPut = new Put(createIndexKey(row, column, newValue), IDX_COL, row);
}
// apply all operations to both tables
boolean success = table.compareAndSwap(row, column, expected, newValue);
if (!success) {
// do nothing: no changes
return false;
}
if (idxDelete != null) {
index.delete(idxDelete);
}
if (idxPut != null) {
index.put(idxPut);
}
return true;
}
use of io.cdap.cdap.api.dataset.table.Delete in project cdap by caskdata.
the class MetadataStoreDataset method deleteAll.
/**
* Delete all values in the given prefix row key which satisfies the predicate
*
* @param id prefix row key
*/
public void deleteAll(MDSKey id, @Nullable Predicate<MDSKey> filter) {
byte[] prefix = id.getKey();
byte[] stopKey = Bytes.stopKeyForPrefix(prefix);
try {
try (Scanner scan = table.scan(prefix, stopKey)) {
Row next;
while ((next = scan.next()) != null) {
String columnValue = next.getString(COLUMN);
if (columnValue == null) {
continue;
}
MDSKey key = new MDSKey(next.getRow());
if (filter != null && !filter.test(key)) {
continue;
}
table.delete(new Delete(next.getRow()).add(COLUMN));
}
}
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
Aggregations