#include <CRingItem.h>
CRingITem
CRingItem(uint16_t type, size_t maxBody = 8192);
CRingItem(uint16_t type, uint64_t timestamp, uint32_t sourceId, uint32_t barrierType = 0, size_t maxBody = 8192);
CRingItem(const CRingItem& rhs);
virtual ~CRingItem();
CRingItem& operator=(const CRingItem& rhs);
const int operator==(const CRingItem& rhs);
const int operator!=(const CRingItem& rhs);
const size_t getStorageSize();
const size_t getBodySize();
void* getBodyPointer();
void* getBodyCursor();
_RingItem* getItemPointer();
const uint32_t type();
void setBodyCursor(void* pNewCursor);
void commitToRing(CRingBuffer& ring);
const bool mustSwap();
const bool hasBodyHeader();
const uint64_t getEventTimestamp() throws std::string;
const uint32_t getSourceId() throws std::string;
const uint32_t getBarrierType() throws std::string;
void setBodyHeader(uint64_t timestamp, uint32_t sourceId, uint32_t barrierType = 0);
virtual const std::string typeName() ();
virtual const std::string toString() ();
static CRingItem* getFromRing(CRingBuffer& ring, CRingSelectionPredicate& predicate);
CRingItem
is the base class of a hierarchy
of classes that encapsulate the format of items put in ring buffers
by the NSCL DAQ readout frameworks.
The class hierarchy as a whole is intended both to help application
writers format item to be submitted to a ring buffer and to
fetch and decode items from a ring buffer. The fetch logic works
closely with the set of classes derived from
CRingSelectionPredicate
to support selective reception of data inserted by a producer program.
CRingItem(uint16_t type, size_t maxBody = 8192);
Constructs a Ring Item. type
initializes the
type field of the item, and maximum size of the body is
set to be maxBody
.
The size of the actual ring buffer item placed in a ring
via commitToRing
is computed from the
position of the body cursor as set by the
last invocation of setBodyCursor
.
In order to reduce the amount of dynamic memory management required
for ring buffer items, a static buffer of size
CRingItemStaticBufferSize
is carried by
all objects. Only if the maximum size is requested to be larger than
that is a dynamically allocated body produced by the constructor
and deleted by the destructor.
CRingItem(uint16_t type, uint64_t timestamp, uint32_t sourceId, uint32_t barrierType = 0, size_t maxBody = 8192);
Constructs a ring item with a full body header. The
timestamp
, sourceId
and barriereType
parameters set the corresponding
fields in the body header. The default barrierType
of 0 indicates a non-barrier item.
CRingItem(const CRingItem& rhs);
Constructs a ring item by creating a functional copy of
rhs
(copy construction).
CRingItem& operator=(const CRingItem& rhs);
Makes the current object (on the left hand side of an assignment statement)
a functional equivalent of rhs
.
const int operator==(const CRingItem& rhs);
Compares the object on the left hand side of an ==
to rhs
for functional equivalence.
If the two objects reasonably represent the same ring item, returns
nonzero, else returns zero.
const int operator!=(const CRingItem& rhs);
Computes the logical inverse of operator==
const size_t getStorageSize();
Returns the total size available for the ring item, header and body together.
const size_t getBodySize();
Returns the amount of data in the body of the ring.
void* getBodyPointer();
Returns a pointer to the start of the body. Note that this returns a pointer to the body payload, that is the first byte after the Body Header if one is present or the byte after the zero indicating there is no body header if one is not.
void* getBodyCursor();
Returns the last stored body cursor. This is intended to allow you
(along with setBodyCursor
) to keep track of
where you should next add information to a ring item.
_RingItem* getItemPointer();
Returns a pointer to the items storage. This should be a RingItemHeader followed by whatever has been put in the body.
const uint32_t type();
Returns the type of the item encapsulated by the object. This member does account for byte order mismatches in the event the generating system had a different byte order than the system running the object.
void setBodyCursor(void* pNewCursor);
Items have a bodyCursor. This is intended
to allow software that is building up an item to keep track of
the next free hunk of memory in the item. The cusor can be
fetched via getBodyCursor
and stored
back via setBodyCursor
which sets the
body cursor to pNewCursor
This is intended as a performance compromise that enables data such as physics events to insert data into items with no penalty other than a pointer dereference. The body cursor is also used to compute the size of an item when it is requested, and when or if it is committed to a ring buffer.
void commitToRing(CRingBuffer& ring);
Inserts the item that is encapsulated by the object into the
ring buffer represented by the object ring
.
At this time, the body cursor must point to the first unused
byte following the body, as it is used to calculate the size field
of the item.
This call may block indefinitely if space is not available in the ring.
const bool mustSwap();
Returns true if the byte order of the object is the opposite of the
running system. Two assumptions are used to derive this result.
First, that all ring items that are formatted in the local host
will have local host byte ordering and therefore should return
false
for mustSwap
.
Second, that the top 16 bits of the data type are always zero
and that this can be used to determine the byte ordering of an item.
const bool hasBodyHeader();
Returns true if the ring item has a body header. Returns false if not. Note that the condition for returning true is that the length of the body header is non zero.
const uint64_t getEventTimestamp()
throws std::string;
Returns the value of the timestamp from the items' body header. If
hasBodyHeader
would return false
a string exception containing an explanatory error message is
thrown as an exception.
const uint32_t getSourceId()
throws std::string;
Returns the source id from the item's body header.
If
hasBodyHeader
would return false
a string exception containing an explanatory error message is
thrown as an exception.
const uint32_t getBarrierType()
throws std::string;
Returns the barrier type of the item.
If
hasBodyHeader
would return false
a string exception containing an explanatory error message is
thrown as an exception.
void setBodyHeader(uint64_t timestamp, uint32_t sourceId, uint32_t barrierType = 0);
If the item does not yet have a BodyHeader the body contents are
moved to make room and the timestramp
sourceId
and barrierType
parameters are used to fill in the corresponding fields of the
Body Header. If the item already has a body header, the parameters
replace the contents of the body header in place.
Naturally if you have an event item witha potentially large body,
it is more efficient to construct it with a body header, even with
nonsensical values and then invoke setBodyHeader
than it is to construct the item without a body header, fill it in
and then invoke setBodyHeader
.
virtual const std::string typeName() ();
This virtual method is intended to be overriden in subclasses
to provide a textual name of the item type. This method along
with toString
below are intended to provide
support for creating human readable dumps of ring items. If not
overriden, the method will produce string like:
Unknown (hex-type)
where hex-type is the hexadecimal value
of the item type code in the ring item header.
virtual const std::string toString() ();
This virtual method is inteded to be overridden in the subclasses to provide a human readable string representation of the item. If not overridden, the body header formatted and the body payload is simply dumped as hexadecimal bytes.
Note | |
---|---|
The protected method |
static CRingItem* getFromRing(CRingBuffer& ring, CRingSelectionPredicate& predicate);
Returns a pointer to a dynamically allocated ring item that was
fetched from the ring buffer ring
.
The item must satisfy the selection criteria defined by
predicate
.
If you want all items, simply pass in an un-reconfigured
CAllButPredicate
object.
Predicates provide a powerful mechanism for selecting and sampling
data from ring buffers. For more information about them,
see the chapter
Ring Format
which provides background information about ring buffer predicates.
For reference information, see the reference pages for:
CRingSelectionPredicate
,
CAllButPredicate
,
and
CDesiredTypesPredicate
.
Note that you may also construct your own predicate classes should
these not be sufficient to meet your needs.
The caller is responsible for deleting the object.
While not explicitly referenced in the public interfaces
of
CRingItem
, if you use this class directly,
you should be familiar with the data types defined in the header
DataFormat.h. These are described fully in
the chapter:
Ring Format.
The code fragment below shows how to sample the next physics buffer
from a ring which is represented by the object ring
Example 1. Selecting sampled event from a ring.
#include <DataFormat.h> ... CDesiredTypesPredicate sampledEventsOnly; sampledEventsOnly.addDesiredType(PHYSICS_EVENT, true); CRingItem* item = CRingItem::getFromRing(ring, sampledEventsOnly); // work with the item... // Done with the item. delete item;
CDesiredTypesPredicate
which
selects only the types we tell it to in the mode requested.