Search in sources :

Example 56 with ColumnMetadata

use of org.apache.cassandra.schema.ColumnMetadata in project cassandra by apache.

the class Rows method merge.

/**
     * Merges two rows into the given builder, mainly for merging memtable rows. In addition to reconciling the cells
     * in each row, the liveness info, and deletion times for the row and complex columns are also merged.
     * <p>
     * Note that this method assumes that the provided rows can meaningfully be reconciled together. That is,
     * that the rows share the same clustering value, and belong to the same partition.
     *
     * @param existing
     * @param update
     * @param builder the row build to which the result of the reconciliation is written.
     * @param nowInSec the current time in seconds (which plays a role during reconciliation
     * because deleted cells always have precedence on timestamp equality and deciding if a
     * cell is a live or not depends on the current time due to expiring cells).
     *
     * @return the smallest timestamp delta between corresponding rows from existing and update. A
     * timestamp delta being computed as the difference between the cells and DeletionTimes from {@code existing}
     * and those in {@code existing}.
     */
public static long merge(Row existing, Row update, Row.Builder builder, int nowInSec) {
    Clustering clustering = existing.clustering();
    builder.newRow(clustering);
    LivenessInfo existingInfo = existing.primaryKeyLivenessInfo();
    LivenessInfo updateInfo = update.primaryKeyLivenessInfo();
    LivenessInfo mergedInfo = existingInfo.supersedes(updateInfo) ? existingInfo : updateInfo;
    long timeDelta = Math.abs(existingInfo.timestamp() - mergedInfo.timestamp());
    Row.Deletion rowDeletion = existing.deletion().supersedes(update.deletion()) ? existing.deletion() : update.deletion();
    if (rowDeletion.deletes(mergedInfo))
        mergedInfo = LivenessInfo.EMPTY;
    else if (rowDeletion.isShadowedBy(mergedInfo))
        rowDeletion = Row.Deletion.LIVE;
    builder.addPrimaryKeyLivenessInfo(mergedInfo);
    builder.addRowDeletion(rowDeletion);
    DeletionTime deletion = rowDeletion.time();
    Iterator<ColumnData> a = existing.iterator();
    Iterator<ColumnData> b = update.iterator();
    ColumnData nexta = a.hasNext() ? a.next() : null, nextb = b.hasNext() ? b.next() : null;
    while (nexta != null | nextb != null) {
        int comparison = nexta == null ? 1 : nextb == null ? -1 : nexta.column.compareTo(nextb.column);
        ColumnData cura = comparison <= 0 ? nexta : null;
        ColumnData curb = comparison >= 0 ? nextb : null;
        ColumnMetadata column = (cura != null ? cura : curb).column;
        if (column.isSimple()) {
            timeDelta = Math.min(timeDelta, Cells.reconcile((Cell) cura, (Cell) curb, deletion, builder, nowInSec));
        } else {
            ComplexColumnData existingData = (ComplexColumnData) cura;
            ComplexColumnData updateData = (ComplexColumnData) curb;
            DeletionTime existingDt = existingData == null ? DeletionTime.LIVE : existingData.complexDeletion();
            DeletionTime updateDt = updateData == null ? DeletionTime.LIVE : updateData.complexDeletion();
            DeletionTime maxDt = existingDt.supersedes(updateDt) ? existingDt : updateDt;
            if (maxDt.supersedes(deletion))
                builder.addComplexDeletion(column, maxDt);
            else
                maxDt = deletion;
            Iterator<Cell> existingCells = existingData == null ? null : existingData.iterator();
            Iterator<Cell> updateCells = updateData == null ? null : updateData.iterator();
            timeDelta = Math.min(timeDelta, Cells.reconcileComplex(column, existingCells, updateCells, maxDt, builder, nowInSec));
        }
        if (cura != null)
            nexta = a.hasNext() ? a.next() : null;
        if (curb != null)
            nextb = b.hasNext() ? b.next() : null;
    }
    return timeDelta;
}
Also used : ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata)

Example 57 with ColumnMetadata

use of org.apache.cassandra.schema.ColumnMetadata in project cassandra by apache.

the class ViewUpdateGenerator method createEntry.

/**
     * Creates a view entry corresponding to the provided base row.
     * <p>
     * This method checks that the base row does match the view filter before applying it.
     */
private void createEntry(Row baseRow) {
    // Before create a new entry, make sure it matches the view filter
    if (!matchesViewFilter(baseRow))
        return;
    startNewUpdate(baseRow);
    currentViewEntryBuilder.addPrimaryKeyLivenessInfo(computeLivenessInfoForEntry(baseRow));
    currentViewEntryBuilder.addRowDeletion(baseRow.deletion());
    for (ColumnData data : baseRow) {
        ColumnMetadata viewColumn = view.getViewColumn(data.column());
        // Alose, if it's part of the view PK it's already been taken into account in the clustering.
        if (viewColumn == null || viewColumn.isPrimaryKeyColumn())
            continue;
        addColumnData(viewColumn, data);
    }
    submitUpdate();
}
Also used : ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata)

Example 58 with ColumnMetadata

use of org.apache.cassandra.schema.ColumnMetadata in project cassandra by apache.

the class ViewUpdateGenerator method updateAction.

/**
     * Compute which type of action needs to be performed to the view for a base table row
     * before and after an update.
     */
private UpdateAction updateAction(Row existingBaseRow, Row mergedBaseRow) {
    // but if we have no update at all, we shouldn't get there.
    assert !mergedBaseRow.isEmpty();
    if (baseMetadata.isCompactTable()) {
        Clustering clustering = mergedBaseRow.clustering();
        for (int i = 0; i < clustering.size(); i++) {
            if (clustering.get(i) == null)
                return UpdateAction.NONE;
        }
    }
    assert view.baseNonPKColumnsInViewPK.size() <= 1 : "We currently only support one base non-PK column in the view PK";
    if (view.baseNonPKColumnsInViewPK.isEmpty()) {
        // The view entry is necessarily the same pre and post update.
        // Note that we allow existingBaseRow to be null and treat it as empty (see MultiViewUpdateBuilder.generateViewsMutations).
        boolean existingHasLiveData = existingBaseRow != null && existingBaseRow.hasLiveData(nowInSec);
        boolean mergedHasLiveData = mergedBaseRow.hasLiveData(nowInSec);
        return existingHasLiveData ? (mergedHasLiveData ? UpdateAction.UPDATE_EXISTING : UpdateAction.DELETE_OLD) : (mergedHasLiveData ? UpdateAction.NEW_ENTRY : UpdateAction.NONE);
    }
    ColumnMetadata baseColumn = view.baseNonPKColumnsInViewPK.get(0);
    assert !baseColumn.isComplex() : "A complex column couldn't be part of the view PK";
    Cell before = existingBaseRow == null ? null : existingBaseRow.getCell(baseColumn);
    Cell after = mergedBaseRow.getCell(baseColumn);
    // If the update didn't modified this column, the cells will be the same object so it's worth checking
    if (before == after)
        return isLive(before) ? UpdateAction.UPDATE_EXISTING : UpdateAction.NONE;
    if (!isLive(before))
        return isLive(after) ? UpdateAction.NEW_ENTRY : UpdateAction.NONE;
    if (!isLive(after))
        return UpdateAction.DELETE_OLD;
    return baseColumn.cellValueType().compare(before.value(), after.value()) == 0 ? UpdateAction.UPDATE_EXISTING : UpdateAction.SWITCH_ENTRY;
}
Also used : ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata)

Example 59 with ColumnMetadata

use of org.apache.cassandra.schema.ColumnMetadata in project cassandra by apache.

the class TargetParser method parse.

public static Pair<ColumnMetadata, IndexTarget.Type> parse(TableMetadata metadata, IndexMetadata indexDef) {
    String target = indexDef.options.get("target");
    assert target != null : String.format("No target definition found for index %s", indexDef.name);
    Pair<ColumnMetadata, IndexTarget.Type> result = parse(metadata, target);
    if (result == null)
        throw new ConfigurationException(String.format("Unable to parse targets for index %s (%s)", indexDef.name, target));
    return result;
}
Also used : ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata) ConfigurationException(org.apache.cassandra.exceptions.ConfigurationException)

Example 60 with ColumnMetadata

use of org.apache.cassandra.schema.ColumnMetadata in project cassandra by apache.

the class CassandraIndex method setMetadata.

private void setMetadata(IndexMetadata indexDef) {
    metadata = indexDef;
    Pair<ColumnMetadata, IndexTarget.Type> target = TargetParser.parse(baseCfs.metadata(), indexDef);
    functions = getFunctions(indexDef, target);
    TableMetadataRef tableRef = TableMetadataRef.forOfflineTools(indexCfsMetadata(baseCfs.metadata(), indexDef));
    indexCfs = ColumnFamilyStore.createColumnFamilyStore(baseCfs.keyspace, tableRef.name, tableRef, baseCfs.getTracker().loadsstables);
    indexedColumn = target.left;
}
Also used : ColumnMetadata(org.apache.cassandra.schema.ColumnMetadata) AbstractType(org.apache.cassandra.db.marshal.AbstractType) CollectionType(org.apache.cassandra.db.marshal.CollectionType) EmptyType(org.apache.cassandra.db.marshal.EmptyType) TableMetadataRef(org.apache.cassandra.schema.TableMetadataRef)

Aggregations

ColumnMetadata (org.apache.cassandra.schema.ColumnMetadata)123 Test (org.junit.Test)35 ByteBuffer (java.nio.ByteBuffer)23 Row (org.apache.cassandra.db.rows.Row)17 TableMetadata (org.apache.cassandra.schema.TableMetadata)16 ColumnIdentifier (org.apache.cassandra.cql3.ColumnIdentifier)15 AbstractType (org.apache.cassandra.db.marshal.AbstractType)8 ConfigurationException (org.apache.cassandra.exceptions.ConfigurationException)5 java.util (java.util)4 IndexTarget (org.apache.cassandra.cql3.statements.IndexTarget)4 CollectionType (org.apache.cassandra.db.marshal.CollectionType)4 IndexMetadata (org.apache.cassandra.schema.IndexMetadata)4 IOException (java.io.IOException)3 Collectors (java.util.stream.Collectors)3 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)3 ColumnFilter (org.apache.cassandra.db.filter.ColumnFilter)3 ImmutableBTreePartition (org.apache.cassandra.db.partitions.ImmutableBTreePartition)3 Cell (org.apache.cassandra.db.rows.Cell)3 RowIterator (org.apache.cassandra.db.rows.RowIterator)3 InvalidRequestException (org.apache.cassandra.exceptions.InvalidRequestException)3