private DeltaAwareCacheEntry wrapInternalCacheEntryForDelta( InvocationContext ctx, Object key, CacheEntry cacheEntry) { DeltaAwareCacheEntry e; if (cacheEntry instanceof MVCCEntry) { e = createWrappedDeltaEntry(key, (DeltaAware) cacheEntry.getValue(), cacheEntry); } else { e = createWrappedDeltaEntry(key, (DeltaAware) cacheEntry.getValue(), null); } ctx.putLookedUpEntry(key, e); return e; }
private void raiseEventForInitialTransfer(UUID identifier, CacheEntry entry, boolean clustered) { EventImpl preEvent; if (clustered) { // In clustered mode we only send post event preEvent = null; } else { preEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED); preEvent.setKey(entry.getKey()); preEvent.setPre(true); } EventImpl postEvent = EventImpl.createEvent(cache, CACHE_ENTRY_CREATED); postEvent.setKey(entry.getKey()); postEvent.setValue(entry.getValue()); postEvent.setMetadata(entry.getMetadata()); postEvent.setPre(false); for (CacheEntryListenerInvocation<K, V> invocation : cacheEntryCreatedListeners) { // Now notify all our methods of the creates if (invocation.getIdentifier() == identifier) { if (preEvent != null) { // Non clustered notifications are done twice invocation.invokeNoChecks(preEvent, true, true); } invocation.invokeNoChecks(postEvent, true, true); } } }
@Override public final CacheEntry wrapEntryForReading(InvocationContext ctx, Object key) throws InterruptedException { CacheEntry cacheEntry = getFromContext(ctx, key); if (cacheEntry == null) { cacheEntry = getFromContainer(key); // do not bother wrapping though if this is not in a tx. repeatable read etc are all // meaningless unless there is a tx. if (useRepeatableRead) { MVCCEntry mvccEntry = cacheEntry == null ? createWrappedEntry(key, null, null, false, false, -1) : createWrappedEntry( key, cacheEntry.getValue(), cacheEntry.getVersion(), false, false, cacheEntry.getLifespan()); if (mvccEntry != null) ctx.putLookedUpEntry(key, mvccEntry); return mvccEntry; } else if (cacheEntry != null) { // if not in transaction and repeatable read, or simply read committed // (regardless of whether in TX or not), do not wrap ctx.putLookedUpEntry(key, cacheEntry); } return cacheEntry; } return cacheEntry; }
public static Collection getInternalValues(Cache cache) { DataContainer dataContainer = TestingUtil.extractComponent(cache, DataContainer.class); Collection values = new ArrayList(); for (CacheEntry entry : dataContainer) { values.add(entry.getValue()); } return values; }
private Object realRemoteGet( InvocationContext ctx, Object key, boolean storeInL1, boolean isWrite) throws Throwable { if (trace) log.tracef("Doing a remote get for key %s", key); boolean acquireRemoteLock = false; if (ctx.isInTxScope()) { TxInvocationContext txContext = (TxInvocationContext) ctx; acquireRemoteLock = isWrite && isPessimisticCache && !txContext.getAffectedKeys().contains(key); } // attempt a remote lookup InternalCacheEntry ice = dm.retrieveFromRemoteSource(key, ctx, acquireRemoteLock); if (acquireRemoteLock) { ((TxInvocationContext) ctx).addAffectedKey(key); } if (ice != null) { if (storeInL1) { if (isL1CacheEnabled) { if (trace) log.tracef("Caching remotely retrieved entry for key %s in L1", key); // This should be fail-safe try { long lifespan = ice.getLifespan() < 0 ? configuration.getL1Lifespan() : Math.min(ice.getLifespan(), configuration.getL1Lifespan()); PutKeyValueCommand put = cf.buildPutKeyValueCommand( ice.getKey(), ice.getValue(), lifespan, -1, ctx.getFlags()); lockAndWrap(ctx, key, ice); invokeNextInterceptor(ctx, put); } catch (Exception e) { // Couldn't store in L1 for some reason. But don't fail the transaction! log.infof("Unable to store entry %s in L1 cache", key); log.debug("Inability to store in L1 caused by", e); } } else { CacheEntry ce = ctx.lookupEntry(key); if (ce == null || ce.isNull() || ce.isLockPlaceholder() || ce.getValue() == null) { if (ce != null && ce.isChanged()) { ce.setValue(ice.getValue()); } else { if (isWrite) lockAndWrap(ctx, key, ice); else ctx.putLookedUpEntry(key, ice); } } } } else { if (trace) log.tracef("Not caching remotely retrieved entry for key %s in L1", key); } return ice.getValue(); } return null; }
public static String printCache(Cache cache) { DataContainer dataContainer = TestingUtil.extractComponent(cache, DataContainer.class); Iterator it = dataContainer.iterator(); StringBuilder builder = new StringBuilder(cache.getName() + "["); while (it.hasNext()) { CacheEntry ce = (CacheEntry) it.next(); builder.append(ce.getKey() + "=" + ce.getValue() + ",l=" + ce.getLifespan() + "; "); } builder.append("]"); return builder.toString(); }
private MVCCEntry wrapMvccEntryForRemove( InvocationContext ctx, Object key, CacheEntry cacheEntry) { MVCCEntry mvccEntry = createWrappedEntry( key, cacheEntry.getValue(), cacheEntry.getVersion(), false, true, cacheEntry.getLifespan()); ctx.putLookedUpEntry(key, mvccEntry); return mvccEntry; }
protected Object performRemove(CacheEntry e, InvocationContext ctx) { final Object removedValue = e.getValue(); notify(ctx, removedValue, e.getMetadata(), true); e.setRemoved(true); e.setValid(false); e.setChanged(true); if (valueMatcher != ValueMatcher.MATCH_EXPECTED_OR_NEW) { return isConditional() ? true : removedValue; } else { // Return the expected value when retrying return isConditional() ? true : value; } }
protected void notifyCommitEntry( boolean created, boolean removed, boolean expired, CacheEntry entry, InvocationContext ctx, FlagAffectedCommand command, Object previousValue, Metadata previousMetadata) { boolean isWriteOnly = (command instanceof WriteCommand) && ((WriteCommand) command).isWriteOnly(); if (removed) { if (command instanceof RemoveCommand) { ((RemoveCommand) command).notify(ctx, previousValue, previousMetadata, false); } else { if (expired) { notifier.notifyCacheEntryExpired(entry.getKey(), previousValue, previousMetadata, ctx); } else { notifier.notifyCacheEntryRemoved( entry.getKey(), previousValue, previousMetadata, false, ctx, command); } // A write-only command only writes and so can't 100% guarantee // to be able to retrieve previous value when removed, so only // send remove event when the command is read-write. if (!isWriteOnly) functionalNotifier.notifyOnRemove( EntryViews.readOnly(entry.getKey(), previousValue, previousMetadata)); functionalNotifier.notifyOnWrite(() -> EntryViews.noValue(entry.getKey())); } } else { // Notify entry event after container has been updated if (created) { notifier.notifyCacheEntryCreated( entry.getKey(), entry.getValue(), entry.getMetadata(), false, ctx, command); // A write-only command only writes and so can't 100% guarantee // that an entry has been created, so only send create event // when the command is read-write. if (!isWriteOnly) functionalNotifier.notifyOnCreate(EntryViews.readOnly(entry)); functionalNotifier.notifyOnWrite(() -> EntryViews.readOnly(entry)); } else { notifier.notifyCacheEntryModified( entry.getKey(), entry.getValue(), entry.getMetadata(), previousValue, previousMetadata, false, ctx, command); // A write-only command only writes and so can't 100% guarantee // that an entry has been created, so only send modify when the // command is read-write. if (!isWriteOnly) functionalNotifier.notifyOnModify( EntryViews.readOnly(entry.getKey(), previousValue, previousMetadata), EntryViews.readOnly(entry)); functionalNotifier.notifyOnWrite(() -> EntryViews.readOnly(entry)); } } }