otsdaq  v1_01_03
 All Classes Namespaces Functions
CircularBuffer.h
1 #ifndef _ots_CircularBuffer_h_
2 #define _ots_CircularBuffer_h_
3 
4 #include "otsdaq-core/DataManager/CircularBufferBase.h"
5 #include "otsdaq-core/DataManager/BufferImplementation.h"
6 
7 #include "otsdaq-core/MessageFacility/MessageFacility.h"
8 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
9 
10 #include <iostream>
11 #include <string>
12 #include <map>
13 #include <atomic>
14 
15 namespace ots
16 {
17 template <class D, class H>
19 {
20 public:
21  CircularBuffer (void);
22  virtual ~CircularBuffer(void);
23 
24  void reset (void);//This DOES NOT reset the consumer list
25  void resetConsumerList (void);
26  bool isEmpty (void);
27  unsigned int getNumberOfBuffers(void);
28 
29  inline int read (D& buffer, const std::string& consumerID)
30  {
31  H dummyHeader;
32  return read(buffer, dummyHeader, consumerID);
33  }
34 
35  inline int read (D& buffer, H& header, const std::string& consumerID)
36  {
37  setNextProducerBuffer(consumerID);
38  unsigned int readCounter = theBuffer_.size()-1;
39  ++megaCounter_;
40  if(megaCounter_%10000000 == 0)
41  std::cout << __COUT_HDR_FL__ << __COUT_HDR_FL__
42  << "Consumer: " << consumerID
43  << " Reading producer: " << lastReadBuffer_[consumerID]->first
44  << " Buffer empty? " << lastReadBuffer_[consumerID]->second.isEmpty()
45  << " written buffers: " << lastReadBuffer_[consumerID]->second.numberOfWrittenBuffers()
46  << std::endl;
47  int readReturnVal;
48  while((readReturnVal = lastReadBuffer_[consumerID]->second.read(buffer, header, consumerID)) < 0 && readCounter > 0)
49  {
50  setNextProducerBuffer(consumerID);
51  --readCounter;
52  }
53  return readReturnVal;
54  }
55 
56  int read(D*& buffer, H*& header, const std::string& consumerID)
57  {
58  setNextProducerBuffer(consumerID);
59  unsigned int readCounter = theBuffer_.size()-1;
60  ++megaCounter_;
61  if(megaCounter_%10000000 == 0)
62  std::cout << __COUT_HDR_FL__ << __COUT_HDR_FL__
63  << "Consumer: " << consumerID
64  << " Reading producer: " << lastReadBuffer_[consumerID]->first
65  << " Buffer empty? " << lastReadBuffer_[consumerID]->second.isEmpty()
66  << " written buffers: " << lastReadBuffer_[consumerID]->second.numberOfWrittenBuffers()
67  << std::endl;
68  int readReturnVal;
69  while((readReturnVal = lastReadBuffer_[consumerID]->second.read(buffer, header, consumerID)) < 0 && readCounter > 0)
70  {
71  setNextProducerBuffer(consumerID);
72  --readCounter;
73  }
74  return readReturnVal;
75  }
76 
77  BufferImplementation<D,H>& getLastReadBuffer(std::string consumerID){return lastReadBuffer_[consumerID]->second;}
78  BufferImplementation<D,H>& getBuffer (std::string producerID){return theBuffer_[producerID];}
79 
80 private:
81  std::map<std::string, BufferImplementation<D,H>> theBuffer_;
82 
83  void registerProducer (std::string producerID, unsigned int numberOfSubBuffers=100);
84  void registerConsumer (std::string consumerID, CircularBufferBase::ConsumerPriority priority);
85  void unregisterConsumer (std::string consumerID);
86  void setNextProducerBuffer(const std::string& consumer);
87  //The first element is a CONSUMER, then it is the producer buffer map!!!!!
88  std::map<std::string, typename std::map<std::string, BufferImplementation<D,H>>::iterator> lastReadBuffer_;
89 
90  unsigned long long megaCounter_;
91 };
92 #include "otsdaq-core/DataManager/CircularBuffer.icc"
93 
94 }
95 #endif
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108