Search in sources :

Example 1 with MutationType

use of com.apple.foundationdb.MutationType in project fdb-record-layer by FoundationDB.

the class AtomicMutationIndexMaintainer method updateIndexKeys.

@Override
protected <M extends Message> CompletableFuture<Void> updateIndexKeys(@Nonnull final FDBIndexableRecord<M> savedRecord, final boolean remove, @Nonnull final List<IndexEntry> indexEntries) {
    final MutationType mutationType = mutation.getMutationType();
    final int groupPrefixSize = getGroupingCount();
    for (IndexEntry indexEntry : indexEntries) {
        long startTime = System.nanoTime();
        final Tuple groupKey;
        final IndexEntry groupedValue;
        if (groupPrefixSize <= 0) {
            groupKey = TupleHelpers.EMPTY;
            groupedValue = indexEntry;
        } else if (groupPrefixSize == indexEntry.getKeySize()) {
            groupKey = indexEntry.getKey();
            groupedValue = indexEntry.subKey(0, 0);
        } else {
            groupKey = TupleHelpers.subTuple(indexEntry.getKey(), 0, groupPrefixSize);
            groupedValue = indexEntry.subKey(groupPrefixSize, indexEntry.getKeySize());
        }
        final byte[] param = mutation.getMutationParam(groupedValue, remove);
        if (param == null) {
            continue;
        }
        // this is a bit of a hack here, but it's the minimally invasive way and most explicit way to do this
        if (!mutation.allowsNegative()) {
            Number numVal = (Number) groupedValue.getKeyValue(0);
            if (numVal != null && numVal.longValue() < 0) {
                throw new RecordCoreException("Attempted update of MAX_EVER_LONG or MIN_EVER_LONG index with negative value");
            }
        }
        final byte[] key = state.indexSubspace.pack(groupKey);
        if (AtomicMutation.Standard.MAX_EVER_VERSION.equals(mutation)) {
            if (groupedValue.getKey().hasIncompleteVersionstamp()) {
                // With an incomplete versionstamp, we need to call SET_VERSIONSTAMPED_VALUE.
                // If multiple records (with possibly different local versions) are written with the same
                // grouping key in the same context, we want to only write the one with the maximum
                // local version. Choosing the one with the maximum byte representation will do this
                // as all incomplete versionstamps are serialized with identical fake global versions.
                state.context.updateVersionMutation(MutationType.SET_VERSIONSTAMPED_VALUE, key, param, (oldParam, newParam) -> ByteArrayUtil.compareUnsigned(oldParam, newParam) < 0 ? newParam : oldParam);
            } else {
                state.transaction.mutate(MutationType.BYTE_MAX, key, param);
            }
        } else {
            state.transaction.mutate(mutationType, key, param);
            final byte[] compareAndClear = mutation.getCompareAndClearParam();
            if (compareAndClear != null) {
                state.transaction.mutate(MutationType.COMPARE_AND_CLEAR, key, compareAndClear);
            }
        }
        if (state.store.getTimer() != null) {
            state.store.getTimer().recordSinceNanoTime(FDBStoreTimer.Events.MUTATE_INDEX_ENTRY, startTime);
        }
    }
    return AsyncUtil.DONE;
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) MutationType(com.apple.foundationdb.MutationType) IndexEntry(com.apple.foundationdb.record.IndexEntry) Tuple(com.apple.foundationdb.tuple.Tuple)

Aggregations

MutationType (com.apple.foundationdb.MutationType)1 IndexEntry (com.apple.foundationdb.record.IndexEntry)1 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)1 Tuple (com.apple.foundationdb.tuple.Tuple)1