The Mem Ops Bytes class represents a sequence of bytes from a byte array. It can be a sequence
of bytes from a shared byte array, as obtained from one of the byte allocators
BytesAllocatorManualDefrag, or a byte array created via the
To avoid fragmenting the Java heap with
Bytes instances, the
Bytes class is designed
to be obtained from an ObjectPool . Thus, the
Bytes object can be
returned to the
ObjectPool after the byte sequence it references has been freed back to the
bytes allocator they were allocated from.
Creating a Bytes ObjectPool
To use the
Bytes class effectively you should create a
BytesFactory and an
ObjectPool . Here is how that looks:
BytesAllocatorAutoDefrag byteArrayAllocator = new BytesAllocatorAutoDefrag(new byte[1024 * 1024]); BytesFactory bytesFactory = new BytesFactory(byteArrayAllocator); ObjectPool<Bytes> objectPool = new ObjectPool<Bytes>(16,bytesFactory);
Obtaining a Bytes Instance
To obtain a
Bytes instance from the
ObjectPool you simply call the
instance() method. Here is an example of obtaining a
instance from the
Bytes bytes = objectPool.instance();
Allocate Byte Sequence
Once you have obtained a
Bytes instance from the
ObjectPool you will need to allocate
a sequence of bytes from the
BytesAllocatorAutoDefrag. Here is how you allocate a byte sequence
ByteAllocatorAutoDefrag via the
This example allocates 1024 bytes from the
When you are done with the byte sequence, and the
Bytes instance, you need to free the byte sequence
Bytes instance again. You do so by calling the
free() will free the
Bytes instance back to the
and the allocated bytes back to the
Here is an example of how to free a
Bytes instance including the byte sequence it has allocated:
Bytes object has several fields which you can use to access and work with the allocated byte sequence
Bytes object represents. Each of these fields will be covered in the following sections.
Bytes field is a reference to the byte array in which the byte sequence is allocated.
You need this reference in order to read bytes from, or write bytes to the allocated byte sequence. Here is an example:
byte value = bytes.data[someIndex]; bytes.data[someIndex] = 123;
Bytes field contains the index in the byte array referenced by the
data field where your allocated byte sequence starts. The
startIndex field contains
the index of the first byte of this byte sequence.
Bytes field contains the length in bytes of the allocated byte
sequence represented by this
Bytes field contains the first index after the last byte in the
allocated byte sequence. In other words, the byte referenced by
endIndex is not part of the byte
sequence, but the byte just before it is.
endIndex is equal to
endIndex will be equal to the
startIndex of the next byte sequence allocated right after the byte sequence represented by this
Bytes field is an index you can use when writing bytes into the allocated
byte sequence. The
writeIndex can be used to keep track of how many bytes you have already written to
the byte sequence. Also, in case you don't use all of the allocated bytes in the byte sequence, the
writeIndex can help you keep track of how many bytes you actually wrote into the byte sequence.
For instance, imagine you have to write a response from a server back to a client. You know the response will never exceed 1 MB, so you allocate a byte sequence of 1 MB to hold the response. The response might only end up requiring e.g. 38 KB, so only these 38 KB of the 1 MB allocated byte sequence to should be written back to the client.
writeIndex field can then be used to keep track of the bytes written to the byte sequence.
In the example above, the
writeIndex will point to the first byte after the 38 KB byte written.
Thus, the bytes to write back to the client are the bytes from and including
writeIndex. In other words,
writeIndex is like the
but of the actual bytes written, not of the whole allocated byte sequence.
Bytes field can be used when reading the bytes that were actually written
to the allocated byte sequence. For instance, if 38 KB were written into a 1 MB allocated sequence, then only the
first 38 KB of the allocated sequence should be read again. Thus, when sending back a response to a client,
you will have to read those 38 KB out of the byte sequence and write them to a network socket. The
readIndex can be used to help you keep track of how many bytes you have actually read, in case you
are not able to read them all in one go.
Use Case Examples
In this section I will try to give you a few visual use case examples that shows how to use the
class, and its fields. The use cases are actually quite similar in how they use the
Bytes class, even
if they are doing different things.
Receiving and Processing a Message
Imagine your code runs in a server that receives messages from clients. When a message arrives you need to store it in memory before processing it, and then you need to process it too.
First, you start with a shared byte array from which you can allocate a byte sequence to store the incoming message:
Second, you allocate a byte sequence from this shared byte array which is big enough to handle any message that is within acceptable message size limits:
Third, you write the incoming message into the allocated byte sequence, advancing the
while doing so:
Fourth, you start processing the message in the allocated byte sequence, advancing
readIndex as you
process more and more of the message:
Sending a Response to a Client
Imagine your code runs in a server that receives messages from clients. After processing a message you may need to send back a response to the client.
First, you start with a shared byte array from which you can allocate the byte sequence to generate the response into, before sending it back to the client:
Second, you allocate a byte sequence big enough to hold any response that is within acceptable response message size limits:
Third, you generate the response message into the allocated byte sequence, advancing the
while generating the response:
Fourth, you need to read the generated response message and send it back to the client. While reading
and sending the generated response back, you advance the