GemaCoreLib
The GeMA Core library
Loading...
Searching...
No Matches
GmSingleAppendBuffer< T, Base > Class Template Reference

An implementation of the GmAppendBuffer interface based on synchoronized access to a shared buffer. More...

#include <gmAppendBuffer.h>

Inheritance diagram for GmSingleAppendBuffer< T, Base >:
Collaboration diagram for GmSingleAppendBuffer< T, Base >:

Classes

struct  ControllData
 Aux controll structure storing a buffer. More...
 

Public Member Functions

 GmSingleAppendBuffer (size_t initSize, double resizeFactor=2.0, int numThreads=-1)
 Buffer constructor. Can optionally pre allocate the buffer with initSize entries. If initSize is zero, a call to reserve() MUST be made before any append. The given resizeFactor controlls how the buffer grows in case of a resize. See the class comments for additional info.
 
 ~GmSingleAppendBuffer ()
 Destructor. Releases the allocated memory.
 
virtual void clear ()
 Releases the memory used by the buffer, returning it to a recently constructed state. Must be followed by a call to reserve() before the object is able to do any further appends. Must be called from the main thread only.
 
virtual void reserve (size_t bsize)
 See comments on the base class. Should not be called if the size was given in the constructor.
 
virtual void append (const T &val)
 Appends val to the buffer in a thread safe way. Can grow the buffer if needed.
 
virtual void appendFromThread (int tid, const T &val)
 Appends val to the buffer in a thread safe way, using the given tid to access TLS storage. Can grow the buffer if needed.
 
virtual size_t size () const
 Returns the number of entries in the buffer. Must be called from the main thread only.
 
virtual T * data ()
 Returns a vector filled with the buffer data. After this call, NO calls to append() can be made without a prior call to clear().
 
virtual size_t usedMemory () const
 Returns an estimative of the total memory used by the buffer in bytes.
 
- Public Member Functions inherited from GmAppendBuffer< T >
virtual ~GmAppendBuffer ()
 Virtual destructor.
 

Protected Member Functions

void clearList ()
 

Protected Attributes

ControllData_head
 Pointer to the first allocated buffer.
 
double _resizeFactor
 The resize factor.
 
QAtomicInteger< size_t > _nextIndex
 The next free index in the global vector.
 
QAtomicPointer< ControllData_controll
 The controll block pointing to the current buffer.
 
GmSpinLock _controllLock
 The lock controlling changes to _controll.
 
T * _dataBuffer
 The single buffer after a call to data()
 
int _nt
 Number of threads considered for parallel memcopy.
 

Detailed Description

template<class T, class Base = GmAppendBuffer<T>>
class GmSingleAppendBuffer< T, Base >

An implementation of the GmAppendBuffer interface based on synchoronized access to a shared buffer.

This class uses atomic opertions to provide an efficient way for multiple threads to append data to a shared vector. When there is need for growing the vector, additional buffers are created (instead of growing the original one).

The initial buffer size needs to be informed either in the constructor or by a call to reserve(). The quality of this initial guess can impact in the overall efficiency of the buffer object. See below.

Calling data() will either return the internal vector if the size given in the buffer initialization was enough to hold all the added data or will allocate a new vector and fill it with the buffer data from the several internal buffers.

Buffer growing is controlled by a factor parameter given in the constructor. Considering that the current buffer size at the moment of growing is S and the growing factor is f (f > 1), the new buffer size will be equal to (S * f). The default growing factor is 2.0, but it can be changed for sometihing smaller, like 1.1, if the confidence on the initial size is high.

This class can be more efficient than the GmPerThreadAppendBuffer option when the initial buffer size guess is good (no need to grow the pre-allocated vector) AND the memory usage is close to its limit. In this scenario, the synchronisation price is payed by the possibility of returning the original vector in data(), without the need of allocating more memory in an already low (physical) memory environment.

OBS: This class inherits from a template parameter Base, defaulted to GmAppendBuffer, in order to make it easy for changing the base class to another one that inherits GmAppendBuffer adding additional methods, as is done in the GmSparseMatrixTripletBuffer class.

Constructor & Destructor Documentation

◆ GmSingleAppendBuffer()

template<class T , class Base = GmAppendBuffer<T>>
GmSingleAppendBuffer< T, Base >::GmSingleAppendBuffer ( size_t initSize,
double resizeFactor = 2.0,
int numThreads = -1 )
inline

Buffer constructor. Can optionally pre allocate the buffer with initSize entries. If initSize is zero, a call to reserve() MUST be made before any append. The given resizeFactor controlls how the buffer grows in case of a resize. See the class comments for additional info.

The number of threads defaults to the maximum number of threads as seen by the thread manager (when numThreads is -1). It only affects the number of threads used by parallel memcpy operations

Member Function Documentation

◆ append()

template<class T , class Base = GmAppendBuffer<T>>
virtual void GmSingleAppendBuffer< T, Base >::append ( const T & val)
inlinevirtual

Appends val to the buffer in a thread safe way. Can grow the buffer if needed.

Implements GmAppendBuffer< T >.

◆ appendFromThread()

template<class T , class Base = GmAppendBuffer<T>>
virtual void GmSingleAppendBuffer< T, Base >::appendFromThread ( int tid,
const T & val )
inlinevirtual

Appends val to the buffer in a thread safe way, using the given tid to access TLS storage. Can grow the buffer if needed.

Implements GmAppendBuffer< T >.

◆ clear()

template<class T , class Base = GmAppendBuffer<T>>
virtual void GmSingleAppendBuffer< T, Base >::clear ( )
inlinevirtual

Releases the memory used by the buffer, returning it to a recently constructed state. Must be followed by a call to reserve() before the object is able to do any further appends. Must be called from the main thread only.

Implements GmAppendBuffer< T >.

◆ data()

template<class T , class Base = GmAppendBuffer<T>>
virtual T * GmSingleAppendBuffer< T, Base >::data ( )
inlinevirtual

Returns a vector filled with the buffer data. After this call, NO calls to append() can be made without a prior call to clear().

If the buffer has internally only one vector, that vector will be returned. Otherwise, a new vector will be created, the buffer data copied to the new vector and the old buffers released. Either way, the returned buffer is valid until the append buffer is destroyed or until a call to clear().

Must be called from the main thread only.

Returns NULL if the vector could not be created. In that case, leaves the original buffers untouched.

Implements GmAppendBuffer< T >.

◆ reserve()

template<class T , class Base = GmAppendBuffer<T>>
virtual void GmSingleAppendBuffer< T, Base >::reserve ( size_t bsize)
inlinevirtual

See comments on the base class. Should not be called if the size was given in the constructor.

Implements GmAppendBuffer< T >.

◆ size()

template<class T , class Base = GmAppendBuffer<T>>
virtual size_t GmSingleAppendBuffer< T, Base >::size ( ) const
inlinevirtual

Returns the number of entries in the buffer. Must be called from the main thread only.

Implements GmAppendBuffer< T >.

◆ usedMemory()

template<class T , class Base = GmAppendBuffer<T>>
virtual size_t GmSingleAppendBuffer< T, Base >::usedMemory ( ) const
inlinevirtual

Returns an estimative of the total memory used by the buffer in bytes.

Implements GmAppendBuffer< T >.


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