/**
 * Memcached protocol decoder
 *
 * @author dennis
 */
public class MemcachedDecoder implements Decoder {

  public static final Logger log = LoggerFactory.getLogger(MemcachedDecoder.class);

  public MemcachedDecoder() {
    super();
  }

  /** shift-and algorithm for ByteBuffer's match */
  public static final ByteBufferMatcher SPLIT_MATCHER =
      new ShiftAndByteBufferMatcher(IoBuffer.wrap(ByteUtils.SPLIT));

  public Object decode(IoBuffer buffer, Session origSession) {
    MemcachedTCPSession session = (MemcachedTCPSession) origSession;
    if (session.getCurrentCommand() != null) {
      return decode0(buffer, session);
    } else {
      session.takeCurrentCommand();
      if (session.getCurrentCommand() == null) return null;
      return decode0(buffer, session);
    }
  }

  private Object decode0(IoBuffer buffer, MemcachedTCPSession session) {
    if (session.getCurrentCommand().decode(session, buffer.buf())) {
      final Command command = session.getCurrentCommand();
      session.setCurrentCommand(null);
      return command;
    }
    return null;
  }
}
Esempio n. 2
0
  private Command newMergedCommand(
      final Map<Object, Command> mergeCommands,
      int mergeCount,
      final CommandCollector commandCollector,
      final CommandType commandType) {
    if (protocol == Protocol.Text) {
      String resultKey = (String) commandCollector.getResult();

      byte[] keyBytes = ByteUtils.getBytes(resultKey);
      byte[] cmdBytes = commandType == CommandType.GET_ONE ? Constants.GET : Constants.GETS;
      final byte[] buf = new byte[cmdBytes.length + 3 + keyBytes.length];
      ByteUtils.setArguments(buf, 0, cmdBytes, keyBytes);
      TextGetOneCommand cmd = new TextGetOneCommand(resultKey, keyBytes, commandType, null);
      cmd.setMergeCommands(mergeCommands);
      cmd.setWriteFuture(new FutureImpl<Boolean>());
      cmd.setMergeCount(mergeCount);
      cmd.setIoBuffer(IoBuffer.wrap(buf));
      return cmd;
    } else {
      BinaryGetMultiCommand result = (BinaryGetMultiCommand) commandCollector.getResult();
      result.setMergeCount(mergeCount);
      result.setMergeCommands(mergeCommands);
      return result;
    }
  }
Esempio n. 3
0
 public Object getResult() {
   byte[] buf = new byte[totalBytes];
   int offset = 0;
   for (IoBuffer buffer : bufferList) {
     byte[] ba = buffer.array();
     System.arraycopy(ba, 0, buf, offset, ba.length);
     offset += ba.length;
   }
   BinaryGetMultiCommand resultCommand =
       new BinaryGetMultiCommand(null, CommandType.GET_MANY, new CountDownLatch(1));
   resultCommand.setIoBuffer(IoBuffer.wrap(buf));
   return resultCommand;
 }
 @Override
 public final void encode() {
   int size = Constants.DELETE.length + 1 + this.keyBytes.length + Constants.CRLF.length;
   if (isNoreply()) {
     size += 8;
   }
   byte[] buf = new byte[size];
   if (isNoreply()) {
     ByteUtils.setArguments(buf, 0, Constants.DELETE, this.keyBytes, Constants.NO_REPLY);
   } else {
     ByteUtils.setArguments(buf, 0, Constants.DELETE, this.keyBytes);
   }
   this.ioBuffer = IoBuffer.wrap(buf);
 }
Esempio n. 5
0
 /**
  * �峰�涓��琛�
  *
  * @param buffer
  */
 public static final String nextLine(ByteBuffer buffer) {
   if (buffer == null) {
     return null;
   }
   /**
    * 娴��琛ㄦ���� Shift-And绠���归� >BM绠���归���� > �寸��归� > KMP�归�锛�
    * 濡��浣���村ソ��缓璁��璇�mail缁��([email protected])
    */
   int index =
       MemcachedDecoder.SPLIT_MATCHER.matchFirst(
           com.google.code.yanf4j.buffer.IoBuffer.wrap(buffer));
   if (index >= 0) {
     int limit = buffer.limit();
     buffer.limit(index);
     byte[] bytes = new byte[buffer.remaining()];
     buffer.get(bytes);
     buffer.limit(limit);
     buffer.position(index + ByteUtils.SPLIT.remaining());
     return getString(bytes);
   }
   return null;
 }
Esempio n. 6
0
  @SuppressWarnings("unchecked")
  private final Command mergeBuffer(
      final Command firstCommand,
      final Queue writeQueue,
      final Queue<Command> executingCmds,
      final int sendBufferSize) {
    Command lastCommand = firstCommand; // ��苟������涓�ommand
    Command nextCmd = (Command) writeQueue.peek();
    if (nextCmd == null) {
      return lastCommand;
    }

    final List<Command> commands = getLocalList();
    final ByteBuffer firstBuffer = firstCommand.getIoBuffer().buf();
    int totalBytes = firstBuffer.remaining();
    commands.add(firstCommand);
    boolean wasFirst = true;
    while (totalBytes + nextCmd.getIoBuffer().remaining() <= sendBufferSize
        && (nextCmd = (Command) writeQueue.peek()) != null) {
      if (nextCmd.getStatus() == OperationStatus.WRITING) {
        break;
      }
      if (nextCmd.isCancel()) {
        writeQueue.remove();
        continue;
      }
      nextCmd.setStatus(OperationStatus.WRITING);

      writeQueue.remove();

      if (wasFirst) {
        wasFirst = false;
      }
      // if it is get_one command,try to merge get commands
      if ((nextCmd.getCommandType() == CommandType.GET_ONE
              || nextCmd.getCommandType() == CommandType.GETS_ONE)
          && optimiezeGet) {
        nextCmd = mergeGetCommands(nextCmd, writeQueue, executingCmds, nextCmd.getCommandType());
      }

      commands.add(nextCmd);
      lastCommand = nextCmd;
      totalBytes += nextCmd.getIoBuffer().remaining();
      if (totalBytes > sendBufferSize) {
        break;
      }
    }
    if (commands.size() > 1) {
      byte[] buf = new byte[totalBytes];
      int offset = 0;
      for (Command command : commands) {
        byte[] ba = command.getIoBuffer().array();
        System.arraycopy(ba, 0, buf, offset, ba.length);
        offset += ba.length;
        if (command != lastCommand
            && (!command.isNoreply() || command instanceof BaseBinaryCommand)) {
          executingCmds.add(command);
        }
      }
      lastCommand.setIoBuffer(IoBuffer.wrap(buf));
    }
    return lastCommand;
  }