Search in sources :

Example 1 with Result

use of io.cdap.cdap.api.dataset.table.Result in project cdap by caskdata.

the class IndexedTable method incrementAndGet.

/**
 * Increments (atomically) the specified row and columns by the specified amounts, and returns the new values.
 * Note that performing this operation on an indexed column will generally have a negative impact on performance,
 * since up to three writes will need to be performed for every increment (one removing the index for the previous,
 * pre-increment value, one adding the index for the incremented value, and one for the increment itself).
 *
 * @see Table#incrementAndGet(byte[], byte[][], long[])
 */
@ReadWrite
@Override
public Row incrementAndGet(byte[] row, byte[][] columns, long[] amounts) {
    if (columns.length != amounts.length) {
        throw new IllegalArgumentException("Size of columns and amounts arguments must match");
    }
    Row existingRow = table.get(row, columns);
    byte[][] updatedValues = new byte[columns.length][];
    NavigableMap<byte[], byte[]> result = new TreeMap<>(Bytes.BYTES_COMPARATOR);
    for (int i = 0; i < columns.length; i++) {
        long existingValue = 0L;
        byte[] existingBytes = existingRow.get(columns[i]);
        if (existingBytes != null) {
            if (existingBytes.length != Bytes.SIZEOF_LONG) {
                throw new NumberFormatException("Attempted to increment a value that is not convertible to long," + " row: " + Bytes.toStringBinary(row) + " column: " + Bytes.toStringBinary(columns[i]));
            }
            existingValue = Bytes.toLong(existingBytes);
            if (indexedColumns.contains(columns[i])) {
                index.delete(createIndexKey(row, columns[i], existingBytes), IDX_COL);
            }
        }
        updatedValues[i] = Bytes.toBytes(existingValue + amounts[i]);
        result.put(columns[i], updatedValues[i]);
        if (indexedColumns.contains(columns[i])) {
            index.put(createIndexKey(row, columns[i], updatedValues[i]), IDX_COL, row);
        }
    }
    table.put(row, columns, updatedValues);
    return new Result(row, result);
}
Also used : Row(io.cdap.cdap.api.dataset.table.Row) TreeMap(java.util.TreeMap) Result(io.cdap.cdap.api.dataset.table.Result) ReadWrite(io.cdap.cdap.api.annotation.ReadWrite)

Example 2 with Result

use of io.cdap.cdap.api.dataset.table.Result in project cdap by caskdata.

the class BufferingTable method get.

@ReadOnly
@Override
public Row get(byte[] row, byte[][] columns) {
    ensureTransactionIsStarted();
    reportRead(1);
    try {
        return new Result(row, getRowMap(row, columns));
    } catch (Exception e) {
        LOG.debug("get failed for table: " + getTransactionAwareName() + ", row: " + Bytes.toStringBinary(row), e);
        throw new DataSetException("get failed", e);
    }
}
Also used : DataSetException(io.cdap.cdap.api.dataset.DataSetException) DataSetException(io.cdap.cdap.api.dataset.DataSetException) IOException(java.io.IOException) Result(io.cdap.cdap.api.dataset.table.Result) ReadOnly(io.cdap.cdap.api.annotation.ReadOnly)

Example 3 with Result

use of io.cdap.cdap.api.dataset.table.Result in project cdap by caskdata.

the class BufferingTable method get.

/**
 * NOTE: Depending on the use-case, calling this method may be much less
 *       efficient than calling same method with columns as parameters because it may always require round trip to
 *       persistent store
 */
@ReadOnly
@Override
public Row get(byte[] row) {
    ensureTransactionIsStarted();
    reportRead(1);
    try {
        return new Result(row, getRowMap(row));
    } catch (Exception e) {
        LOG.debug("get failed for table: " + getTransactionAwareName() + ", row: " + Bytes.toStringBinary(row), e);
        throw new DataSetException("get failed", e);
    }
}
Also used : DataSetException(io.cdap.cdap.api.dataset.DataSetException) DataSetException(io.cdap.cdap.api.dataset.DataSetException) IOException(java.io.IOException) Result(io.cdap.cdap.api.dataset.table.Result) ReadOnly(io.cdap.cdap.api.annotation.ReadOnly)

Example 4 with Result

use of io.cdap.cdap.api.dataset.table.Result in project cdap by cdapio.

the class BufferingTable method get.

@ReadOnly
@Override
public Row get(byte[] row, byte[] startColumn, byte[] stopColumn, int limit) {
    ensureTransactionIsStarted();
    reportRead(1);
    // checking if the row was deleted inside this tx
    NavigableMap<byte[], Update> buffCols = buff.get(row);
    // potential improvement: do not fetch columns available in in-mem buffer (we know them at this point)
    try {
        Map<byte[], byte[]> persistedCols = getPersisted(row, startColumn, stopColumn, limit);
        // adding server cols, and then overriding with buffered values
        NavigableMap<byte[], byte[]> result = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
        if (persistedCols != null) {
            result.putAll(persistedCols);
        }
        if (buffCols != null) {
            buffCols = getRange(buffCols, startColumn, stopColumn, limit);
            // null valued columns in in-memory buffer are deletes, so we need to delete them from the result list
            mergeToPersisted(result, buffCols, null);
        }
        // applying limit
        return new Result(row, head(result, limit));
    } catch (Exception e) {
        LOG.debug("get failed for table: " + getTransactionAwareName() + ", row: " + Bytes.toStringBinary(row), e);
        throw new DataSetException("get failed", e);
    }
}
Also used : DataSetException(io.cdap.cdap.api.dataset.DataSetException) DataSetException(io.cdap.cdap.api.dataset.DataSetException) IOException(java.io.IOException) Result(io.cdap.cdap.api.dataset.table.Result) ReadOnly(io.cdap.cdap.api.annotation.ReadOnly)

Example 5 with Result

use of io.cdap.cdap.api.dataset.table.Result in project cdap by cdapio.

the class BufferingTable method get.

@ReadOnly
@Override
public List<Row> get(List<Get> gets) {
    ensureTransactionIsStarted();
    try {
        // get persisted, then overwrite with whats buffered
        List<Map<byte[], byte[]>> persistedRows = getPersisted(gets);
        // gets and rows lists are always of the same size
        Preconditions.checkArgument(gets.size() == persistedRows.size(), "Invalid number of rows fetched when performing multi-get. There must be one row for each get.");
        List<Row> result = Lists.newArrayListWithCapacity(persistedRows.size());
        Iterator<Map<byte[], byte[]>> persistedRowsIter = persistedRows.iterator();
        Iterator<Get> getIter = gets.iterator();
        while (persistedRowsIter.hasNext() && getIter.hasNext()) {
            Get get = getIter.next();
            Map<byte[], byte[]> persistedRow = persistedRowsIter.next();
            // navigable copy of the persisted data. Implementation may return immutable or unmodifiable maps,
            // so we make a copy here.
            NavigableMap<byte[], byte[]> rowColumns = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
            rowColumns.putAll(persistedRow);
            byte[] row = get.getRow();
            NavigableMap<byte[], Update> buffCols = buff.get(row);
            // merge what was in the buffer and what was persisted
            if (buffCols != null) {
                List<byte[]> getColumns = get.getColumns();
                byte[][] columns = getColumns == null ? null : getColumns.toArray(new byte[getColumns.size()][]);
                mergeToPersisted(rowColumns, buffCols, columns);
            }
            result.add(new Result(row, unwrapDeletes(rowColumns)));
        }
        return result;
    } catch (Exception e) {
        LOG.debug("multi-get failed for table: " + getTransactionAwareName(), e);
        throw new DataSetException("multi-get failed", e);
    }
}
Also used : DataSetException(io.cdap.cdap.api.dataset.DataSetException) IOException(java.io.IOException) Result(io.cdap.cdap.api.dataset.table.Result) DataSetException(io.cdap.cdap.api.dataset.DataSetException) Get(io.cdap.cdap.api.dataset.table.Get) Row(io.cdap.cdap.api.dataset.table.Row) Map(java.util.Map) NavigableMap(java.util.NavigableMap) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) ReadOnly(io.cdap.cdap.api.annotation.ReadOnly)

Aggregations

Result (io.cdap.cdap.api.dataset.table.Result)15 DataSetException (io.cdap.cdap.api.dataset.DataSetException)10 IOException (java.io.IOException)10 ReadOnly (io.cdap.cdap.api.annotation.ReadOnly)8 Row (io.cdap.cdap.api.dataset.table.Row)7 ReadWrite (io.cdap.cdap.api.annotation.ReadWrite)4 Get (io.cdap.cdap.api.dataset.table.Get)4 TreeMap (java.util.TreeMap)4 Test (org.junit.Test)3 DatasetAdmin (io.cdap.cdap.api.dataset.DatasetAdmin)2 Table (io.cdap.cdap.api.dataset.table.Table)2 HBaseTable (io.cdap.cdap.data2.dataset2.lib.table.hbase.HBaseTable)2 Map (java.util.Map)2 NavigableMap (java.util.NavigableMap)2 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)2 Transaction (org.apache.tephra.Transaction)2 TransactionAware (org.apache.tephra.TransactionAware)2 StructuredRecord (io.cdap.cdap.api.data.format.StructuredRecord)1 Schema (io.cdap.cdap.api.data.schema.Schema)1