use of co.cask.cdap.data2.dataset2.lib.table.PutValue in project cdap by caskdata.
the class InMemoryTableService method swap.
public static synchronized boolean swap(String tableName, byte[] row, byte[] column, byte[] oldValue, byte[] newValue) {
ConcurrentNavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, Update>>> table = tables.get(tableName);
// get the correct row from the table, create it if it doesn't exist
NavigableMap<byte[], NavigableMap<Long, Update>> rowMap = table.get(row);
Update existingValue = null;
if (rowMap != null) {
NavigableMap<Long, Update> columnMap = rowMap.get(column);
if (columnMap != null) {
existingValue = columnMap.lastEntry().getValue();
}
}
// verify existing value matches
if (oldValue == null && existingValue != null) {
return false;
}
if (oldValue != null && (existingValue == null || !Bytes.equals(oldValue, existingValue.getBytes()))) {
return false;
}
// write new value
if (newValue == null) {
if (rowMap != null) {
rowMap.remove(column);
}
} else {
if (rowMap == null) {
rowMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
table.put(row, rowMap);
}
NavigableMap<Long, Update> columnMap = rowMap.get(column);
if (columnMap == null) {
columnMap = Maps.newTreeMap();
rowMap.put(column, columnMap);
}
PutValue newPut = new PutValue(newValue);
columnMap.put(System.currentTimeMillis(), newPut);
}
return true;
}
use of co.cask.cdap.data2.dataset2.lib.table.PutValue in project cdap by caskdata.
the class HBaseTable method persist.
@Override
protected void persist(NavigableMap<byte[], NavigableMap<byte[], Update>> updates) throws Exception {
if (updates.isEmpty()) {
return;
}
List<Mutation> mutations = new ArrayList<>();
for (Map.Entry<byte[], NavigableMap<byte[], Update>> row : updates.entrySet()) {
// create these only when they are needed
PutBuilder put = null;
PutBuilder incrementPut = null;
IncrementBuilder increment = null;
for (Map.Entry<byte[], Update> column : row.getValue().entrySet()) {
// we want support tx and non-tx modes
if (tx != null) {
// TODO: hijacking timestamp... bad
Update val = column.getValue();
if (val instanceof IncrementValue) {
if (safeReadlessIncrements) {
increment = getIncrement(increment, row.getKey(), true);
increment.add(columnFamily, column.getKey(), tx.getWritePointer(), ((IncrementValue) val).getValue());
} else {
incrementPut = getPutForIncrement(incrementPut, row.getKey());
incrementPut.add(columnFamily, column.getKey(), tx.getWritePointer(), Bytes.toBytes(((IncrementValue) val).getValue()));
}
} else if (val instanceof PutValue) {
put = getPut(put, row.getKey());
put.add(columnFamily, column.getKey(), tx.getWritePointer(), wrapDeleteIfNeeded(((PutValue) val).getValue()));
}
} else {
Update val = column.getValue();
if (val instanceof IncrementValue) {
incrementPut = getPutForIncrement(incrementPut, row.getKey());
incrementPut.add(columnFamily, column.getKey(), Bytes.toBytes(((IncrementValue) val).getValue()));
} else if (val instanceof PutValue) {
put = getPut(put, row.getKey());
put.add(columnFamily, column.getKey(), ((PutValue) val).getValue());
}
}
}
if (incrementPut != null) {
mutations.add(incrementPut.build());
}
if (increment != null) {
mutations.add(increment.build());
}
if (put != null) {
mutations.add(put.build());
}
}
if (!hbaseFlush(mutations)) {
LOG.info("No writes to persist!");
}
}
use of co.cask.cdap.data2.dataset2.lib.table.PutValue in project cdap by caskdata.
the class LevelDBTable method persist.
@Override
protected void persist(NavigableMap<byte[], NavigableMap<byte[], Update>> changes) throws Exception {
persistedVersion = tx == null ? System.currentTimeMillis() : tx.getWritePointer();
NavigableMap<byte[], NavigableMap<byte[], byte[]>> puts = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
NavigableMap<byte[], NavigableMap<byte[], Long>> increments = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
for (Map.Entry<byte[], NavigableMap<byte[], Update>> rowEntry : changes.entrySet()) {
for (Map.Entry<byte[], Update> colEntry : rowEntry.getValue().entrySet()) {
Update val = colEntry.getValue();
if (val instanceof IncrementValue) {
NavigableMap<byte[], Long> incrCols = increments.get(rowEntry.getKey());
if (incrCols == null) {
incrCols = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
increments.put(rowEntry.getKey(), incrCols);
}
incrCols.put(colEntry.getKey(), ((IncrementValue) val).getValue());
} else if (val instanceof PutValue) {
NavigableMap<byte[], byte[]> putCols = puts.get(rowEntry.getKey());
if (putCols == null) {
putCols = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
puts.put(rowEntry.getKey(), putCols);
}
putCols.put(colEntry.getKey(), ((PutValue) val).getValue());
}
}
}
if (!increments.isEmpty() || !puts.isEmpty()) {
persist(increments, puts);
}
}
use of co.cask.cdap.data2.dataset2.lib.table.PutValue in project cdap by caskdata.
the class InMemoryTableServiceTest method testInternalsNotLeaking.
@Test
public void testInternalsNotLeaking() {
// Test that there's no way to break the state of InMemoryTableService by changing parameters of update
// methods (after method invocation) or by changing returned values "in-place"
InMemoryTableService.create("table");
// verify writing thru merge is guarded
NavigableMap<byte[], NavigableMap<byte[], Update>> updates = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
NavigableMap<byte[], Update> rowUpdate = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
byte[] rowParam = new byte[] { 1 };
byte[] columnParam = new byte[] { 2 };
byte[] valParam = new byte[] { 3 };
rowUpdate.put(columnParam, new PutValue(valParam));
updates.put(rowParam, rowUpdate);
InMemoryTableService.merge("table", updates, 1L);
verify123();
updates.remove(rowParam);
rowUpdate.remove(columnParam);
rowParam[0]++;
columnParam[0]++;
valParam[0]++;
verify123();
// verify changing returned data from get doesn't affect the stored data
NavigableMap<byte[], NavigableMap<Long, byte[]>> rowFromGet = InMemoryTableService.get("table", new byte[] { 1 }, new Transaction(1L, 2L, new long[0], new long[0], 1L));
Assert.assertEquals(1, rowFromGet.size());
byte[] columnFromGet = rowFromGet.firstEntry().getKey();
Assert.assertArrayEquals(new byte[] { 2 }, columnFromGet);
byte[] valFromGet = rowFromGet.firstEntry().getValue().get(1L);
Assert.assertArrayEquals(new byte[] { 3 }, valFromGet);
rowFromGet.firstEntry().getValue().remove(1L);
rowFromGet.remove(columnFromGet);
columnFromGet[0]++;
valFromGet[0]++;
verify123();
// verify changing returned data doesn't affect the stored data
NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> fromGetRange = InMemoryTableService.getRowRange("table", null, null, new Transaction(1L, 2L, new long[0], new long[0], 1L));
Assert.assertEquals(1, fromGetRange.size());
byte[] keyFromGetRange = fromGetRange.firstEntry().getKey();
Assert.assertArrayEquals(new byte[] { 1 }, keyFromGetRange);
NavigableMap<byte[], NavigableMap<Long, byte[]>> rowFromGetRange = fromGetRange.get(new byte[] { 1 });
Assert.assertEquals(1, rowFromGetRange.size());
byte[] columnFromGetRange = rowFromGetRange.firstEntry().getKey();
Assert.assertArrayEquals(new byte[] { 2 }, columnFromGetRange);
byte[] valFromGetRange = rowFromGetRange.firstEntry().getValue().get(1L);
Assert.assertArrayEquals(new byte[] { 3 }, valFromGetRange);
rowFromGetRange.firstEntry().getValue().remove(1L);
rowFromGetRange.remove(columnFromGetRange);
fromGetRange.remove(keyFromGetRange);
keyFromGetRange[0]++;
columnFromGetRange[0]++;
valFromGet[0]++;
verify123();
}
Aggregations