00001 #ifndef _ots_CircularBuffer_h_
00002 #define _ots_CircularBuffer_h_
00003
00004 #include "otsdaq-core/DataManager/CircularBufferBase.h"
00005 #include "otsdaq-core/DataManager/BufferImplementation.h"
00006
00007 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00008 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00009
00010 #include <iostream>
00011 #include <string>
00012 #include <map>
00013 #include <atomic>
00014
00015 namespace ots
00016 {
00017 template <class D, class H>
00018 class CircularBuffer : public CircularBufferBase
00019 {
00020 public:
00021 CircularBuffer (void);
00022 virtual ~CircularBuffer(void);
00023
00024 void reset (void);
00025 void resetConsumerList (void);
00026 bool isEmpty (void);
00027 unsigned int getNumberOfBuffers(void);
00028
00029 inline int read (D& buffer, const std::string& consumerID)
00030 {
00031 H dummyHeader;
00032 return read(buffer, dummyHeader, consumerID);
00033 }
00034
00035 inline int read (D& buffer, H& header, const std::string& consumerID)
00036 {
00037 setNextProducerBuffer(consumerID);
00038 unsigned int readCounter = theBuffer_.size()-1;
00039 ++megaCounter_;
00040 if(megaCounter_%10000000 == 0)
00041 std::cout << __COUT_HDR_FL__ << __COUT_HDR_FL__
00042 << "Consumer: " << consumerID
00043 << " Reading producer: " << lastReadBuffer_[consumerID]->first
00044 << " Buffer empty? " << lastReadBuffer_[consumerID]->second.isEmpty()
00045 << " written buffers: " << lastReadBuffer_[consumerID]->second.numberOfWrittenBuffers()
00046 << std::endl;
00047 int readReturnVal;
00048 while((readReturnVal = lastReadBuffer_[consumerID]->second.read(buffer, header, consumerID)) < 0 && readCounter > 0)
00049 {
00050 setNextProducerBuffer(consumerID);
00051 --readCounter;
00052 }
00053 return readReturnVal;
00054 }
00055
00056 int read(D*& buffer, H*& header, const std::string& consumerID)
00057 {
00058 setNextProducerBuffer(consumerID);
00059 unsigned int readCounter = theBuffer_.size()-1;
00060 ++megaCounter_;
00061 if(megaCounter_%10000000 == 0)
00062 std::cout << __COUT_HDR_FL__ << __COUT_HDR_FL__
00063 << "Consumer: " << consumerID
00064 << " Reading producer: " << lastReadBuffer_[consumerID]->first
00065 << " Buffer empty? " << lastReadBuffer_[consumerID]->second.isEmpty()
00066 << " written buffers: " << lastReadBuffer_[consumerID]->second.numberOfWrittenBuffers()
00067 << std::endl;
00068 int readReturnVal;
00069 while((readReturnVal = lastReadBuffer_[consumerID]->second.read(buffer, header, consumerID)) < 0 && readCounter > 0)
00070 {
00071 setNextProducerBuffer(consumerID);
00072 --readCounter;
00073 }
00074 return readReturnVal;
00075 }
00076
00077 BufferImplementation<D,H>& getLastReadBuffer(std::string consumerID){return lastReadBuffer_[consumerID]->second;}
00078 BufferImplementation<D,H>& getBuffer (std::string producerID){return theBuffer_[producerID];}
00079
00080 private:
00081 std::map<std::string, BufferImplementation<D,H>> theBuffer_;
00082
00083 void registerProducer (std::string producerID, unsigned int numberOfSubBuffers=100);
00084 void registerConsumer (std::string consumerID, CircularBufferBase::ConsumerPriority priority);
00085 void unregisterConsumer (std::string consumerID);
00086 void setNextProducerBuffer(const std::string& consumer);
00087
00088 std::map<std::string, typename std::map<std::string, BufferImplementation<D,H>>::iterator> lastReadBuffer_;
00089
00090 unsigned long long megaCounter_;
00091 };
00092 #include "otsdaq-core/DataManager/CircularBuffer.icc"
00093
00094 }
00095 #endif
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108