when needing to copy over the bytes from the netty content channel, zero it out so ti can be GC'ed

This commit is contained in:
Shay Banon 2012-07-05 23:36:27 +02:00
parent 5f1b1c6f69
commit 0a615ca35a
2 changed files with 25 additions and 24 deletions

View File

@ -20,11 +20,9 @@
package org.elasticsearch.http.netty; package org.elasticsearch.http.netty;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.http.HttpRequest; import org.elasticsearch.http.HttpRequest;
import org.elasticsearch.rest.support.AbstractRestRequest; import org.elasticsearch.rest.support.AbstractRestRequest;
import org.elasticsearch.rest.support.RestUtils; import org.elasticsearch.rest.support.RestUtils;
import org.elasticsearch.transport.netty.ChannelBufferStreamInputFactory;
import org.jboss.netty.handler.codec.http.HttpMethod; import org.jboss.netty.handler.codec.http.HttpMethod;
import java.util.HashMap; import java.util.HashMap;
@ -41,11 +39,14 @@ public class NettyHttpRequest extends AbstractRestRequest implements HttpRequest
private final String rawPath; private final String rawPath;
private byte[] cachedData; private final int contentLength;
private byte[] contentAsBytes;
public NettyHttpRequest(org.jboss.netty.handler.codec.http.HttpRequest request) { public NettyHttpRequest(org.jboss.netty.handler.codec.http.HttpRequest request) {
this.request = request; this.request = request;
this.params = new HashMap<String, String>(); this.params = new HashMap<String, String>();
this.contentLength = request.getContent().readableBytes();
String uri = request.getUri(); String uri = request.getUri();
int pathEndPos = uri.indexOf('?'); int pathEndPos = uri.indexOf('?');
@ -100,42 +101,45 @@ public class NettyHttpRequest extends AbstractRestRequest implements HttpRequest
@Override @Override
public boolean hasContent() { public boolean hasContent() {
return request.getContent().readableBytes() > 0; return contentLength > 0;
}
@Override
public StreamInput contentStream() {
return ChannelBufferStreamInputFactory.create(request.getContent());
} }
@Override @Override
public int contentLength() { public int contentLength() {
return request.getContent().readableBytes(); return contentLength;
} }
@Override @Override
public boolean contentUnsafe() { public boolean contentUnsafe() {
// HttpMessageDecoder#content variable gets freshly created for each request and not reused across // if its a copy, then its not unsafe...
// requests if (contentAsBytes != null) {
return false;
}
// HttpMessageDecoder#content is sliced but out of freshly created buffers for each read
return false; return false;
//return request.getContent().hasArray(); //return request.getContent().hasArray();
} }
@Override @Override
public byte[] contentByteArray() { public byte[] contentByteArray() {
if (contentAsBytes != null) {
return contentAsBytes;
}
if (request.getContent().hasArray()) { if (request.getContent().hasArray()) {
return request.getContent().array(); return request.getContent().array();
} }
if (cachedData != null) { contentAsBytes = new byte[request.getContent().readableBytes()];
return cachedData; request.getContent().getBytes(request.getContent().readerIndex(), contentAsBytes);
} // clear the content, so it can be GC'ed, we make sure to work from contentAsBytes from here on
cachedData = new byte[request.getContent().readableBytes()]; request.setContent(null);
request.getContent().getBytes(request.getContent().readerIndex(), cachedData); return contentAsBytes;
return cachedData;
} }
@Override @Override
public int contentByteArrayOffset() { public int contentByteArrayOffset() {
if (contentAsBytes != null) {
return 0;
}
if (request.getContent().hasArray()) { if (request.getContent().hasArray()) {
// get the array offset, and the reader index offset within it // get the array offset, and the reader index offset within it
return request.getContent().arrayOffset() + request.getContent().readerIndex(); return request.getContent().arrayOffset() + request.getContent().readerIndex();
@ -145,6 +149,9 @@ public class NettyHttpRequest extends AbstractRestRequest implements HttpRequest
@Override @Override
public String contentAsString() { public String contentAsString() {
if (contentAsBytes != null) {
return new String(contentAsBytes, Charsets.UTF_8);
}
return request.getContent().toString(Charsets.UTF_8); return request.getContent().toString(Charsets.UTF_8);
} }

View File

@ -19,7 +19,6 @@
package org.elasticsearch.rest; package org.elasticsearch.rest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
@ -59,11 +58,6 @@ public interface RestRequest extends ToXContent.Params {
*/ */
boolean contentUnsafe(); boolean contentUnsafe();
/**
* The content as a stream.
*/
StreamInput contentStream();
byte[] contentByteArray(); byte[] contentByteArray();
int contentByteArrayOffset(); int contentByteArrayOffset();