📄 circularbuffer.h
字号:
#ifndef CIRCULARBUFFER_H#define CIRCULARBUFFER_H#include "CircularBufferResidentObject.h"#include "EmptyEventListener.h"#include "ReadThresholdEventSource.h"#include "WriteThresholdEventSource.h"
#include "Utils/CompoundObject.h"#include "Misc/ObjectPool.h"#include "Misc/Notifier.h"#include <utility>namespace oxsemi{ namespace circular_buffer { /** * Although provision is made for acquiring more than one buffer for * read by each reader and more than one buffer for write by the writer, * the user must ensure that the buffers are released in the order in * which they were acquired (independently for each reader and the * writer). Furthermore, if multiple buffers are acquired for write, it * will not be possible alter the size of the buffer associated with the * object when it is released */ class CircularBuffer :
public CompoundObject, public Notifier<EmptyEventListener>, public ReadThresholdEventSource<unsigned long>, public WriteThresholdEventSource<unsigned long> { public: virtual ~CircularBuffer() = 0; /** * Construct an object from the next available in the circular buffer for * the specified reader * * @param readerNumber An unsigned specifying the reader number * @param previousObject A CircularBufferResidentObject* which if * non-null indicates that the acquired object should be the one * after the pointed-to object in the circular buffer. If non-null, * previousObject must point to an object that has previously been * acquired from the circular buffer, via a call to this method * @param blockIfUnsufficientSpace A bool which if true requests * that this call should block until there is an object available * @param sizeHint An unsigned long giving a hint as to the 'size', * whatever that means for the particular type of object in the * circular buffer, of the object required * @return A std::pair<bool, CircularBufferResidentObject*> whose * first element will be true if a fatal error occured and whose * second element, a CircularBufferResidentObject*, will be non- * null if the an object was successfully decoded from this circular * buffer */ virtual std::pair<bool, CircularBufferResidentObject*> AcquireForRead( unsigned readerNumber, CircularBufferResidentObject* previousObject, bool blockIfNoObjectsAvailable, unsigned long sizeHint) = 0; /** * @param object A const CircularBufferResidentObject& referring to * the object describing the space required in this circular buffer * and containing any data required in addition to the bulk data to * later be stored in this circular buffer * @param previousObject A CircularBufferResidentObject* which if * non-null indicates that the acquired object should be allocated * space in the circular buffer after the pointed-to object. If non- * null, previousObject must point to an object that has previously * been allocated space in the circular buffer, via a call to this * method * @param blockIfUnsufficientSpace A bool which if true requests that * this call should block until there is sufficient space within * this circular buffer to accomodate the specified * circularBufferResidentObject. * @return A bool which will be true there was sufficient space in * this circular buffer in which to encode the object */ virtual bool AcquireForWrite( CircularBufferResidentObject& object, CircularBufferResidentObject* previousObject, bool blockIfInsufficientSpace) = 0; /** * Conceptually advance the read pointer for all readers to the * position of the write pointer * * @return A bool which if true means that the read pointer was * advanced */ virtual bool FlushAvailableForRead() = 0; /** * Conceptually advance the read pointer for the specified reader to * the position of the write pointer * * @param readerNumber An unsigned specifying the number of the * reader whose read pointer is to be advanced * @return A bool which if true means that the read pointer was * advanced */ virtual bool FlushAvailableForRead(unsigned readerNumber) = 0; /** * Wake any threads suspended awaiting buffers and disallow any further * blocking. Would generally be called prior to destruction to unblock * any user threads before the buffer manager is pulled out from * under them */ virtual void ForceUnblockAll() = 0; /** * @param readerNumber An unsigned specifying the reader number * @return An unsigned giving the number of objects available for * read by the specified reader */ virtual unsigned long GetNumberOfObjects(unsigned readerNumber) const = 0; /** * @return An unsigned giving the number of readers of this buffer */ virtual unsigned GetNumberOfReaders() const = 0; /** * @param readerNumber An unsigned specifying the reader number * @return A pair<bool, unsigned long> whose first element is true * if a read limmit is currently applied to the specified reader * and if so the second element gives the read limit */ virtual std::pair<bool, unsigned long> GetReadLimit(unsigned readerNumber) = 0; /** * @return An unsigned long giving the size of the larger of the two * sections of available write space */ virtual unsigned long GetSpaceAvailableForWrite() const = 0; /** * @param readerNumber An unsigned specifying the number of the * reader whose read pointer is to be advanced * @return A bool which will be true if there are no objects avail- * able for reading */ virtual bool IsEmpty(unsigned readerNumber) const = 0; /** * @param readerNumber An unsigned specifying the number of the * reader whose read pointer is to be advanced * @return An unsigned int - the number of bytes used in the * circular buffer. */ virtual unsigned int BytesUsed(unsigned int readerNumber) const = 0; /** * Invoked to provide the information necessary for this circular buffer to * be able to decode objects from its internal buffer and dispose of them * when no longer required. * A class may be de-registered by specifying the classId parameter, but * passing null for both the allocate and free parameters * * @param id A CircularBufferResidentObject::Id& which will filled with the * with which to denote objects of the registered class when encoded in * this circular buffer * @param pool An ObjectPool& referring to an object which can allocate and * free instances of the CircularBufferResidentObject class identified by * the passed CircularBufferResidentObject::Id * @return A bool which if true means that the class was successfully reg- * istered with this circular buffer */ virtual bool RegisterResidentClass( CircularBufferResidentObject::Id& id, ObjectPool& pool) = 0; /** * Indicate that the specified object and the circular buffer space associ- * ated with it are no longer required by the specified reader. Conceptually * advances the read position for the specified reader to after the in-buffer * representation of the passed object * * @param readerNumber An unsigned specifying the reader number * @param object A CircularBufferResidentObject* pointing to the * object to be released * @param pending A bool which if true indicates the the passed object * is finished with, but that the circular buffer resident object * should not be released, so that it will be available to a later * call to AcquireForRead() */ virtual void ReleaseFromRead( unsigned readerNumber, CircularBufferResidentObject* object, bool pending) = 0; /** * Make the passed object within the circular buffer available to readers * Conceptually advances the write pointer, to make the object's representa- * tion within this circular buffer available to the readers * * @param object A const CircularBufferResidentObject& referring to * the object whose circular buffer resident image is to be stored * within this circular buffer and made available to the readers * @param discard A bool which if true indicates that the released object * should not be made available to readers, but the associated buffer space * made immediately available to the writer */ virtual void ReleaseFromWrite( const CircularBufferResidentObject& object, bool discard) = 0; /** * Make the passed objects within the circular buffer available to * readers Conceptually advances the write pointer, to make the * objects' representations within this circular buffer available to * the readers * * @param buffers An const Vector<CircularBufferResidentObject*>& * pointing to a collection of buffers to be released * @param discard A bool which if true indicates that the released * objects should not be made available to readers, but the asso- * ciated buffer space made immediately available to the writer */ virtual void ReleaseFromWrite( const Vector<CircularBufferResidentObject*>& buffers, bool discard) = 0; /** * @return A bool which if true means that this buffer manager is in * the process of shutting down */ virtual bool ShuttingDown() = 0; /** * @param readersCanBlock A bool which if false will prevent readers * from blocking on acquiring buffers for read and will unblock any * readers currently blocked. If true readers are allowed to block on * acquiring buffers */ virtual void SetReaderBlockState(bool readersCanBlock) = 0; /** * @param readerNumber An unsigned specifying the reader number * @param limit An unsigned long specifying how many objects the * specified reader may read from the circular buffer before being * blocked until another limit is set or if FlushAvailableForRead() * is called. If the limit is zero, it removes any limit */ virtual void SetReadLimit( unsigned readerNumber, unsigned long limit) = 0; /** * Trimming should only be attempted on the most recently acquired * for write object * * @param object CircularBufferResidentObject& which should refer to * the object most recently acquired for write from this circular * buffer. Adjustments will be made such that a subsequent object * acquired for write will be given space within the circular buffer * which abutts this trimmed object's trimmed extent * @param previousObject A CircularBufferResidentObject* which if * non-null indicates that the object to be trimmed is situated in * the circular buffer after the pointed-to object. If non-null, * previousObject must point to an object that has previously been * allocated space in the circular buffer. * @param A bool which if false means the trim failed, most likely * due to an attempt to trim an object which is not the most recently * acquired for write */ virtual bool TrimMostRecentlyAcquiredObjectForWrite( CircularBufferResidentObject& object, CircularBufferResidentObject* previousObject) = 0; protected: static const unsigned char ALIGNMENT_POWER_OF_2 = 2; static const CircularBufferResidentObject::Id MOVE_TO_START_ID = 0; static const CircularBufferResidentObject::Id JUMP_ZERO_ID = 1; static const CircularBufferResidentObject::Id JUMP_ID = 2; static const unsigned MAX_SPECIAL_IDS = 3; CircularBuffer( unsigned maxEmptyEventListeners, unsigned maxReadThresholdEventListeners, unsigned maxWriteThresholdEventListeners); static const CircularBufferPosition& GetAfterPosition(const CircularBufferResidentObject& object); static ObjectPool* GetPool(const CircularBufferResidentObject& object); static void SetAfterPosition( CircularBufferResidentObject& object, const CircularBufferPosition& circularBufferPosition); static void SetPool( CircularBufferResidentObject& object, ObjectPool* pool); static CircularBufferResidentObject::EncodeResult TrimBufferUsage(CircularBufferResidentObject& object); private: CircularBuffer(const CircularBuffer&); CircularBuffer& operator=(const CircularBuffer&); }; }}#endif // #if !defined(__CIRCULARBUFFER_H__)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -