00001 /* 00002 A ring buffer for the Storage Manager Event Server 00003 Serialized events are stored (EventMsgView). The size of the 00004 buffer can be given in the constructor but the max size 00005 of each event is hardwired to 7MB (actually 7000000). 00006 This is used by the Storage Manager FragmentCollector. 00007 When the ring buffer is full it the oldest event gets 00008 overwritten. 00009 00010 31 Jul 2006 - KAB - First implementation. 00011 */ 00012 #include "EventFilter/StorageManager/interface/EvtMsgRingBuffer.h" 00013 00014 #include "FWCore/Utilities/interface/DebugMacros.h" 00015 00016 #include <iostream> 00017 00018 using namespace stor; 00019 using namespace edm; 00020 using namespace std; 00021 00022 EvtMsgRingBuffer::EvtMsgRingBuffer(unsigned int size): 00023 maxsize_(size), head_(0), tail_(0), nextfree_(0), 00024 ring_buffer_(maxsize_), ring_totmsgsize_(maxsize_) 00025 { 00026 for (int i=0; i<(int)maxsize_; i++) 00027 ring_buffer_[i].reserve(MAX_EVTBUF_SIZE); 00028 } 00029 00030 EventMsgView EvtMsgRingBuffer::pop_front() 00031 { 00032 // check to see if empty - what to return? 00033 // calling code needs to check ifEmpty() and do appropriate thing 00034 // should really return a message an appropriate MsgCode 00035 if(isEmpty()) return EventMsgView(&ring_buffer_[head_][0]); 00036 00037 EventMsgView popthis(&ring_buffer_[head_][0]); 00038 if(head_ == (int)maxsize_-1) head_ = 0; 00039 else head_++; 00040 // see if now empty and need to move the tail 00041 if(head_ == nextfree_) tail_ = head_; 00042 FDEBUG(10) << "after pop_front head = " << head_ << " tail = " << tail_ 00043 << " next free = " << nextfree_ << endl; 00044 FDEBUG(10) << "popping event = " << popthis.event() << endl; 00045 FDEBUG(10) << "pop_front msg event size " << popthis.eventLength() << std::endl; 00046 return popthis; 00047 } 00048 00049 void EvtMsgRingBuffer::push_back(EventMsgView inputMsgView) 00050 { 00051 // see if full and need to move the head 00052 if(isFull()) { 00053 if(head_ == (int)maxsize_-1) head_ = 0; 00054 else head_++; 00055 } 00056 00057 // 31-Jul-2006, KAB: I expect that the correct way to copy an 00058 // event message is create an EventMsgBuilder using data fetched from 00059 // the input message. However, there currently doesn't seem to be 00060 // sufficient methods in EventMsgView to support this. So, for now, 00061 // we just copy the data directly (ugly hack). 00062 unsigned char* pos = (unsigned char*) &ring_buffer_[nextfree_][0]; 00063 unsigned char* from = (unsigned char*) 00064 ((unsigned int) inputMsgView.eventData() - inputMsgView.headerSize()); 00065 int dsize = inputMsgView.eventLength() + inputMsgView.headerSize(); 00066 copy(from,from+dsize,pos); 00067 ring_totmsgsize_[nextfree_]=dsize; 00068 00069 tail_ = nextfree_; 00070 if(tail_ == (int)maxsize_-1) nextfree_ = 0; 00071 else nextfree_++; 00072 FDEBUG(10) << "after push_back head = " << head_ << " tail = " << tail_ 00073 << " next free = " << nextfree_ << endl; 00074 } 00075 00076 bool EvtMsgRingBuffer::isEmpty() 00077 { 00078 return ((head_ == tail_) && (head_ == nextfree_)); 00079 } 00080 00081 bool EvtMsgRingBuffer::isFull() 00082 { 00083 return ((head_ != tail_) && (head_ == nextfree_)); 00084 }