@Override
 public ByteBuffer processBinaryStorageCommand(
     Object key, byte[] value, long cas, int flags, Cache cache, RequestReader request) {
   ByteBuffer response = request.getResponse();
   Region<Object, ValueWrapper> r = getMemcachedRegion(cache);
   ValueWrapper val = ValueWrapper.getWrappedValue(value, flags);
   try {
     Object oldVal = r.putIfAbsent(key, val);
     // set status
     if (oldVal == null) {
       if (getLogger().fineEnabled()) {
         getLogger().fine("added key: " + key);
       }
       if (isQuiet()) {
         return null;
       }
       response.putShort(POSITION_RESPONSE_STATUS, ResponseStatus.NO_ERROR.asShort());
       // set cas
       response.putLong(POSITION_CAS, val.getVersion());
     } else {
       if (getLogger().fineEnabled()) {
         getLogger().fine("key: " + key + " not added as is already exists");
       }
       response.putShort(POSITION_RESPONSE_STATUS, ResponseStatus.KEY_EXISTS.asShort());
     }
   } catch (Exception e) {
     response = handleBinaryException(key, request, response, "add", e);
   }
   return response;
 }
  private ByteBuffer processAsciiCommand(ByteBuffer buffer, Cache cache) {
    CharBuffer flb = getFirstLineBuffer();
    getAsciiDecoder().reset();
    getAsciiDecoder().decode(buffer, flb, false);
    flb.flip();
    String firstLine = getFirstLine();
    String[] firstLineElements = firstLine.split(" ");

    assert "decr".equals(firstLineElements[0]);
    String key = firstLineElements[1];
    String decrByStr = stripNewline(firstLineElements[2]);
    Long decrBy = Long.parseLong(decrByStr);
    boolean noReply = firstLineElements.length > 3;

    Region<Object, ValueWrapper> r = getMemcachedRegion(cache);
    String reply = Reply.NOT_FOUND.toString();
    ByteBuffer newVal = ByteBuffer.allocate(8);
    while (true) {
      ValueWrapper oldValWrapper = r.get(key);
      if (oldValWrapper == null) {
        break;
      }
      newVal.clear();
      byte[] oldVal = oldValWrapper.getValue();
      long oldLong = getLongFromByteArray(oldVal);
      long newLong = oldLong - decrBy;
      newVal.putLong(newLong);
      ValueWrapper newValWrapper = ValueWrapper.getWrappedValue(newVal.array(), 0 /*flags*/);
      if (r.replace(key, oldValWrapper, newValWrapper)) {
        reply = newLong + "\r\n";
        break;
      }
    }
    return noReply ? null : asciiCharset.encode(reply);
  }
 @Override
 public ByteBuffer processStorageCommand(String key, byte[] value, int flags, Cache cache) {
   Region<Object, ValueWrapper> r = getMemcachedRegion(cache);
   Object oldVal = r.putIfAbsent(key, ValueWrapper.getWrappedValue(value, flags));
   String reply = null;
   if (oldVal == null) {
     reply = Reply.STORED.toString();
   } else {
     reply = Reply.NOT_STORED.toString();
   }
   return asciiCharset.encode(reply);
 }
  private ByteBuffer processBinaryProtocol(RequestReader request, Cache cache) {
    ByteBuffer buffer = request.getRequest();
    int extrasLength = buffer.get(EXTRAS_LENGTH_INDEX);
    final KeyWrapper key = getKey(buffer, HEADER_LENGTH + extrasLength);

    long decrBy = buffer.getLong(HEADER_LENGTH);
    long initialVal = buffer.getLong(HEADER_LENGTH + LONG_LENGTH);
    int expiration = buffer.getInt(HEADER_LENGTH + LONG_LENGTH + LONG_LENGTH);

    final Region<Object, ValueWrapper> r = getMemcachedRegion(cache);
    ByteBuffer newVal = ByteBuffer.allocate(8);
    boolean notFound = false;
    ValueWrapper newValWrapper = null;

    try {
      while (true) {
        ValueWrapper oldValWrapper = r.get(key);
        if (oldValWrapper == null) {
          if (expiration == -1) {
            notFound = true;
          } else {
            newVal.putLong(0, initialVal);
            newValWrapper = ValueWrapper.getWrappedValue(newVal.array(), 0 /*flags*/);
            r.put(key, newValWrapper);
          }
          break;
        }
        byte[] oldVal = oldValWrapper.getValue();
        long oldLong = getLongFromByteArray(oldVal);
        long newLong = oldLong - decrBy;
        if (newLong < 0) {
          newLong = 0;
        }
        newVal.putLong(0, newLong);
        newValWrapper = ValueWrapper.getWrappedValue(newVal.array(), 0 /*flags*/);
        if (r.replace(key, oldValWrapper, newValWrapper)) {
          break;
        }
      }
    } catch (Exception e) {
      return handleBinaryException(key, request, request.getResponse(), "decrement", e);
    }

    if (expiration > 0) {
      StorageCommand.getExpiryExecutor()
          .schedule(
              new Runnable() {
                @Override
                public void run() {
                  r.destroy(key);
                }
              },
              expiration,
              TimeUnit.SECONDS);
    }

    if (getLogger().fineEnabled()) {
      getLogger()
          .fine(
              "decr:key:"
                  + key
                  + " decrBy:"
                  + decrBy
                  + " initVal:"
                  + initialVal
                  + " exp:"
                  + expiration
                  + " notFound:"
                  + notFound);
    }

    ByteBuffer response = null;
    if (notFound) {
      response = request.getResponse();
      response.putShort(POSITION_RESPONSE_STATUS, ResponseStatus.KEY_NOT_FOUND.asShort());
    } else {
      if (isQuiet()) {
        return null;
      }
      response = request.getResponse(HEADER_LENGTH + LONG_LENGTH);
      response.putInt(TOTAL_BODY_LENGTH_INDEX, LONG_LENGTH);
      response.putLong(HEADER_LENGTH, newVal.getLong(0));
      response.putLong(POSITION_CAS, newValWrapper.getVersion());
    }
    return response;
  }