Skip to content

Instantly share code, notes, and snippets.

@ndimiduk
Created February 20, 2014 18:38
Show Gist options
  • Save ndimiduk/9120342 to your computer and use it in GitHub Desktop.
Save ndimiduk/9120342 to your computer and use it in GitHub Desktop.
package bufperf;
import sun.nio.ch.DirectBuffer;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
public class DirectByteBufferUtils {
static final Field buffer_address;
static final Field buffer_capacity;
static {
try {
buffer_address = Buffer.class.getDeclaredField("address");
buffer_address.setAccessible(true);
buffer_capacity = Buffer.class.getDeclaredField("capacity");
buffer_capacity.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Use the public API to retireve a new slice on `source` of given length.
*/
public static ByteBuffer getNextSlice(final ByteBuffer source, final int size) {
ByteBuffer b = (ByteBuffer) source.slice().limit(size);
source.position(source.position() + size);
return b;
}
/**
* Create an empty shell of a DirectByteBuffer instance that thinks it is of the specified capacity.
*/
public static ByteBuffer allocateDirectShell(final int size) throws Exception {
ByteBuffer b = ByteBuffer.allocateDirect(0);
buffer_capacity.setInt(b, size);
return b;
}
/**
* Use reflection to update the state of `updateMe` to be as a slice of `source` of the specified length.
*/
public static void updateSlice(final DirectBuffer source, final DirectBuffer updateMe, final int size) throws Exception {
ByteBuffer sourceAsBB = (ByteBuffer) source;
ByteBuffer meAsBB = (ByteBuffer) updateMe;
meAsBB.limit(size);
buffer_address.setLong(updateMe, source.address() + (sourceAsBB.position() << 0));
buffer_capacity.setInt(updateMe, size);
meAsBB.clear();
sourceAsBB.position(sourceAsBB.position() + size);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment