ByteBuf for Key instead of String for codec-memcache

Motivation:

The key can be ByteBuf to avoid converting between ByteBuf and String. See #3689.

Modifications:

Replace the type of key with ByteBuf.

Result:

The type of key becomes ByteBuf.
This commit is contained in:
Xiaoyan Lin 2016-01-29 09:58:35 -08:00 committed by Norman Maurer
parent f43dc7d551
commit 36aa11937d
15 changed files with 84 additions and 70 deletions

View File

@ -24,12 +24,9 @@ import io.netty.handler.codec.memcache.DefaultLastMemcacheContent;
import io.netty.handler.codec.memcache.DefaultMemcacheContent;
import io.netty.handler.codec.memcache.LastMemcacheContent;
import io.netty.handler.codec.memcache.MemcacheContent;
import io.netty.util.CharsetUtil;
import java.util.List;
import static io.netty.buffer.ByteBufUtil.*;
/**
* Decoder for both {@link BinaryMemcacheRequest} and {@link BinaryMemcacheResponse}.
* <p/>
@ -90,7 +87,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
return;
}
currentMessage.setExtras(readBytes(ctx.alloc(), in, extrasLength));
currentMessage.setExtras(in.readSlice(extrasLength).retain());
}
state = State.READ_KEY;
@ -106,8 +103,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
return;
}
currentMessage.setKey(in.toString(in.readerIndex(), keyLength, CharsetUtil.UTF_8));
in.skipBytes(keyLength);
currentMessage.setKey(in.readSlice(keyLength).retain());
}
out.add(currentMessage.retain());
state = State.READ_CONTENT;
@ -135,7 +131,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
toRead = remainingLength;
}
ByteBuf chunkBuffer = readBytes(ctx.alloc(), in, toRead);
ByteBuf chunkBuffer = in.readSlice(toRead).retain();
MemcacheContent chunk;
if ((alreadyReadChunkSize += toRead) >= valueLength) {

View File

@ -64,12 +64,12 @@ public abstract class AbstractBinaryMemcacheEncoder<M extends BinaryMemcacheMess
* @param buf the {@link ByteBuf} to write into.
* @param key the key to encode.
*/
private static void encodeKey(ByteBuf buf, String key) {
if (key == null || key.isEmpty()) {
private static void encodeKey(ByteBuf buf, ByteBuf key) {
if (key == null || !key.isReadable()) {
return;
}
buf.writeBytes(key.getBytes(CharsetUtil.UTF_8));
buf.writeBytes(key);
}
/**

View File

@ -28,7 +28,7 @@ public abstract class AbstractBinaryMemcacheMessage
/**
* Contains the optional key.
*/
private String key;
private ByteBuf key;
/**
* Contains the optional extras.
@ -50,13 +50,13 @@ public abstract class AbstractBinaryMemcacheMessage
* @param key the message key.
* @param extras the message extras.
*/
protected AbstractBinaryMemcacheMessage(String key, ByteBuf extras) {
protected AbstractBinaryMemcacheMessage(ByteBuf key, ByteBuf extras) {
this.key = key;
this.extras = extras;
}
@Override
public String key() {
public ByteBuf key() {
return key;
}
@ -66,13 +66,19 @@ public abstract class AbstractBinaryMemcacheMessage
}
@Override
public BinaryMemcacheMessage setKey(String key) {
public BinaryMemcacheMessage setKey(ByteBuf key) {
if (this.key != null) {
this.key.release();
}
this.key = key;
return this;
}
@Override
public BinaryMemcacheMessage setExtras(ByteBuf extras) {
if (this.extras != null) {
this.extras.release();
}
this.extras = extras;
return this;
}
@ -179,6 +185,9 @@ public abstract class AbstractBinaryMemcacheMessage
@Override
protected void deallocate() {
if (key != null) {
key.release();
}
if (extras != null) {
extras.release();
}
@ -192,6 +201,9 @@ public abstract class AbstractBinaryMemcacheMessage
@Override
public BinaryMemcacheMessage touch(Object hint) {
if (key != null) {
key.touch(hint);
}
if (extras != null) {
extras.touch(hint);
}

View File

@ -160,14 +160,16 @@ public interface BinaryMemcacheMessage extends MemcacheMessage {
*
* @return the key of the document.
*/
String key();
ByteBuf key();
/**
* Sets the key of the document.
* Sets the key of the document. {@link ByteBuf#release()} ownership of {@code key}
* is transferred to this {@link BinaryMemcacheMessage}.
*
* @param key the key of the message.
* @param key the key of the message. {@link ByteBuf#release()} ownership is transferred
* to this {@link BinaryMemcacheMessage}.
*/
BinaryMemcacheMessage setKey(String key);
BinaryMemcacheMessage setKey(ByteBuf key);
/**
* Returns a {@link ByteBuf} representation of the optional extras.
@ -177,9 +179,11 @@ public interface BinaryMemcacheMessage extends MemcacheMessage {
ByteBuf extras();
/**
* Sets the extras buffer on the message.
* Sets the extras buffer on the message. {@link ByteBuf#release()} ownership of {@code extras}
* is transferred to this {@link BinaryMemcacheMessage}.
*
* @param extras the extras buffer of the document.
* @param extras the extras buffer of the document. {@link ByteBuf#release()} ownership is transferred
* to this {@link BinaryMemcacheMessage}.
*/
BinaryMemcacheMessage setExtras(ByteBuf extras);

View File

@ -53,9 +53,10 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg
}
private static FullBinaryMemcacheRequest toFullRequest(BinaryMemcacheRequest request, ByteBuf content) {
ByteBuf key = request.key() == null ? null : request.key().retain();
ByteBuf extras = request.extras() == null ? null : request.extras().retain();
FullBinaryMemcacheRequest fullRequest =
new DefaultFullBinaryMemcacheRequest(request.key(), extras, content);
new DefaultFullBinaryMemcacheRequest(key, extras, content);
fullRequest.setMagic(request.magic());
fullRequest.setOpcode(request.opcode());
@ -71,9 +72,10 @@ public class BinaryMemcacheObjectAggregator extends AbstractMemcacheObjectAggreg
}
private static FullBinaryMemcacheResponse toFullResponse(BinaryMemcacheResponse response, ByteBuf content) {
ByteBuf key = response.key() == null ? null : response.key().retain();
ByteBuf extras = response.extras() == null ? null : response.extras().retain();
FullBinaryMemcacheResponse fullResponse =
new DefaultFullBinaryMemcacheResponse(response.key(), extras, content);
new DefaultFullBinaryMemcacheResponse(key, extras, content);
fullResponse.setMagic(response.magic());
fullResponse.setOpcode(response.opcode());

View File

@ -49,6 +49,6 @@ public class BinaryMemcacheRequestDecoder
@Override
protected BinaryMemcacheRequest buildInvalidMessage() {
return new DefaultBinaryMemcacheRequest("", Unpooled.EMPTY_BUFFER);
return new DefaultBinaryMemcacheRequest(Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER);
}
}

View File

@ -49,6 +49,6 @@ public class BinaryMemcacheResponseDecoder
@Override
protected BinaryMemcacheResponse buildInvalidMessage() {
return new DefaultBinaryMemcacheResponse("", Unpooled.EMPTY_BUFFER);
return new DefaultBinaryMemcacheResponse(Unpooled.EMPTY_BUFFER, Unpooled.EMPTY_BUFFER);
}
}

View File

@ -41,26 +41,17 @@ public class DefaultBinaryMemcacheRequest extends AbstractBinaryMemcacheMessage
*
* @param key the key to use.
*/
public DefaultBinaryMemcacheRequest(String key) {
public DefaultBinaryMemcacheRequest(ByteBuf key) {
this(key, null);
}
/**
* Create a new {@link DefaultBinaryMemcacheRequest} with the header and extras.
*
* @param extras the extras to use.
*/
public DefaultBinaryMemcacheRequest(ByteBuf extras) {
this(null, extras);
}
/**
* Create a new {@link DefaultBinaryMemcacheRequest} with the header only.
*
* @param key the key to use.
* @param extras the extras to use.
*/
public DefaultBinaryMemcacheRequest(String key, ByteBuf extras) {
public DefaultBinaryMemcacheRequest(ByteBuf key, ByteBuf extras) {
super(key, extras);
setMagic(REQUEST_MAGIC_BYTE);
}

View File

@ -41,26 +41,17 @@ public class DefaultBinaryMemcacheResponse extends AbstractBinaryMemcacheMessage
*
* @param key the key to use
*/
public DefaultBinaryMemcacheResponse(String key) {
public DefaultBinaryMemcacheResponse(ByteBuf key) {
this(key, null);
}
/**
* Create a new {@link DefaultBinaryMemcacheResponse} with the header and extras.
*
* @param extras the extras to use.
*/
public DefaultBinaryMemcacheResponse(ByteBuf extras) {
this(null, extras);
}
/**
* Create a new {@link DefaultBinaryMemcacheResponse} with the header, key and extras.
*
* @param key the key to use.
* @param extras the extras to use.
*/
public DefaultBinaryMemcacheResponse(String key, ByteBuf extras) {
public DefaultBinaryMemcacheResponse(ByteBuf key, ByteBuf extras) {
super(key, extras);
setMagic(RESPONSE_MAGIC_BYTE);
}

View File

@ -32,7 +32,7 @@ public class DefaultFullBinaryMemcacheRequest extends DefaultBinaryMemcacheReque
* @param key the key to use.
* @param extras the extras to use.
*/
public DefaultFullBinaryMemcacheRequest(String key, ByteBuf extras) {
public DefaultFullBinaryMemcacheRequest(ByteBuf key, ByteBuf extras) {
this(key, extras, Unpooled.buffer(0));
}
@ -43,7 +43,7 @@ public class DefaultFullBinaryMemcacheRequest extends DefaultBinaryMemcacheReque
* @param extras the extras to use.
* @param content the content of the full request.
*/
public DefaultFullBinaryMemcacheRequest(String key, ByteBuf extras,
public DefaultFullBinaryMemcacheRequest(ByteBuf key, ByteBuf extras,
ByteBuf content) {
super(key, extras);
if (content == null) {
@ -91,19 +91,27 @@ public class DefaultFullBinaryMemcacheRequest extends DefaultBinaryMemcacheReque
@Override
public FullBinaryMemcacheRequest copy() {
ByteBuf key = key();
if (key != null) {
key = key.copy();
}
ByteBuf extras = extras();
if (extras != null) {
extras = extras.copy();
}
return new DefaultFullBinaryMemcacheRequest(key(), extras, content().copy());
return new DefaultFullBinaryMemcacheRequest(key, extras, content().copy());
}
@Override
public FullBinaryMemcacheRequest duplicate() {
ByteBuf key = key();
if (key != null) {
key = key.duplicate();
}
ByteBuf extras = extras();
if (extras != null) {
extras = extras.duplicate();
}
return new DefaultFullBinaryMemcacheRequest(key(), extras, content().duplicate());
return new DefaultFullBinaryMemcacheRequest(key, extras, content().duplicate());
}
}

View File

@ -32,7 +32,7 @@ public class DefaultFullBinaryMemcacheResponse extends DefaultBinaryMemcacheResp
* @param key the key to use.
* @param extras the extras to use.
*/
public DefaultFullBinaryMemcacheResponse(String key, ByteBuf extras) {
public DefaultFullBinaryMemcacheResponse(ByteBuf key, ByteBuf extras) {
this(key, extras, Unpooled.buffer(0));
}
@ -43,7 +43,7 @@ public class DefaultFullBinaryMemcacheResponse extends DefaultBinaryMemcacheResp
* @param extras the extras to use.
* @param content the content of the full request.
*/
public DefaultFullBinaryMemcacheResponse(String key, ByteBuf extras,
public DefaultFullBinaryMemcacheResponse(ByteBuf key, ByteBuf extras,
ByteBuf content) {
super(key, extras);
if (content == null) {
@ -91,19 +91,27 @@ public class DefaultFullBinaryMemcacheResponse extends DefaultBinaryMemcacheResp
@Override
public FullBinaryMemcacheResponse copy() {
ByteBuf key = key();
if (key != null) {
key = key.copy();
}
ByteBuf extras = extras();
if (extras != null) {
extras = extras.copy();
}
return new DefaultFullBinaryMemcacheResponse(key(), extras, content().copy());
return new DefaultFullBinaryMemcacheResponse(key, extras, content().copy());
}
@Override
public FullBinaryMemcacheResponse duplicate() {
ByteBuf key = key();
if (key != null) {
key = key.duplicate();
}
ByteBuf extras = extras();
if (extras != null) {
extras = extras.duplicate();
}
return new DefaultFullBinaryMemcacheResponse(key(), extras, content().duplicate());
return new DefaultFullBinaryMemcacheResponse(key, extras, content().duplicate());
}
}

View File

@ -256,10 +256,10 @@ public class BinaryMemcacheDecoderTest {
new BinaryMemcacheRequestEncoder(),
new BinaryMemcacheRequestDecoder());
String key = "Netty";
ByteBuf key = Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8);
ByteBuf extras = Unpooled.copiedBuffer("extras", CharsetUtil.UTF_8);
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key, extras);
request.setKeyLength((short) key.length());
request.setKeyLength((short) key.readableBytes());
request.setExtrasLength((byte) extras.readableBytes());
assertTrue(channel.writeOutbound(request));

View File

@ -85,7 +85,7 @@ public class BinaryMemcacheEncoderTest {
ByteBuf extras = Unpooled.copiedBuffer(extrasContent, CharsetUtil.UTF_8);
int extrasLength = extras.readableBytes();
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(extras);
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(Unpooled.EMPTY_BUFFER, extras);
request.setExtrasLength((byte) extrasLength);
boolean result = channel.writeOutbound(request);
@ -100,8 +100,8 @@ public class BinaryMemcacheEncoderTest {
@Test
public void shouldEncodeKey() {
String key = "netty";
int keyLength = key.length();
ByteBuf key = Unpooled.copiedBuffer("netty", CharsetUtil.UTF_8);
int keyLength = key.readableBytes();
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key);
request.setKeyLength((byte) keyLength);
@ -112,7 +112,7 @@ public class BinaryMemcacheEncoderTest {
ByteBuf written = channel.readOutbound();
assertThat(written.readableBytes(), is(DEFAULT_HEADER_SIZE + keyLength));
written.readBytes(DEFAULT_HEADER_SIZE);
assertThat(written.readBytes(keyLength).toString(CharsetUtil.UTF_8), equalTo(key));
assertThat(written.readBytes(keyLength).toString(CharsetUtil.UTF_8), equalTo("netty"));
written.release();
}

View File

@ -86,17 +86,17 @@ public class BinaryMemcacheObjectAggregatorTest {
new BinaryMemcacheRequestDecoder(),
new BinaryMemcacheObjectAggregator(MAX_CONTENT_SIZE));
String key = "Netty";
ByteBuf key = Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8);
ByteBuf extras = Unpooled.copiedBuffer("extras", CharsetUtil.UTF_8);
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key, extras);
request.setKeyLength((short) key.length());
request.setKeyLength((short) key.readableBytes());
request.setExtrasLength((byte) extras.readableBytes());
DefaultMemcacheContent content1 =
new DefaultMemcacheContent(Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8));
DefaultLastMemcacheContent content2 =
new DefaultLastMemcacheContent(Unpooled.copiedBuffer(" Rocks!", CharsetUtil.UTF_8));
int totalBodyLength = key.length() + extras.readableBytes() +
int totalBodyLength = key.readableBytes() + extras.readableBytes() +
content1.content().readableBytes() + content2.content().readableBytes();
request.setTotalBodyLength(totalBodyLength);
@ -107,7 +107,7 @@ public class BinaryMemcacheObjectAggregatorTest {
FullBinaryMemcacheRequest read = channel.readInbound();
assertThat(read, notNullValue());
assertThat(read.key(), is("Netty"));
assertThat(read.key().toString(CharsetUtil.UTF_8), is("Netty"));
assertThat(read.extras().toString(CharsetUtil.UTF_8), is("extras"));
assertThat(read.content().toString(CharsetUtil.UTF_8), is("Netty Rocks!"));

View File

@ -36,12 +36,13 @@ public class MemcacheClientHandler extends ChannelDuplexHandler {
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
String command = (String) msg;
if (command.startsWith("get ")) {
String key = command.substring("get ".length());
String keyString = command.substring("get ".length());
ByteBuf key = Unpooled.wrappedBuffer(keyString.getBytes(CharsetUtil.UTF_8));
BinaryMemcacheRequest req = new DefaultBinaryMemcacheRequest(key);
req.setOpcode(BinaryMemcacheOpcodes.GET);
req.setKeyLength((short) key.length());
req.setTotalBodyLength(key.length());
req.setKeyLength((short) key.readableBytes());
req.setTotalBodyLength(key.readableBytes());
ctx.write(req, promise);
} else if (command.startsWith("set ")) {
@ -49,18 +50,19 @@ public class MemcacheClientHandler extends ChannelDuplexHandler {
if (parts.length < 3) {
throw new IllegalArgumentException("Malformed Command: " + command);
}
String key = parts[1];
String keyString = parts[1];
String value = parts[2];
ByteBuf key = Unpooled.wrappedBuffer(keyString.getBytes(CharsetUtil.UTF_8));
ByteBuf content = Unpooled.wrappedBuffer(value.getBytes(CharsetUtil.UTF_8));
ByteBuf extras = ctx.alloc().buffer(8);
extras.writeZero(8);
BinaryMemcacheRequest req = new DefaultFullBinaryMemcacheRequest(key, extras, content);
req.setOpcode(BinaryMemcacheOpcodes.SET);
req.setKeyLength((short) key.length());
req.setKeyLength((short) key.readableBytes());
req.setExtrasLength((byte) 8);
req.setTotalBodyLength(key.length() + 8 + value.length());
req.setTotalBodyLength(key.readableBytes() + 8 + value.length());
ctx.write(req, promise);
} else {