Search in sources :

Example 11 with DataConversion

use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.

the class CallInterceptor method visitReadOnlyKeyCommand.

@Override
public Object visitReadOnlyKeyCommand(InvocationContext ctx, ReadOnlyKeyCommand command) throws Throwable {
    if (command instanceof TxReadOnlyKeyCommand) {
        TxReadOnlyKeyCommand txReadOnlyKeyCommand = (TxReadOnlyKeyCommand) command;
        List<Mutation> mutations = txReadOnlyKeyCommand.getMutations();
        if (mutations != null && !mutations.isEmpty()) {
            return visitTxReadOnlyKeyCommand(ctx, txReadOnlyKeyCommand, mutations);
        }
    }
    Object key = command.getKey();
    CacheEntry entry = ctx.lookupEntry(key);
    if (entry == null) {
        throw new IllegalStateException();
    }
    DataConversion keyDataConversion = command.getKeyDataConversion();
    EntryView.ReadEntryView ro = entry.isNull() ? EntryViews.noValue(key, keyDataConversion) : EntryViews.readOnly(entry, keyDataConversion, command.getValueDataConversion());
    Object ret = snapshot(command.getFunction().apply(ro));
    // We'll consider the entry always read for stats purposes even if the function is a noop
    return Param.StatisticsMode.isSkip(command.getParams()) ? ret : StatsEnvelope.create(ret, entry.isNull());
}
Also used : DataConversion(org.infinispan.encoding.DataConversion) EntryView(org.infinispan.functional.EntryView) TxReadOnlyKeyCommand(org.infinispan.commands.functional.TxReadOnlyKeyCommand) Mutation(org.infinispan.commands.functional.Mutation) InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) CacheEntry(org.infinispan.container.entries.CacheEntry)

Example 12 with DataConversion

use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.

the class CallInterceptor method visitReadWriteKeyValueCommand.

@Override
public Object visitReadWriteKeyValueCommand(InvocationContext ctx, ReadWriteKeyValueCommand command) throws Throwable {
    ValueMatcher valueMatcher = command.getValueMatcher();
    // It's not worth looking up the entry if we're never going to apply the change.
    if (valueMatcher == ValueMatcher.MATCH_NEVER) {
        command.fail();
        return null;
    }
    MVCCEntry e = (MVCCEntry) ctx.lookupEntry(command.getKey());
    // Could be that the key is not local
    if (e == null)
        return null;
    Object prevValue = command.getPrevValue();
    Metadata prevMetadata = command.getPrevMetadata();
    boolean hasCommandRetry = command.hasAnyFlag(FlagBitSets.COMMAND_RETRY);
    // Command only has one previous value, do not override it
    if (prevValue == null && !hasCommandRetry) {
        prevValue = e.getValue();
        prevMetadata = e.getMetadata();
        command.setPrevValueAndMetadata(prevValue, prevMetadata);
    }
    // Protect against outdated old value using the value matcher.
    // If the value has been update while on the retry, use the newer value.
    // Also take into account that the value might have been removed.
    // TODO: Configure equivalence function
    // TODO: this won't work properly until we store if the command was executed or not...
    Object oldPrevValue = e.getValue();
    // Note: other commands don't clone the entry as they don't carry the previous value for comparison
    // using value matcher - if other commands are retried these can apply the function multiple times.
    // Here we don't want to modify the value in context when trying what would be the outcome of the operation.
    MVCCEntry copy = e.clone();
    DataConversion valueDataConversion = command.getValueDataConversion();
    Object decodedArgument = valueDataConversion.fromStorage(command.getArgument());
    EntryViews.AccessLoggingReadWriteView view = EntryViews.readWrite(copy, prevValue, prevMetadata, command.getKeyDataConversion(), valueDataConversion);
    Object ret = snapshot(command.getBiFunction().apply(decodedArgument, view));
    if (valueMatcher.matches(oldPrevValue, prevValue, copy.getValue())) {
        log.tracef("Execute read-write function on previous value %s and previous metadata %s", prevValue, prevMetadata);
        e.setValue(copy.getValue());
        e.setMetadata(copy.getMetadata());
        // These are the only flags that should be changed with EntryViews.readWrite
        e.setChanged(copy.isChanged());
        e.setRemoved(copy.isRemoved());
    }
    // The effective result of retried command is not safe; we'll go to backup anyway
    if (!e.isChanged() && !hasCommandRetry) {
        command.fail();
    }
    updateStoreFlags(command, e);
    return Param.StatisticsMode.isSkip(command.getParams()) ? ret : StatsEnvelope.create(ret, e, prevValue != null, view.isRead());
}
Also used : DataConversion(org.infinispan.encoding.DataConversion) ValueMatcher(org.infinispan.commands.write.ValueMatcher) EntryViews(org.infinispan.functional.impl.EntryViews) Metadata(org.infinispan.metadata.Metadata) MVCCEntry(org.infinispan.container.entries.MVCCEntry)

Example 13 with DataConversion

use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.

the class CallInterceptor method visitReadOnlyManyCommand.

@Override
public Object visitReadOnlyManyCommand(InvocationContext ctx, ReadOnlyManyCommand command) throws Throwable {
    if (command instanceof TxReadOnlyManyCommand) {
        TxReadOnlyManyCommand txReadOnlyManyCommand = (TxReadOnlyManyCommand) command;
        List<List<Mutation>> mutations = txReadOnlyManyCommand.getMutations();
        if (mutations != null && !mutations.isEmpty()) {
            return visitTxReadOnlyCommand(ctx, (TxReadOnlyManyCommand) command, mutations);
        }
    }
    Collection<?> keys = command.getKeys();
    // lazy execution triggers exceptions on unexpected places
    ArrayList<Object> retvals = new ArrayList<>(keys.size());
    boolean skipStats = Param.StatisticsMode.isSkip(command.getParams());
    DataConversion keyDataConversion = command.getKeyDataConversion();
    DataConversion valueDataConversion = command.getValueDataConversion();
    Function function = command.getFunction();
    for (Object k : keys) {
        CacheEntry me = ctx.lookupEntry(k);
        EntryView.ReadEntryView view = me.isNull() ? EntryViews.noValue(k, keyDataConversion) : EntryViews.readOnly(me, keyDataConversion, valueDataConversion);
        Object ret = snapshot(function.apply(view));
        retvals.add(skipStats ? ret : StatsEnvelope.create(ret, me.isNull()));
    }
    return retvals.stream();
}
Also used : ArrayList(java.util.ArrayList) InternalCacheEntry(org.infinispan.container.entries.InternalCacheEntry) CacheEntry(org.infinispan.container.entries.CacheEntry) DataConversion(org.infinispan.encoding.DataConversion) BiFunction(java.util.function.BiFunction) Function(java.util.function.Function) EntryView(org.infinispan.functional.EntryView) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) TxReadOnlyManyCommand(org.infinispan.commands.functional.TxReadOnlyManyCommand)

Example 14 with DataConversion

use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.

the class CallInterceptor method visitReadWriteManyCommand.

@Override
public Object visitReadWriteManyCommand(InvocationContext ctx, ReadWriteManyCommand command) throws Throwable {
    // Can't return a lazy stream here because the current code in
    // EntryWrappingInterceptor expects any changes to be done eagerly,
    // otherwise they're not applied. So, apply the function eagerly and
    // return a lazy stream of the void returns.
    Collection<Object> keys = command.getAffectedKeys();
    List<Object> returns = new ArrayList<>(keys.size());
    boolean skipStats = Param.StatisticsMode.isSkip(command.getParams());
    DataConversion keyDataConversion = command.getKeyDataConversion();
    DataConversion valueDataConversion = command.getValueDataConversion();
    Function function = command.getFunction();
    keys.forEach(k -> {
        MVCCEntry entry = (MVCCEntry) ctx.lookupEntry(k);
        boolean exists = entry.getValue() != null;
        EntryViews.AccessLoggingReadWriteView view = EntryViews.readWrite(entry, keyDataConversion, valueDataConversion);
        Object r = snapshot(function.apply(view));
        returns.add(skipStats ? r : StatsEnvelope.create(r, entry, exists, view.isRead()));
        updateStoreFlags(command, entry);
    });
    return returns;
}
Also used : DataConversion(org.infinispan.encoding.DataConversion) BiFunction(java.util.function.BiFunction) Function(java.util.function.Function) EntryViews(org.infinispan.functional.impl.EntryViews) ArrayList(java.util.ArrayList) MVCCEntry(org.infinispan.container.entries.MVCCEntry)

Example 15 with DataConversion

use of org.infinispan.encoding.DataConversion in project infinispan by infinispan.

the class CallInterceptor method visitTxReadOnlyCommand.

private Object visitTxReadOnlyCommand(InvocationContext ctx, TxReadOnlyManyCommand command, List<List<Mutation>> mutations) {
    Collection<Object> keys = command.getKeys();
    ArrayList<Object> retvals = new ArrayList<>(keys.size());
    Iterator<List<Mutation>> mutIt = mutations.iterator();
    boolean skipStats = Param.StatisticsMode.isSkip(command.getParams());
    Function function = command.getFunction();
    DataConversion keyDataConversion = command.getKeyDataConversion();
    DataConversion valueDataConversion = command.getValueDataConversion();
    for (Object k : keys) {
        List<Mutation> innerMutations = mutIt.next();
        MVCCEntry entry = (MVCCEntry) ctx.lookupEntry(k);
        EntryView.ReadEntryView ro;
        Object ret = null;
        if (mutations.isEmpty()) {
            ro = entry.isNull() ? EntryViews.noValue(k, keyDataConversion) : EntryViews.readOnly(entry, keyDataConversion, valueDataConversion);
        } else {
            EntryView.ReadWriteEntryView rw = EntryViews.readWrite(entry, keyDataConversion, valueDataConversion);
            for (Mutation mutation : innerMutations) {
                entry.updatePreviousValue();
                ret = mutation.apply(rw);
            }
            ro = rw;
        }
        if (function != null) {
            ret = function.apply(ro);
        }
        ret = snapshot(ret);
        retvals.add(skipStats ? ret : StatsEnvelope.create(ret, entry.isNull()));
    }
    return retvals.stream();
}
Also used : ArrayList(java.util.ArrayList) DataConversion(org.infinispan.encoding.DataConversion) BiFunction(java.util.function.BiFunction) Function(java.util.function.Function) EntryView(org.infinispan.functional.EntryView) MVCCEntry(org.infinispan.container.entries.MVCCEntry) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) Mutation(org.infinispan.commands.functional.Mutation)

Aggregations

DataConversion (org.infinispan.encoding.DataConversion)41 MVCCEntry (org.infinispan.container.entries.MVCCEntry)9 KeyPartitioner (org.infinispan.distribution.ch.KeyPartitioner)9 ArrayList (java.util.ArrayList)8 AdvancedCache (org.infinispan.AdvancedCache)8 Util (org.infinispan.commons.util.Util)8 EnumUtil (org.infinispan.commons.util.EnumUtil)7 InvocationContext (org.infinispan.context.InvocationContext)7 Completable (io.reactivex.rxjava3.core.Completable)6 Flowable (io.reactivex.rxjava3.core.Flowable)6 Set (java.util.Set)6 CompletionStage (java.util.concurrent.CompletionStage)6 Function (java.util.function.Function)6 Transaction (javax.transaction.Transaction)6 TransactionManager (javax.transaction.TransactionManager)6 MediaType (org.infinispan.commons.dataconversion.MediaType)6 TimeService (org.infinispan.commons.time.TimeService)6 Configuration (org.infinispan.configuration.cache.Configuration)6 CacheEntry (org.infinispan.container.entries.CacheEntry)6 FlagBitSets (org.infinispan.context.impl.FlagBitSets)6