CFEL - ASG Software Suite  2.5.0
CASS
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
cass::RingBuffer< T > Class Template Reference

A Ringbuffer, handles communication between Input and Worker Threads. More...

#include <ringbuffer.hpp>

+ Inheritance diagram for cass::RingBuffer< T >:
+ Collaboration diagram for cass::RingBuffer< T >:

Classes

class  Element
 an element of the ringbuffer. More...
 

Public Types

typedef std::vector< Elementbuffer_t
 type of the container of all elements More...
 
typedef buffer_t::iterator iter_type
 type of the interator over the elements of the container More...
 

Public Member Functions

 RingBuffer (size_t size)
 constructor. More...
 
 ~RingBuffer ()
 destructor More...
 
iter_type nextToProcess (unsigned long timeout=ULONG_MAX)
 return the next filled but non processed element. More...
 
void doneProcessing (iter_type iter)
 putting the processed element back to the buffer. More...
 
iter_type nextToFill (unsigned long timeout=ULONG_MAX)
 retrieve the "to be filled" element. More...
 
void doneFilling (iter_type iter, bool fillstatus=true)
 putting the filled element back to the buffer. More...
 
int countProcessing ()
 count how many elements of the buffer are not processed More...
 
void waitUntilEmpty ()
 wait until no element that needs processing is on the list More...
 
iter_type end ()
 

Private Member Functions

bool findNextProcessable ()
 advances the _nextToProcess iterator to the next processable element. More...
 
bool findNextFillable ()
 advances the _nextToFill itertor to the next fillable element. More...
 

Private Attributes

QMutex _mutex
 mutex to protect the iterators and the buffer elements More...
 
QWaitCondition _fillcondition
 sync the filling part More...
 
QWaitCondition _processcondition
 sync the processing part More...
 
buffer_t _buffer
 the ringbuffer container More...
 
iter_type _nextToProcess
 iterator to the next processable element More...
 
iter_type _nextToFill
 iterator to the next fillable element More...
 

Detailed Description

template<typename T>
class cass::RingBuffer< T >

A Ringbuffer, handles communication between Input and Worker Threads.

The ringbuffer handles the main communication between the single producers (input derived from InputBase) and the multiple consumers (worker).

The ringbuffer can be compiled or non blocking by defining RINGBUFFER_BLOCKING or not, respectively.

It is designed in such a way, that in the nonblocking case, the consumers do not block the producer from putting new entries into the ringbuffer. If the producers velocity in filling the buffer varies, then this buffer will make sure, that it can be faster than the consumers. When the producer fills elements slower than the consumers consume them, then the consumers can consume the elements that have already been put into the buffer. They will do this by going backwards through the buffer from the last element that the producer has put into the buffer. The ringbuffers' elements will be created on the Heap.

Template Parameters
TElement typ
Todo:

find out how one can use std::find to find the right element

maybe create a ReadWriteLock for each element to get rid of the mutexes

separeate declaration and definition to make class more readable

Author
Lutz Foucar

Definition at line 52 of file ringbuffer.hpp.

Member Typedef Documentation

template<typename T>
typedef std::vector<Element> cass::RingBuffer< T >::buffer_t

type of the container of all elements

Definition at line 90 of file ringbuffer.hpp.

template<typename T>
typedef buffer_t::iterator cass::RingBuffer< T >::iter_type

type of the interator over the elements of the container

Definition at line 93 of file ringbuffer.hpp.

Constructor & Destructor Documentation

template<typename T>
cass::RingBuffer< T >::RingBuffer ( size_t  size)
inline

constructor.

This will create the buffer, fill it with the requested amount of elements, and initialize the iterators.

Parameters
sizeThe size of the ringbuffer

Definition at line 102 of file ringbuffer.hpp.

template<typename T>
cass::RingBuffer< T >::~RingBuffer ( )
inline

destructor

Definition at line 112 of file ringbuffer.hpp.

Member Function Documentation

template<typename T>
int cass::RingBuffer< T >::countProcessing ( )
inline

count how many elements of the buffer are not processed

The number of elements in the buffer that are not processed tell how many are still beeing processed.

Returns
number of elements that are in processing state

Definition at line 355 of file ringbuffer.hpp.

Referenced by cass::RingBuffer< cass::CASSEvent >::waitUntilEmpty().

template<typename T>
void cass::RingBuffer< T >::doneFilling ( iter_type  iter,
bool  fillstatus = true 
)
inline

putting the filled element back to the buffer.

This function will put the element that we just filled back to the buffer. It will will search the buffer for the element and then set the flags of that element according to its current state and depending on the fillstatus. Using the fillstatus we can say that this element should be processed or not.

Returns
void
[in] element reference to the pointer of the element
[in] fillstatus True when the element should be processed, false if not.

set the status properties according to the fillstatus

set the next to process iterator to this element, since its the next element that we should process. This should shorten the time we are searching for the next processable element

notify the waiting condition that something new is in the buffer

Note
we need to unlock the lock before

Definition at line 325 of file ringbuffer.hpp.

template<typename T>
void cass::RingBuffer< T >::doneProcessing ( iter_type  iter)
inline

putting the processed element back to the buffer.

This function will put the element that we just processed back to the buffer. It will will search the buffer for the element and then set the flags of that element according to its current state.

Returns
void
[in] iterator to the element in the buffer that is done processing

set flags

notify the waiting condition that something new is in the buffer

Note
we need to unlock the lock before

Definition at line 252 of file ringbuffer.hpp.

template<typename T>
iter_type cass::RingBuffer< T >::end ( )
inline
Returns
the end element of the buffer (which is not good)

Definition at line 379 of file ringbuffer.hpp.

Referenced by cass::RingBuffer< cass::CASSEvent >::countProcessing().

template<typename T>
bool cass::RingBuffer< T >::findNextFillable ( )
inlineprivate

advances the _nextToFill itertor to the next fillable element.

this function is used when the behaviour of the ringbuffer is blockable it will iterate through the buffer and checks the elements for the status in progress (inBearbeitung) and processed (bearbeitet) it will only return true when its not in progress and already processed.

this function is used when the behaviour of the ringbuffer is nonblockable it will iterate through the buffer and checks the elements for only the status in progress (inBearbeitung). it will only return true when its not in progress.

Returns
true when a fillable element has been found

the start point is one before the current point where we started

search until the current element is not currently in use

if we end up where we started, then the elements are not yet processed or still in progress, so retrun that we have not found anything yet.

wrap to beginning if we hit the end

Definition at line 166 of file ringbuffer.hpp.

Referenced by cass::RingBuffer< cass::CASSEvent >::nextToFill().

template<typename T>
bool cass::RingBuffer< T >::findNextProcessable ( )
inlineprivate

advances the _nextToProcess iterator to the next processable element.

will go through the whole ringbuffer backwards starting at the position where the _nextToProcess pointer was put. It will check whether the current element is not currently in use, has been not been filled and is processed. If thats the case we need to check for the next element

Returns
true when a processable element has been found

stop at the next item in tbe buffer

search until the current element is not currently in use or not filled yet

stop at the position 1 beyond the start

we go backwards through the buffer to have always the latest element to process. If we come to the beginning of the vector, then we have to jump to the back

Definition at line 126 of file ringbuffer.hpp.

Referenced by cass::RingBuffer< cass::CASSEvent >::nextToProcess().

template<typename T>
iter_type cass::RingBuffer< T >::nextToFill ( unsigned long  timeout = ULONG_MAX)
inline

retrieve the "to be filled" element.

This function will retrieve the next element that we can fill. Depending on the behaviour of the ringbuffer, we check whether it has been processed or not. When the behaviour is blocking then we only retrieve elements that are processed, if not then we just return the next element that is not in process. In the blocking case this function will only return when a processed event was put into the buffer.

Returns
iterator to the element that can be filled and in case a timeout occured, return the end iterator of the buffer.
Parameters
[in]timeoutTime that we will wait that a new fillable element is beeing made available. It is defaulted to ULONG_MAX

find an fillable element of the buffer, if there is no fillable, wait until a new element has been processed

Note
this is blocking until an element has been processed

Set the flags accordingly

the next element should be one that we are going to fill next. Therefore decrease the iterator by one

Definition at line 284 of file ringbuffer.hpp.

template<typename T>
iter_type cass::RingBuffer< T >::nextToProcess ( unsigned long  timeout = ULONG_MAX)
inline

return the next filled but non processed element.

This function will return the next filled element, which will either be the one just filled by the shared memory input or one or more before, depending on how fast elements are retrieved before they are filled again. When there are no Elements that we can work on, this function will wait until there is a new element that we can process.

Note
this can be the reason why only one of the threads is working at a time.
Returns
iterator to the element of the ringbuffer that is processable and in case a timeout occured, return the end iterator of the buffer.
Parameters
[in]timeoutTime that we will wait that a new element is beeing put into the buffer. It is defaulted to ULONG_MAX

if nothing was found, wait until we get noticed that a new element was added to the buffer and return 0 if waited long enough

set the flags of that element

The next element that will be asked for is the previous one. Unless a new element to be processed has been added to the buffer therefore let the iterator point to the previous element

Definition at line 215 of file ringbuffer.hpp.

template<typename T>
void cass::RingBuffer< T >::waitUntilEmpty ( )
inline

wait until no element that needs processing is on the list

this function is blocking until all elements in the buffer are in the processed state.

Definition at line 371 of file ringbuffer.hpp.

Member Data Documentation

template<typename T>
buffer_t cass::RingBuffer< T >::_buffer
private
template<typename T>
QWaitCondition cass::RingBuffer< T >::_fillcondition
private
template<typename T>
QMutex cass::RingBuffer< T >::_mutex
private
template<typename T>
iter_type cass::RingBuffer< T >::_nextToFill
private

iterator to the next fillable element

Definition at line 398 of file ringbuffer.hpp.

Referenced by cass::RingBuffer< cass::CASSEvent >::findNextFillable(), and cass::RingBuffer< cass::CASSEvent >::nextToFill().

template<typename T>
iter_type cass::RingBuffer< T >::_nextToProcess
private
template<typename T>
QWaitCondition cass::RingBuffer< T >::_processcondition
private

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