@Override public CompletableFuture<Void> visitReadOnlyKeyCommand( InvocationContext ctx, ReadOnlyKeyCommand command) throws Throwable { try { CacheEntry entry = entryFactory.wrapEntryForReading(ctx, command.getKey(), null); // Null entry is often considered to mean that entry is not available // locally, but if there's no need to get remote, the read-only // function needs to be executed, so force a non-null entry in // context with null content if (entry == null && cdl.localNodeIsOwner(command.getKey())) { entryFactory.wrapEntryForReading(ctx, command.getKey(), NullCacheEntry.getInstance()); } return ctx.shortCircuit(ctx.forkInvocationSync(command)); } finally { // needed because entries might be added in L1 if (!ctx.isInTxScope()) commitContextEntries(ctx, command, null); else { CacheEntry entry = ctx.lookupEntry(command.getKey()); if (entry != null) { entry.setSkipLookup(true); } } } }
@Override public CompletableFuture<Void> visitGetKeysInGroupCommand( final InvocationContext ctx, GetKeysInGroupCommand command) throws Throwable { final String groupName = command.getGroupName(); if (!command.isGroupOwner()) { return ctx.continueInvocation(); } final KeyFilter<Object> keyFilter = new CompositeKeyFilter<>( new GroupFilter<>(groupName, groupManager), new CollectionKeyFilter<>(ctx.getLookedUpEntries().keySet())); dataContainer.executeTask( keyFilter, (o, internalCacheEntry) -> { synchronized (ctx) { // the process can be made in multiple threads, so we need to synchronize in the // context. entryFactory.wrapExternalEntry( ctx, internalCacheEntry.getKey(), internalCacheEntry, EntryFactory.Wrap.STORE, false); } }); return ctx.continueInvocation(); }
private void wrapEntryForPutIfNeeded(InvocationContext ctx, AbstractDataWriteCommand command) throws Throwable { if (shouldWrap(command.getKey(), ctx, command)) { boolean skipRead = command.hasFlag(Flag.IGNORE_RETURN_VALUES) && !command.isConditional(); entryFactory.wrapEntryForWriting( ctx, command.getKey(), EntryFactory.Wrap.WRAP_ALL, skipRead, false); } }
@Override public CompletableFuture<Void> visitReadWriteManyEntriesCommand( InvocationContext ctx, ReadWriteManyEntriesCommand command) throws Throwable { for (Object key : command.getEntries().keySet()) { if (shouldWrap(key, ctx, command)) { entryFactory.wrapEntryForWriting(ctx, key, EntryFactory.Wrap.WRAP_ALL, false, false); } } return setSkipRemoteGetsAndInvokeNextForPutMapCommand(ctx, command); }
private void wrapEntryForRemoveIfNeeded(InvocationContext ctx, RemoveCommand command) throws InterruptedException { if (shouldWrap(command.getKey(), ctx, command)) { boolean forceWrap = command.getValueMatcher().nonExistentEntryCanMatch(); EntryFactory.Wrap wrap = forceWrap ? EntryFactory.Wrap.WRAP_ALL : EntryFactory.Wrap.WRAP_NON_NULL; boolean skipRead = command.hasFlag(Flag.IGNORE_RETURN_VALUES) && !command.isConditional(); entryFactory.wrapEntryForWriting(ctx, command.getKey(), wrap, skipRead, false); } }
@Override public CompletableFuture<Void> visitWriteOnlyManyCommand( InvocationContext ctx, WriteOnlyManyCommand command) throws Throwable { for (Object key : command.getKeys()) { if (shouldWrap(key, ctx, command)) { // the put map never reads the keys entryFactory.wrapEntryForWriting(ctx, key, EntryFactory.Wrap.WRAP_ALL, true, false); } } return setSkipRemoteGetsAndInvokeNextForPutMapCommand(ctx, command); }
@Override public CompletableFuture<Void> visitInvalidateL1Command( InvocationContext ctx, InvalidateL1Command command) throws Throwable { for (Object key : command.getKeys()) { // for the invalidate command, we need to try to fetch the key from the data container // otherwise it may be not removed entryFactory.wrapEntryForWriting(ctx, key, EntryFactory.Wrap.WRAP_NON_NULL, false, true); if (trace) log.tracef("Entry to be removed: %s", toStr(key)); } return setSkipRemoteGetsAndInvokeNextForDataCommand(ctx, command, null); }
private void wrapEntryForReplaceIfNeeded(InvocationContext ctx, ReplaceCommand command) throws InterruptedException { if (shouldWrap(command.getKey(), ctx, command)) { // When retrying, we might still need to perform the command even if the previous value was // removed EntryFactory.Wrap wrap = command.getValueMatcher().nonExistentEntryCanMatch() ? EntryFactory.Wrap.WRAP_ALL : EntryFactory.Wrap.WRAP_NON_NULL; entryFactory.wrapEntryForWriting(ctx, command.getKey(), wrap, false, false); } }
private CompletableFuture<Void> visitDataReadCommand( InvocationContext ctx, AbstractDataCommand command) throws Throwable { try { entryFactory.wrapEntryForReading(ctx, command.getKey(), null); return ctx.shortCircuit(ctx.forkInvocationSync(command)); } finally { // needed because entries might be added in L1 if (!ctx.isInTxScope()) commitContextEntries(ctx, command, null); else { CacheEntry entry = ctx.lookupEntry(command.getKey()); if (entry != null) { entry.setSkipLookup(true); } } } }
@Override public CompletableFuture<Void> visitReadOnlyManyCommand( InvocationContext ctx, ReadOnlyManyCommand command) throws Throwable { try { for (Object key : command.getKeys()) { entryFactory.wrapEntryForReading(ctx, key, null); } return ctx.shortCircuit(ctx.forkInvocationSync(command)); } finally { if (ctx.isInTxScope()) { for (Object key : command.getKeys()) { CacheEntry entry = ctx.lookupEntry(key); if (entry != null) { entry.setSkipLookup(true); } } } } }
@Override public CompletableFuture<Void> visitApplyDeltaCommand( InvocationContext ctx, ApplyDeltaCommand command) throws Throwable { entryFactory.wrapEntryForDelta(ctx, command.getKey(), command.getDelta()); return ctx.continueInvocation(); }
private void lockAndWrap(InvocationContext ctx, Object key, InternalCacheEntry ice) throws InterruptedException { lockManager.acquireLock(ctx, key); entryFactory.wrapEntryForPut(ctx, key, ice, false); }