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));
        }
      }
    }