private boolean needsRemoteGet(InvocationContext ctx, Object key, boolean retvalCheck) {
   final CacheEntry entry;
   return retvalCheck
       && !ctx.hasFlag(Flag.CACHE_MODE_LOCAL)
       && !ctx.hasFlag(Flag.SKIP_REMOTE_LOOKUP)
       && ((entry = ctx.lookupEntry(key)) == null || entry.isNull() || entry.isLockPlaceholder());
 }
  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;
  }
Пример #3
0
 @Override
 public Object perform(InvocationContext ctx) throws Throwable {
   CacheEntry entry = ctx.lookupEntry(key);
   if (entry == null || entry.isNull()) {
     return null;
   }
   if (entry.isRemoved()) {
     return null;
   }
   return entryFactory.copy(entry);
 }
Пример #4
0
  @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;
  }