Create only one instance of the buffer thread
[u/mrichter/AliRoot.git] / EVE / EveHLT / AliEveEventBuffer.cxx
1 #include <iostream>
2
3 #include "TObjArray.h"
4 #include "TTimer.h"
5 #include "TThread.h"
6 #include "AliEveEventBuffer.h"
7
8
9 //Not needed, only for debug
10 #include "AliESDEvent.h"
11
12 using namespace std;
13
14 ClassImp(AliEveEventBuffer)
15
16 ///_______________________________________________________________________
17 AliEveEventBuffer::AliEveEventBuffer() :
18   fBufferSize(10),
19   fPreBuffer(4),
20   fBusy(kFALSE),
21   fEventBuffer(NULL),
22   fCurrentEvent(NULL),
23   fBIndex(),
24   fTimer(NULL),
25   fEventId(),
26   fBufferMonStarted(kFALSE),
27   fThread(NULL)
28  {
29   // see header file for class documentation
30   fEventBuffer = new TObjArray(fBufferSize, 0);
31   fEventBuffer->SetOwner(kFALSE);
32   
33   for(int id = 0; id < kSize; id++) {
34     fBIndex[id] = -1;
35   }
36   
37   fTimer = new TTimer();
38   fTimer->Connect("Timeout()", "AliEveEventBuffer", this, "CreateBufferThread()");
39
40   fEventId = new ULong64_t[fBufferSize];
41   for(Int_t id = 0; id < fBufferSize; id++ ) {
42     fEventId[id] = -2;
43   }
44
45   fThread = new TThread(AliEveEventBuffer::BufferThread, (void*) this);
46
47   
48
49 }
50
51
52
53 ///_______________________________________________________________________
54 AliEveEventBuffer::~AliEveEventBuffer() {
55   // see header file for class documentation
56   
57   if ( fEventBuffer ) {
58     fEventBuffer->Clear();
59     delete fEventBuffer;
60   }
61   fEventBuffer = NULL;
62
63   if(fCurrentEvent)
64     delete fCurrentEvent;
65   fCurrentEvent = NULL;
66
67 }
68
69 ///___________________________________________________________________________
70 void AliEveEventBuffer::CreateBufferThread() {
71   cout << "Threadexists: " << fThread->Exists() << endl;
72   if(GetBusy()) {
73     cout << "Buffer is busy, no thread created"<< endl;
74     
75   } else {
76     if ( (CalculateDifference(fBIndex[kTop],fBIndex[kLast]) < fPreBuffer) ) {
77       SetBusy(kTRUE);
78       cout << "StartBufferThread()"<<endl;
79       fThread->Run();
80       cout << "Started BufferThread"<<endl;
81     } else { 
82       cout << "Buffer is full already"<<endl;
83     }
84   }
85 }
86
87 ///___________________________________________________________________________
88 void * AliEveEventBuffer::BufferThread(void * buffer) {
89   cout <<"BufferThread : " <<endl;
90   if(buffer) {
91       reinterpret_cast<AliEveEventBuffer*>(buffer)->MonitorBuffer();
92   } else {
93     cout << "no buffer"<<endl;
94   }
95   return (void*)0;
96 }
97
98 ///_____________________________________________________________________________
99 void AliEveEventBuffer::MonitorBuffer() {
100   cout << "Monitorbuffer() ";
101   SetBusy(kTRUE);
102   FetchEvent();
103   SetBusy(kFALSE);
104   cout << "done " << endl;
105 }
106
107
108 ///_______________________________________________________________________________
109 TObject * AliEveEventBuffer::NextEvent() {
110   //See header file for documentation
111   cout << "NextEvent()"<<endl;
112   TObject * nextEvent = GetNextUnSeen();
113   return nextEvent;
114 }
115
116 ///______________________________________________________________________________
117 TObject * AliEveEventBuffer::Back() {
118   cout << "go back"<<endl;
119   PrintIndeces();
120   Int_t prevId = CalculatePrevious(fBIndex[kCurrent]);
121   if(prevId == fBIndex[kTop]) {
122     cout << "returning NULL" << endl;
123     return NULL;
124   } else {
125     fBIndex[kCurrent] = prevId;
126     PrintIndeces();
127     cout <<"returning: "<< fBIndex[kCurrent] << " " << fEventBuffer->At(fBIndex[kCurrent]);
128     return fEventBuffer->At(fBIndex[kCurrent]);
129   }
130 }
131
132
133
134 ///______________________________________________________________________________
135 TObject * AliEveEventBuffer::Fwd() {
136   PrintIndeces();
137   if (fBIndex[kCurrent] == fBIndex[kLast]) {
138     cout<<  "returning NULL"<<endl;
139     return NULL;
140   }
141   
142   fBIndex[kCurrent] = CalculateNext(fBIndex[kCurrent]);
143   TObject * event = fEventBuffer->At(fBIndex[kCurrent]);
144   return event;
145 }
146
147
148
149 ///________________________________________________________________________________
150 TObject * AliEveEventBuffer::GetNextUnSeen() {
151   //See header file for documentation
152   cout << "GetNextUnSeen"<<endl;
153   PrintIndeces();
154   if(CalculateDifference(fBIndex[kTop], fBIndex[kLast])) {
155     fBIndex[kLast] = CalculateNext(fBIndex[kLast]);
156     fBIndex[kCurrent] = fBIndex[kLast];
157     PrintIndeces();
158     return fEventBuffer->At(fBIndex[kCurrent]);      
159   } else {
160     cout << "No new event available, only events in buffer available!"<<endl;
161     return NULL;
162   } 
163 }
164 ///_________________________________________________________________________________
165 void AliEveEventBuffer::PrintIndeces() {
166   for(Int_t i = 0; i < kSize; i++) {
167     cout << i << ": " << fBIndex[i] << endl;
168   }
169 }
170 ///_________________________________________________________________________________
171 void AliEveEventBuffer::PrintBuffer() {
172   for(Int_t i = 0; i < 10; i++) {
173     AliESDEvent * event = dynamic_cast<AliESDEvent*>(fEventBuffer->At(i));
174     if(event) {
175       cout << i << ": " <<event << " " << event->GetEventNumberInFile() << endl;;
176     }
177   }
178 }
179
180 ///____________________________________________________________________________________
181 void AliEveEventBuffer::FetchEvent() {
182   cout << "FetchEvent " << endl;
183   TObject * event = GetEventFromSource();
184   ULong64_t eventId = GetEventIdFromSource();
185   if(event) {
186     AddToBuffer(event);
187     fEventId[fBIndex[kTop]] = eventId;  
188   }
189   
190   PrintIndeces();
191   cout << "FetchedEvent " << endl;
192   
193 }
194
195 ///_________________________________________________________________________________
196 void AliEveEventBuffer::AddToBuffer(TObject * event) {
197   cout << "Add to buffer"<<endl;
198   if(!event) return;
199
200   fBIndex[kTop] = CalculateNext(fBIndex[kTop]);
201   //Delete the event already there (ok to delete as object, not aliesdevent, TList?)
202   //TObject * object = fEventBuffer->At(fBIndex[kTop]);
203   fEventBuffer->RemoveAt(fBIndex[kTop]);
204   //if (object) delete object;
205   fEventBuffer->AddAt(event, fBIndex[kTop]);
206
207 }
208
209 ///_____________________________________________________________________________________
210 Int_t AliEveEventBuffer::CalculateNext(Int_t current) {
211   //See header file for documentation
212   current++;
213   if(current == fBufferSize) current = 0;
214   return current;
215 }
216
217
218 ///_____________________________________________________________________________________
219 Int_t AliEveEventBuffer::CalculatePrevious(Int_t current) {
220   //See header file for documentation
221   cout << "CalculatePrev:  " << current; 
222   current--;
223   if(current == -1) current += fBufferSize;
224   cout << "... " << current << endl;
225   return current;
226 }
227
228 ///__________________________________________________________________________________
229 Int_t AliEveEventBuffer::CalculateDifference(Int_t top, Int_t low) {
230   //See header file for documentation
231   if (top > low) {
232     //    cout << "top > low"<<endl;
233     return (top - low);
234   } else if (top < low) {
235     // cout << "low < top"<<endl;
236     return (fBufferSize - low + top);
237   } else {
238     //cout << "calculated to 0"<<endl;
239     return 0;
240   }
241 }
242
243 ///___________________________________________________________________________________
244 void AliEveEventBuffer::StartBufferMonitor() {
245   //cout << "NOT !!! starting buffer mon"<<endl;
246   cout << "starting buffer mon"<<endl;
247   if(!GetBufferMonStarted()) {
248     CreateBufferThread();
249     SetBufferMonStarted(kTRUE);
250     fTimer->Start(3000);
251   } else {
252     cout << "Stopping buffer monitor"<<endl;
253     fTimer->Stop();
254     SetBufferMonStarted(kFALSE);
255   }
256 }
257 ///___________________________________________________________________________________
258 void AliEveEventBuffer::StopBufferMonitor() {
259   cout << "Stopping buffer mon"<<endl;
260   SetBufferMonStarted(kFALSE);
261   fTimer->Stop();
262 }
263
264
265 // //_________________________________________________________________________________
266 // Int_t AliEveEventBuffer::NavigateEventBufferBack() { 
267 //   // see header file for class documentation
268
269 //   // -- reached the end of the buffer
270 //   if ( fNavigateBufferIdx == fBufferLowIdx )
271 //     return -1;
272
273 //   Int_t newIdx = fNavigateBufferIdx - 1;
274 //   if ( newIdx == -1 )
275 //     newIdx = BUFFERSIZE-1;
276
277 //   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
278
279 //   return newIdx;
280 // }
281
282 // //_______________________________________________________________
283 // Int_t AliEveEventBuffer::NavigateEventBufferFwd() {
284 //   // see header file for class documentation
285
286 //   // -- reached the top of the buffer
287 //   if ( fNavigateBufferIdx == fBufferTopIdx )
288 //     return -1;
289
290 //   Int_t newIdx = fNavigateBufferIdx + 1;
291 //   if ( newIdx == BUFFERSIZE )
292 //     newIdx = 0;
293   
294 //   fCurrentBufferIdx = fNavigateBufferIdx = newIdx;
295
296 //   return newIdx;
297 // }
298
299 // void AliEveEventBuffer::MonitorBuffer() {
300 //   //See header file for documentation
301 //   if( GetNAvailableEvents() < 10) {
302 //     StopBufferChecker();
303 //     StartLoop();
304 //   }
305 // }
306
307 // void AliEveEventBuffer::StartLoop() {
308 //   //See header file for documentation
309 //   fTimer->Start(2000);
310 // }
311 // void AliEveEventBuffer::StopLoop() {
312 //   //See header file for documentation
313 //   fTimer->Stop();
314 // }
315
316 // void AliEveEventBuffer::StartBufferChecker() {
317 //   //See header file for documentation
318 //   fBufferTimer->Start(2000);
319 // }
320 // void AliEveEventBuffer::StopBufferChecker() {
321 //   //See header file for documentation
322 //   fBufferTimer->Stop();
323 // }
324
325 // AliESDEvent * GetNextEvent() {
326   
327 //   tree->GetEntry(fEvent++);
328
329 //   AliESDEvent * event = new AliESDEvent();
330 //   event->ReadFromTree(fTree);
331 //   if (event) {
332 //     return event;
333 //   } else {
334 //     cout << "error getting event" << endl;
335 //     return NULL;
336 //   }
337 // }