/** * Merge get operation to multi-get operation * * @param currentCmd * @param mergeCommands * @return * @throws InterruptedException */ @SuppressWarnings("unchecked") public final Command optimiezeGet( final Queue writeQueue, final Queue<Command> executingCmds, Command optimiezeCommand) { if (optimiezeCommand.getCommandType() == CommandType.GET_ONE || optimiezeCommand.getCommandType() == CommandType.GETS_ONE) { // 浼��get��� if (optimiezeGet) { optimiezeCommand = mergeGetCommands( optimiezeCommand, writeQueue, executingCmds, optimiezeCommand.getCommandType()); } } return optimiezeCommand; }
@SuppressWarnings("unchecked") private final Command mergeGetCommands( final Command currentCmd, final Queue writeQueue, final Queue<Command> executingCmds, CommandType expectedCommandType) { Map<Object, Command> mergeCommands = null; int mergeCount = 1; final CommandCollector commandCollector = creatCommandCollector(); currentCmd.setStatus(OperationStatus.WRITING); commandCollector.visit(currentCmd); while (mergeCount < mergeFactor) { Command nextCmd = (Command) writeQueue.peek(); if (nextCmd == null) { break; } if (nextCmd.isCancel()) { writeQueue.remove(); continue; } if (nextCmd.getCommandType() == expectedCommandType) { if (mergeCommands == null) { // lazy initialize mergeCommands = new HashMap<Object, Command>(mergeFactor / 2); mergeCommands.put(currentCmd.getKey(), currentCmd); } if (log.isDebugEnabled()) { log.debug("Merge get command:" + nextCmd.toString()); } nextCmd.setStatus(OperationStatus.WRITING); Command removedCommand = (Command) writeQueue.remove(); // If the key is exists,add the command to associated list. if (mergeCommands.containsKey(removedCommand.getKey())) { final AssocCommandAware mergedGetCommand = (AssocCommandAware) mergeCommands.get(removedCommand.getKey()); if (mergedGetCommand.getAssocCommands() == null) { mergedGetCommand.setAssocCommands(new ArrayList<Command>(5)); } mergedGetCommand.getAssocCommands().add(removedCommand); } else { commandCollector.visit(nextCmd); mergeCommands.put(removedCommand.getKey(), removedCommand); } mergeCount++; } else { break; } } commandCollector.finish(); if (mergeCount == 1) { return currentCmd; } else { if (log.isDebugEnabled()) { log.debug("Merge optimieze:merge " + mergeCount + " get commands"); } return newMergedCommand(mergeCommands, mergeCount, commandCollector, expectedCommandType); } }
@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; }