|
|
|
@ -27,7 +27,7 @@
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
package org.redisson.client.handler;
|
|
|
|
|
|
|
|
|
@ -44,6 +44,10 @@ import org.redisson.config.CommandMapper;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
import java.util.stream.LongStream;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Redis protocol command encoder
|
|
|
|
|
*
|
|
|
|
@ -59,6 +63,21 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
|
|
|
|
|
private static final char BYTES_PREFIX = '$';
|
|
|
|
|
private static final byte[] CRLF = "\r\n".getBytes();
|
|
|
|
|
|
|
|
|
|
private static final Integer LONG_TO_STRING_CACHE_SIZE = 1000;
|
|
|
|
|
|
|
|
|
|
private static final List<byte[]> LONG_TO_STRING_CACHE = LongStream.range(0, LONG_TO_STRING_CACHE_SIZE)
|
|
|
|
|
.mapToObj(Long::toString)
|
|
|
|
|
.map(s -> s.getBytes(CharsetUtil.US_ASCII))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
public static byte[] longToString(long number) {
|
|
|
|
|
if (number < LONG_TO_STRING_CACHE.size()) {
|
|
|
|
|
return LONG_TO_STRING_CACHE.get((int) number);
|
|
|
|
|
} else {
|
|
|
|
|
return Long.toString(number).getBytes(CharsetUtil.US_ASCII);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private CommandMapper commandMapper;
|
|
|
|
|
|
|
|
|
|
public CommandEncoder(CommandMapper commandMapper) {
|
|
|
|
@ -80,7 +99,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void encode(ChannelHandlerContext ctx, CommandData<?, ?> msg, ByteBuf out) throws Exception {
|
|
|
|
|
try {
|
|
|
|
@ -89,7 +108,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
|
|
|
|
|
if (msg.getCommand().getSubName() != null) {
|
|
|
|
|
len++;
|
|
|
|
|
}
|
|
|
|
|
out.writeCharSequence(Long.toString(len), CharsetUtil.US_ASCII);
|
|
|
|
|
out.writeBytes(longToString(len));
|
|
|
|
|
out.writeBytes(CRLF);
|
|
|
|
|
|
|
|
|
|
String name = commandMapper.map(msg.getCommand().getName());
|
|
|
|
@ -105,7 +124,7 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
|
|
|
|
|
buf.release();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (log.isTraceEnabled()) {
|
|
|
|
|
String info = out.toString(CharsetUtil.UTF_8);
|
|
|
|
|
if (RedisCommands.AUTH.equals(msg.getCommand())) {
|
|
|
|
@ -138,18 +157,18 @@ public class CommandEncoder extends MessageToByteEncoder<CommandData<?, ?>> {
|
|
|
|
|
ByteBufUtil.writeUtf8(buf, payload);
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void writeArgument(ByteBuf out, byte[] arg) {
|
|
|
|
|
out.writeByte(BYTES_PREFIX);
|
|
|
|
|
out.writeCharSequence(Long.toString(arg.length), CharsetUtil.US_ASCII);
|
|
|
|
|
out.writeBytes(longToString(arg.length));
|
|
|
|
|
out.writeBytes(CRLF);
|
|
|
|
|
out.writeBytes(arg);
|
|
|
|
|
out.writeBytes(CRLF);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void writeArgument(ByteBuf out, ByteBuf arg) {
|
|
|
|
|
out.writeByte(BYTES_PREFIX);
|
|
|
|
|
out.writeCharSequence(Long.toString(arg.readableBytes()), CharsetUtil.US_ASCII);
|
|
|
|
|
out.writeBytes(longToString(arg.readableBytes()));
|
|
|
|
|
out.writeBytes(CRLF);
|
|
|
|
|
out.writeBytes(arg, arg.readerIndex(), arg.readableBytes());
|
|
|
|
|
out.writeBytes(CRLF);
|
|
|
|
|