@Override
 public ReplaceStatus replace(final K key, final V oldValue, final V newValue)
     throws StoreAccessException {
   conditionalReplaceObserver.begin();
   try {
     ConditionalReplaceOperation<K, V> operation =
         new ConditionalReplaceOperation<K, V>(
             key, oldValue, newValue, timeSource.getTimeMillis());
     ByteBuffer payload = codec.encode(operation);
     Chain chain = storeProxy.getAndAppend(key.hashCode(), payload);
     ResolvedChain<K, V> resolvedChain = resolver.resolve(chain, key, timeSource.getTimeMillis());
     Result<V> result = resolvedChain.getResolvedResult(key);
     if (result != null) {
       if (oldValue.equals(result.getValue())) {
         conditionalReplaceObserver.end(StoreOperationOutcomes.ConditionalReplaceOutcome.REPLACED);
         return ReplaceStatus.HIT;
       } else {
         conditionalReplaceObserver.end(StoreOperationOutcomes.ConditionalReplaceOutcome.MISS);
         return ReplaceStatus.MISS_PRESENT;
       }
     } else {
       conditionalReplaceObserver.end(StoreOperationOutcomes.ConditionalReplaceOutcome.MISS);
       return ReplaceStatus.MISS_NOT_PRESENT;
     }
   } catch (RuntimeException re) {
     handleRuntimeException(re);
     return null;
   }
 }
 private PutStatus silentPut(final K key, final V value) throws StoreAccessException {
   try {
     PutOperation<K, V> operation = new PutOperation<K, V>(key, value, timeSource.getTimeMillis());
     ByteBuffer payload = codec.encode(operation);
     Chain chain = storeProxy.getAndAppend(key.hashCode(), payload);
     ResolvedChain<K, V> resolvedChain = resolver.resolve(chain, key, timeSource.getTimeMillis());
     if (resolvedChain.getResolvedResult(key) == null) {
       return PutStatus.PUT;
     } else {
       return PutStatus.UPDATE;
     }
   } catch (RuntimeException re) {
     handleRuntimeException(re);
     return PutStatus.NOOP;
   }
 }
 private boolean silentRemove(final K key) throws StoreAccessException {
   try {
     RemoveOperation<K, V> operation = new RemoveOperation<K, V>(key, timeSource.getTimeMillis());
     ByteBuffer payload = codec.encode(operation);
     Chain chain = storeProxy.getAndAppend(key.hashCode(), payload);
     ResolvedChain<K, V> resolvedChain = resolver.resolve(chain, key, timeSource.getTimeMillis());
     if (resolvedChain.getResolvedResult(key) != null) {
       return true;
     } else {
       return false;
     }
   } catch (RuntimeException re) {
     handleRuntimeException(re);
     return false;
   }
 }
  private V getInternal(K key) throws StoreAccessException {
    V value = null;
    try {
      Chain chain = storeProxy.get(key.hashCode());
      if (!chain.isEmpty()) {
        ResolvedChain<K, V> resolvedChain =
            resolver.resolve(chain, key, timeSource.getTimeMillis());

        Chain compactedChain = resolvedChain.getCompactedChain();
        storeProxy.replaceAtHead(key.hashCode(), chain, compactedChain);

        Result<V> resolvedResult = resolvedChain.getResolvedResult(key);
        if (resolvedResult != null) {
          value = resolvedResult.getValue();
        }
      }
    } catch (RuntimeException re) {
      handleRuntimeException(re);
    }
    return value;
  }
 @Override
 public ValueHolder<V> replace(final K key, final V value) throws StoreAccessException {
   replaceObserver.begin();
   try {
     ReplaceOperation<K, V> operation =
         new ReplaceOperation<K, V>(key, value, timeSource.getTimeMillis());
     ByteBuffer payload = codec.encode(operation);
     Chain chain = storeProxy.getAndAppend(key.hashCode(), payload);
     ResolvedChain<K, V> resolvedChain = resolver.resolve(chain, key, timeSource.getTimeMillis());
     Result<V> result = resolvedChain.getResolvedResult(key);
     if (result == null) {
       replaceObserver.end(StoreOperationOutcomes.ReplaceOutcome.MISS);
       return null;
     } else {
       replaceObserver.end(StoreOperationOutcomes.ReplaceOutcome.REPLACED);
       return new ClusteredValueHolder<V>(result.getValue());
     }
   } catch (RuntimeException re) {
     handleRuntimeException(re);
     return null;
   }
 }