Class ByteBufferSupply
1) It can be used as a simple supply of ByteBuffer(Item)s. In this mode, only get() and release() are called. A user does a get(), uses that buffer, then calls release() when done with it. If there are multiple users of a single buffer (say 5), then call bufferItem.setUsers(5) before it is used and the buffer is only released when all 5 users have called release().
2) As in the first usage, it can be used as a supply of ByteBuffers, but each buffer can be preset to a specific ByteBuffer object. Thus it can act as a supply of buffers in which each contains specific data. Because of the circular nature of the ring used to implement this code, after all ByteBuffers have been gotten by the user for the first time, it starts back over with the first -- going round and round.
To implement this, use the constructor which takes a list of ByteBuffer objects with which to fill this supply. The user does a getAsIs() which does not clear the buffer's position and limit. When finished reading/writing, user calls release(). It's up to the user to maintain proper values for the buffer's position and limit since it will be used again. If there are multiple users of a single buffer (say 5), then call bufferItem.setUsers(5) before it is used and the buffer is only released when all 5 users have called release().
3) It can be used as a supply of ByteBuffers in which a single
producer provides data for a single consumer which is waiting for that data.
The producer does a get(), fills the buffer with data, and finally does a publish()
to let the consumer know the data is ready. Simultaneously, a consumer does a
consumerGet() to access the data once it is ready. To access the ByteBuffer contained
int the ByteBufferItem, call ByteBufferItem.getBufferAsIs(), do NOT
call ByteBufferItem.getBuffer() as that clears the returned buffer.
The consumer then calls release(ByteBufferItem) when finished which
allows the producer to reuse the now unused buffer.
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionByteBufferSupply(int ringSize, int bufferSize) Constructor.ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct) Constructor.ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct, boolean orderedRelease) Constructor.ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct, boolean orderedRelease, org.jlab.coda.jevio.EvioNodePool[] pools) Constructor.ByteBufferSupply(int ringSize, List<ByteBuffer> bufList, boolean orderedRelease) Constructor. -
Method Summary
Modifier and TypeMethodDescriptionGet the next available item in ring buffer for getting data already written into.get()Get the next available item in ring buffer for writing/reading data.voidget(int n, ByteBufferItem[] items) Get the next "n" available item in ring buffer for writing/reading data.getAsIs()Get the next available item in ring buffer for writing/reading data.intWhat percentage of the byte buffers are being used? If this ring is full (of unused buffers), it corresponds to an empty input or output channel (0%).voidpublish(int n, ByteBufferItem[] items) Used to tell that the consumer that the ring buffer items are ready for consumption.voidpublish(ByteBufferItem byteBufferItem) Used to tell that the consumer that the ring buffer item is ready for consumption.voidrelease(ByteBufferItem item) Consumer releases claim on the given ring buffer item so it becomes available for reuse.
-
Field Details
-
auxObject
Object to be associated with each ByteBufferItem.
-
-
Constructor Details
-
ByteBufferSupply
Constructor. Buffers are big endian and not direct.- Parameters:
ringSize- number of ByteBufferItem objects in ring buffer.bufferSize- initial size (bytes) of ByteBuffer in each ByteBufferItem object.- Throws:
IllegalArgumentException- if args < 1 or ringSize not power of 2.
-
ByteBufferSupply
public ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct) throws IllegalArgumentException Constructor.- Parameters:
ringSize- number of ByteBufferItem objects in ring buffer.bufferSize- initial size (bytes) of ByteBuffer in each ByteBufferItem object.order- byte order of ByteBuffer in each ByteBufferItem object.direct- if true, make ByteBuffers direct.- Throws:
IllegalArgumentException- if args < 1 or ringSize not power of 2.
-
ByteBufferSupply
public ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct, boolean orderedRelease) throws IllegalArgumentException Constructor. Used when wanting to avoid locks for speed purposes. Say a ByteBufferItem is used by several users. This is true in ET or emu input channels in which many evio events all contain a reference to the same buffer. If the user can guarantee that all the users of one buffer release it before any of the users of the next, then synchronization is not necessary. If that isn't the case, then locks take care of preventing a later acquired buffer from being released first and consequently everything that came before it in the ring.- Parameters:
ringSize- number of ByteBufferItem objects in ring buffer.bufferSize- initial size (bytes) of ByteBuffer in each ByteBufferItem object.order- byte order of ByteBuffer in each ByteBufferItem object.direct- if true, make ByteBuffers direct.orderedRelease- if true, the user promises to release the ByteBufferItems in the same order as acquired. This avoids using synchronized code (no locks).- Throws:
IllegalArgumentException- if args < 1 or ringSize not power of 2.
-
ByteBufferSupply
public ByteBufferSupply(int ringSize, int bufferSize, ByteOrder order, boolean direct, boolean orderedRelease, org.jlab.coda.jevio.EvioNodePool[] pools) throws IllegalArgumentException Constructor. Used when wanting to avoid locks for speed purposes. Say a ByteBufferItem is used by several users. This is true in ET or emu input channels in which many evio events all contain a reference to the same buffer. If the user can guarantee that all the users of one buffer release it before any of the users of the next, then synchronization is not necessary. If that isn't the case, then locks take care of preventing a later acquired buffer from being released first and consequently everything that came before it in the ring.In addition, each ByteBufferItem in this supply will have an object associated with it which is passed in through the last argument. Used to store an EvioNodePool with each buffer in the supply.
- Parameters:
ringSize- number of ByteBufferItem objects in ring buffer.bufferSize- initial size (bytes) of ByteBuffer in each ByteBufferItem object.order- byte order of ByteBuffer in each ByteBufferItem object.direct- if true, make ByteBuffers direct.orderedRelease- if true, the user promises to release the ByteBufferItems in the same order as acquired. This avoids using synchronized code (no locks).pools- one EvioNodePool for each ByteBuffer.- Throws:
IllegalArgumentException- if args < 1 or ringSize not power of 2, pools array must have not be null or have less than ringSize number of elements.
-
ByteBufferSupply
public ByteBufferSupply(int ringSize, List<ByteBuffer> bufList, boolean orderedRelease) throws IllegalArgumentException Constructor. Used when wanting a source of ByteBuffers which already contain data. Useful when testing.- Parameters:
ringSize- number of ByteBufferItem objects in ring buffer.bufList- list of ByteBuffers used to populate this supply. List must contain ringSize number of buffers.orderedRelease- if true, the user promises to release the ByteBufferItems in the same order as acquired. This avoids using synchronized code (no locks).- Throws:
IllegalArgumentException- bad arg or ringSize not power of 2.
-
-
Method Details
-
getFillLevel
public int getFillLevel()What percentage of the byte buffers are being used? If this ring is full (of unused buffers), it corresponds to an empty input or output channel (0%). In this case, (ringSize - (ringSize - (produced - consumed))) = (produced - consumed) = 0. If it's empty then the channel is full (100%). In this case, (produced - consumed) = ringSize.- Returns:
- fill level, 0% to 100%.
-
get
Get the next available item in ring buffer for writing/reading data. Not sure if this method is thread-safe.- Returns:
- next available item in ring buffer.
- Throws:
InterruptedException- if thread interrupted.
-
get
Get the next "n" available item in ring buffer for writing/reading data. This may only be used in conjunction with:publish(ByteBufferItem)or preferablypublish(int, ByteBufferItem[]). Not sure if this method is thread-safe.- Parameters:
n- number of ring buffer items to get.items- array big enough to hold an array of n items.- Throws:
InterruptedException- if thread interrupted.
-
getAsIs
Get the next available item in ring buffer for writing/reading data. Does not set the ByteBuffer to position = 0 and limit = capacity. In other words, it facilitates reading existing data from the buffer. When finished with this item, it's up to the user to set position and limit to the correct value for the next user. Not sure if this method is thread-safe.- Returns:
- next available item in ring buffer.
- Throws:
InterruptedException- if thread interrupted.
-
consumerGet
Get the next available item in ring buffer for getting data already written into. Not sure if this method is thread-safe.- Returns:
- next available item in ring buffer for getting data already written into.
- Throws:
InterruptedException- if thread interrupted.
-
release
Consumer releases claim on the given ring buffer item so it becomes available for reuse. This method ensures that sequences are released in order and is thread-safe. To be used in conjunction withget()andconsumerGet().- Parameters:
item- item in ring buffer to release for reuse.
-
publish
Used to tell that the consumer that the ring buffer item is ready for consumption. Note, it also publishes all previously gotten items! Not sure if this method is thread-safe. To be used in conjunction withget()andconsumerGet().- Parameters:
byteBufferItem- item available for consumer's use.
-
publish
Used to tell that the consumer that the ring buffer items are ready for consumption. This may only be used in conjunction withget(int, ByteBufferItem[]). Not sure if this method is thread-safe.- Parameters:
n- number of array items available for consumer's use.items- array of items available for consumer's use.
-