@Override public Object perform(InvocationContext ctx) throws Throwable { MVCCEntry e = (MVCCEntry) ctx.lookupEntry(key); if (e != null) { if (ctx.isOriginLocal()) { // ISPN-514 if (e.isNull() || e.getValue() == null) { // Revert assumption that new value is to be committed e.setChanged(false); return returnValue(null, false, ctx); } } if (oldValue == null || oldValue.equals(e.getValue()) || ignorePreviousValue) { e.setChanged(true); Object old = e.setValue(newValue); e.setLifespan(lifespanMillis); e.setMaxIdle(maxIdleTimeMillis); return returnValue(old, true, ctx); } // Revert assumption that new value is to be committed e.setChanged(false); } return returnValue(null, false, ctx); }
@Override public final MVCCEntry wrapEntryForRemove(InvocationContext ctx, Object key) throws InterruptedException { CacheEntry cacheEntry = getFromContext(ctx, key); MVCCEntry mvccEntry = null; if (cacheEntry != null) { if (cacheEntry instanceof MVCCEntry && !(cacheEntry instanceof NullMarkerEntry)) { mvccEntry = (MVCCEntry) cacheEntry; } else { mvccEntry = wrapMvccEntryForRemove(ctx, key, cacheEntry); } } else { InternalCacheEntry ice = getFromContainer(key); if (ice != null) { mvccEntry = wrapInternalCacheEntryForPut(ctx, key, ice); } } if (mvccEntry == null) { // make sure we record this! Null value since this is a forced lock on the key ctx.putLookedUpEntry(key, null); } else { mvccEntry.copyForUpdate(container, localModeWriteSkewCheck); } return mvccEntry; }
private MVCCEntry newMvccEntryForPut(InvocationContext ctx, Object key) { MVCCEntry mvccEntry; if (trace) log.trace("Creating new entry."); notifier.notifyCacheEntryCreated(key, true, ctx); mvccEntry = createWrappedEntry(key, null, null, true, false, -1); mvccEntry.setCreated(true); ctx.putLookedUpEntry(key, mvccEntry); notifier.notifyCacheEntryCreated(key, false, ctx); return mvccEntry; }
private MVCCEntry wrapEntry(InvocationContext ctx, Object key) { CacheEntry cacheEntry = getFromContext(ctx, key); MVCCEntry mvccEntry = null; if (cacheEntry != null) { mvccEntry = wrapMvccEntryForPut(ctx, key, cacheEntry); } else { InternalCacheEntry ice = getFromContainer(key); if (ice != null) { mvccEntry = wrapInternalCacheEntryForPut(ctx, ice.getKey(), ice); } } if (mvccEntry != null) mvccEntry.copyForUpdate(container, localModeWriteSkewCheck); return mvccEntry; }
@Override public final MVCCEntry wrapEntryForPut( InvocationContext ctx, Object key, InternalCacheEntry icEntry, boolean undeleteIfNeeded) throws InterruptedException { CacheEntry cacheEntry = getFromContext(ctx, key); MVCCEntry mvccEntry; if (cacheEntry != null && cacheEntry.isNull()) cacheEntry = null; if (cacheEntry != null) { mvccEntry = wrapMvccEntryForPut(ctx, key, cacheEntry); mvccEntry.undelete(undeleteIfNeeded); } else { InternalCacheEntry ice = (icEntry == null ? getFromContainer(key) : icEntry); // A putForExternalRead is putIfAbsent, so if key present, do nothing if (ice != null && ctx.hasFlag(Flag.PUT_FOR_EXTERNAL_READ)) return null; mvccEntry = ice != null ? wrapInternalCacheEntryForPut(ctx, key, ice) : newMvccEntryForPut(ctx, key); } mvccEntry.copyForUpdate(container, localModeWriteSkewCheck); return mvccEntry; }
@Override public Object perform(InvocationContext ctx) throws Throwable { // It's not worth looking up the entry if we're never going to apply the change. if (valueMatcher == ValueMatcher.MATCH_NEVER) { successful = false; return null; } MVCCEntry e = (MVCCEntry) ctx.lookupEntry(key); if (e == null || e.isNull() || e.isRemoved()) { nonExistent = true; if (valueMatcher.matches(e, value, null, valueEquivalence)) { if (e != null) { e.setChanged(true); e.setRemoved(true); } return isConditional() ? true : null; } else { log.trace("Nothing to remove since the entry doesn't exist in the context or it is null"); successful = false; return false; } } if (!valueMatcher.matches(e, value, null, valueEquivalence)) { successful = false; return false; } if (this instanceof EvictCommand) { e.setEvicted(true); } return performRemove(e, ctx); }