use of co.cask.cdap.api.annotation.WriteOnly in project cdap by caskdata.
the class IndexedTable method delete.
@WriteOnly
@Override
public void delete(byte[] row) {
Row existingRow = table.get(row);
if (existingRow.isEmpty()) {
// no row to delete
return;
}
// delete all index entries
deleteIndexEntries(existingRow);
// delete the row
table.delete(row);
}
use of co.cask.cdap.api.annotation.WriteOnly in project cdap by caskdata.
the class IndexedTable method put.
/**
* Writes a put to the data table. If any of the columns in the {@link Put} are configured to be indexed, the
* appropriate indexes will be updated with the indexed values referencing the data table row.
*
* @param put The put operation to store
*/
@WriteOnly
@Override
public void put(Put put) {
// if different value exists, remove current index ref
// add a new index ref unless same value already exists
byte[] dataRow = put.getRow();
// find which values need to be indexed
Map<byte[], byte[]> putColumns = put.getValues();
Set<byte[]> colsToIndex = new TreeSet<>(Bytes.BYTES_COMPARATOR);
for (Map.Entry<byte[], byte[]> putEntry : putColumns.entrySet()) {
if (indexedColumns.contains(putEntry.getKey())) {
colsToIndex.add(putEntry.getKey());
}
}
if (!colsToIndex.isEmpty()) {
// first read the existing indexed values to find which have changed and need to be updated
Row existingRow = table.get(dataRow, colsToIndex.toArray(new byte[colsToIndex.size()][]));
for (Map.Entry<byte[], byte[]> entry : existingRow.getColumns().entrySet()) {
if (!Arrays.equals(entry.getValue(), putColumns.get(entry.getKey()))) {
index.delete(createIndexKey(dataRow, entry.getKey(), entry.getValue()), IDX_COL);
} else {
// value already indexed
colsToIndex.remove(entry.getKey());
}
}
// add new index entries for all values that have changed or did not exist
for (byte[] col : colsToIndex) {
index.put(createIndexKey(dataRow, col, putColumns.get(col)), IDX_COL, dataRow);
}
}
// store the data row
table.put(put);
}
use of co.cask.cdap.api.annotation.WriteOnly in project cdap by caskdata.
the class IndexedObjectStore method write.
/**
* Writes to the dataset, deleting any existing secondaryKey corresponding to the key and updates the indexTable with
* the secondaryKey that is passed.
*
* @param key key for storing the object
* @param object object to be stored
* @param secondaryKeys indices that can be used to lookup the object
*/
@WriteOnly
public void write(byte[] key, T object, byte[][] secondaryKeys) {
writeToObjectStore(key, object);
//Update the secondaryKeys
//logic:
// - Get existing secondary keys
// - Compute diff between existing secondary keys and new secondary keys
// - Remove the secondaryKeys that are removed
// - Add the new keys that are added
Row row = index.get(getPrefixedPrimaryKey(key));
Set<byte[]> existingSecondaryKeys = new TreeSet<>(Bytes.BYTES_COMPARATOR);
if (!row.isEmpty()) {
existingSecondaryKeys = row.getColumns().keySet();
}
Set<byte[]> newSecondaryKeys = new TreeSet<>(Bytes.BYTES_COMPARATOR);
newSecondaryKeys.addAll(Arrays.asList(secondaryKeys));
List<byte[]> secondaryKeysDeleted = secondaryKeysToDelete(existingSecondaryKeys, newSecondaryKeys);
if (secondaryKeysDeleted.size() > 0) {
deleteSecondaryKeys(key, secondaryKeysDeleted.toArray(new byte[secondaryKeysDeleted.size()][]));
}
List<byte[]> secondaryKeysAdded = secondaryKeysToAdd(existingSecondaryKeys, newSecondaryKeys);
//for each key store the secondaryKey. This will be used while deleting old index values.
if (secondaryKeysAdded.size() > 0) {
byte[][] fooValues = new byte[secondaryKeysAdded.size()][];
Arrays.fill(fooValues, EMPTY_VALUE);
index.put(getPrefixedPrimaryKey(key), secondaryKeysAdded.toArray(new byte[secondaryKeysAdded.size()][]), fooValues);
}
for (byte[] secondaryKey : secondaryKeysAdded) {
//update the index.
index.put(secondaryKey, key, EMPTY_VALUE);
}
}
use of co.cask.cdap.api.annotation.WriteOnly in project cdap by caskdata.
the class IndexedObjectStore method write.
@WriteOnly
public void write(byte[] key, T object) {
Row row = index.get(getPrefixedPrimaryKey(key));
if (!row.isEmpty()) {
Set<byte[]> columnsToDelete = row.getColumns().keySet();
deleteSecondaryKeys(key, columnsToDelete.toArray(new byte[columnsToDelete.size()][]));
}
writeToObjectStore(key, object);
}
use of co.cask.cdap.api.annotation.WriteOnly in project cdap by caskdata.
the class PartitionedFileSetDataset method addMetadata.
@WriteOnly
@Override
public void addMetadata(PartitionKey key, Map<String, String> metadata) {
final byte[] rowKey = generateRowKey(key, partitioning);
Row row = partitionsTable.get(rowKey);
if (row.isEmpty()) {
throw new PartitionNotFoundException(key, getName());
}
// ensure that none of the entries already exist in the metadata
for (Map.Entry<String, String> metadataEntry : metadata.entrySet()) {
String metadataKey = metadataEntry.getKey();
byte[] columnKey = columnKeyFromMetadataKey(metadataKey);
if (row.get(columnKey) != null) {
throw new DataSetException(String.format("Entry already exists for metadata key: %s", metadataKey));
}
}
Put put = new Put(rowKey);
addMetadataToPut(metadata, put);
partitionsTable.put(put);
}
Aggregations