Hazelcast C++ Client
Public Member Functions | Friends | List of all members
hazelcast::client::mixedtype::Ringbuffer Class Reference

A Ringbuffer is a data-structure where the content is stored in a ring like structure. More...

#include <Ringbuffer.h>

+ Inheritance diagram for hazelcast::client::mixedtype::Ringbuffer:

Public Member Functions

 Ringbuffer (const Ringbuffer &rhs)
 
int64_t capacity ()
 Returns the capacity of this Ringbuffer. More...
 
int64_t size ()
 Returns number of items in the ringbuffer. More...
 
int64_t tailSequence ()
 Returns the sequence of the tail. More...
 
int64_t headSequence ()
 Returns the sequence of the head. More...
 
int64_t remainingCapacity ()
 Returns the remaining capacity of the ringbuffer. More...
 
template<typename E >
int64_t add (const E &item)
 Adds an item to the tail of the Ringbuffer. More...
 
TypedData readOne (int64_t sequence)
 Reads one item from the Ringbuffer. More...
 

Friends

class client::impl::HazelcastClientInstanceImpl
 

Detailed Description

A Ringbuffer is a data-structure where the content is stored in a ring like structure.

A ringbuffer has a capacity so it won't grow beyond that capacity and endanger the stability of the system. If that capacity is exceeded, than the oldest item in the ringbuffer is overwritten.

The ringbuffer has 2 always incrementing sequences:

  1. tailSequence: this is the side where the youngest item is found. So the tail is the side of the ringbuffer where items are added to.
  2. headSequence: this is the side where the oldest items are found. So the head is the side where items gets discarded.

The items in the ringbuffer can be found by a sequence that is in between (inclusive) the head and tail sequence.

If data is read from a ringbuffer with a sequence that is smaller than the headSequence, it means that the data is not available anymore and a StaleSequenceException is thrown.

A Ringbuffer currently is not a distributed data-structure. So all data is stored in a single partition; comparable to the IQueue implementation. But we'll provide an option to partition the data in the near future.

A Ringbuffer can be used in a similar way as a queue, but one of the key differences is that a queue.take is destructive, meaning that only 1 thread is able to take an item. A ringbuffer.read is not destructive, so you can have multiple threads reading the same item multiple times.

The Ringbuffer is the backing data-structure for the reliable com.hazelcast.core.ITopic implementation. See com.hazelcast.config.ReliableTopicConfig.

Member Function Documentation

◆ add()

template<typename E >
int64_t hazelcast::client::mixedtype::Ringbuffer::add ( const E &  item)
inline

Adds an item to the tail of the Ringbuffer.

If there is no space in the Ringbuffer, the add will overwrite the oldest item in the ringbuffer no matter what the ttl is. For more control on this behavior.

The returned value is the sequence of the added item. Using this sequence you can read the added item.

Using the sequence as id

This sequence will always be unique for this Ringbuffer instance so it can be used as a unique id generator if you are publishing items on this Ringbuffer. However you need to take care of correctly determining an initial id when any node uses the ringbuffer for the first time. The most reliable way to do that is to write a dummy item into the ringbuffer and use the returned sequence as initial id. On the reading side, this dummy item should be discard. Please keep in mind that this id is not the sequence of the item you are about to publish but from a previously published item. So it can't be used to find that item.

Parameters
itemthe item to add.
Returns
the sequence of the added item.

◆ capacity()

int64_t hazelcast::client::mixedtype::Ringbuffer::capacity ( )

Returns the capacity of this Ringbuffer.

Returns
the capacity.

◆ headSequence()

int64_t hazelcast::client::mixedtype::Ringbuffer::headSequence ( )

Returns the sequence of the head.

The head is the side of the ringbuffer where the oldest items in the ringbuffer are found.

If the RingBuffer is empty, the head will be one more than the tail.

The initial value of the head is 0 (1 more than tail).

Returns
the sequence of the head.

◆ readOne()

TypedData hazelcast::client::mixedtype::Ringbuffer::readOne ( int64_t  sequence)

Reads one item from the Ringbuffer.

If the sequence is one beyond the current tail, this call blocks until an item is added.

This means that the ringbuffer can be processed using the following idiom: Ringbuffer<String> ringbuffer = client.getRingbuffer<E>("rb"); long seq = ringbuffer.headSequence(); while(true){ String item = ringbuffer.readOne(seq); seq++; ... process item }

This method is not destructive unlike e.g. a queue.take. So the same item can be read by multiple readers or it can be read multiple times by the same reader.

Currently it isn't possible to control how long this call is going to block. In the future we could add e.g. tryReadOne(long sequence, long timeout, TimeUnit unit).

Parameters
sequencethe sequence of the item to read.
Returns
the read item
Exceptions
StaleSequenceExceptionif the sequence is smaller then headSequence(). Because a Ringbuffer won't store all event indefinitely, it can be that the data for the given sequence doesn't exist anymore and the StaleSequenceException is thrown. It is up to the caller to deal with this particular situation, e.g. throw an Exception or restart from the last known head. That is why the StaleSequenceException contains the last known head.
java.lang.IllegalArgumentExceptionif sequence is smaller than 0 or larger than tailSequence()+1.
InterruptedExceptionif the call is interrupted while blocking.

◆ remainingCapacity()

int64_t hazelcast::client::mixedtype::Ringbuffer::remainingCapacity ( )

Returns the remaining capacity of the ringbuffer.

The returned value could be stale as soon as it is returned.

If ttl is not set, the remaining capacity will always be the capacity.

Returns
the remaining capacity.

◆ size()

int64_t hazelcast::client::mixedtype::Ringbuffer::size ( )

Returns number of items in the ringbuffer.

If no ttl is set, the size will always be equal to capacity after the head completed the first loop around the ring. This is because no items are getting retired.

Returns
the size.

◆ tailSequence()

int64_t hazelcast::client::mixedtype::Ringbuffer::tailSequence ( )

Returns the sequence of the tail.

The tail is the side of the ringbuffer where the items are added to.

The initial value of the tail is -1.

Returns
the sequence of the tail.

The documentation for this class was generated from the following files: