]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTOUT.cxx
Changes needed for new HLT output DDLs.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.cxx
CommitLineData
62bb3cd4 1// $Id$
2
0f1882a7 3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
62bb3cd4 18
4c4b4801 19/// @file AliHLTOUT.cxx
20/// @author Matthias Richter
21/// @date
22/// @brief The control class for HLTOUT data.
23///
62bb3cd4 24
4de7334f 25#include <cerrno>
5db0e774 26#include <cassert>
62bb3cd4 27#include "AliHLTOUT.h"
e5701dcf 28#include "AliHLTMessage.h"
466d4e62 29#include "AliHLTMisc.h"
c1292031 30#include "TSystem.h"
31#include "TClass.h"
32#include "TROOT.h"
4c4b4801 33#include <sstream>
34#include <iomanip>
35using namespace std;
62bb3cd4 36
37/** ROOT macro for the implementation of ROOT specific class methods */
38ClassImp(AliHLTOUT)
39
40AliHLTOUT::AliHLTOUT()
4de7334f 41 :
42 fSearchDataType(kAliHLTVoidDataType),
43 fSearchSpecification(kAliHLTVoidDataSpec),
44dc7683 44 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
0f1882a7 45 fFlags(kSkipProcessed),
4de7334f 46 fBlockDescList(),
0f1882a7 47 fCurrent(0),
5db0e774 48 fpBuffer(NULL),
44dc7683 49 fDataHandlers(),
4c4b4801 50 fbVerbose(false),
b005ef92 51 fLog()
e5701dcf 52 , fpDataObject(NULL)
53 , fpObjectBuffer(NULL)
54 , fObjectBufferSize(0)
c63e8be4 55 , fCurrentEventId(kAliHLTVoidEventID)
4de7334f 56{
62bb3cd4 57 // see header file for class documentation
58 // or
59 // refer to README to build package
60 // or
61 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62}
63
64AliHLTOUT::~AliHLTOUT()
4de7334f 65{
66 // see header file for class documentation
0f1882a7 67 if (CheckStatusFlag(kIsSubCollection)) {
b005ef92 68 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "~AliHLTOUT" , __FILE__ , __LINE__ , "severe internal error: collection has not been released, potential crash due to invalid pointer");
0f1882a7 69 }
e5701dcf 70
71 if (fpDataObject) {
72 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
73 }
74 fpDataObject=NULL;
4de7334f 75}
b005ef92 76AliHLTOUT* AliHLTOUT::fgGlobalInstance=NULL;
4de7334f 77
5db0e774 78int AliHLTOUT::Init()
79{
80 // see header file for class documentation
81 int iResult=0;
f3c1d403 82
83 // ignore if already initialized
84 if (fBlockDescList.size()>0) {
f3c1d403 85 return 0;
86 }
87
18b56222 88 SetStatusFlag(kCollecting);
5db0e774 89 if ((iResult=GenerateIndex())>=0) {
90 if ((iResult=InitHandlers())>=0) {
91 }
92 }
18b56222 93 ClearStatusFlag(kCollecting);
5db0e774 94 return iResult;
95}
96
4de7334f 97int AliHLTOUT::GetNofDataBlocks()
98{
99 // see header file for class documentation
100 return fBlockDescList.size();
101}
102
5db0e774 103int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
0f1882a7 104 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType,
105 bool skipProcessed)
4de7334f 106{
107 // see header file for class documentation
0f1882a7 108 fCurrent=0;
4de7334f 109 fSearchDataType=dt;
110 fSearchSpecification=spec;
44dc7683 111 fSearchHandlerType=handlerType;
0f1882a7 112 if (skipProcessed) SetStatusFlag(kSkipProcessed);
113 else ClearStatusFlag(kSkipProcessed);
049b43b2 114 return FindAndSelectDataBlock();
4de7334f 115}
116
117int AliHLTOUT::SelectNextDataBlock()
118{
119 // see header file for class documentation
0f1882a7 120 if (fCurrent>=fBlockDescList.size()) return -ENOENT;
049b43b2 121 fCurrent++;
122 return FindAndSelectDataBlock();
123}
124
125int AliHLTOUT::FindAndSelectDataBlock()
126{
127 // see header file for class documentation
128 if (CheckStatusFlag(kLocked)) return -EPERM;
4de7334f 129 int iResult=-ENOENT;
0f1882a7 130 while (fCurrent<fBlockDescList.size() && iResult==-ENOENT) {
131 if (fBlockDescList[fCurrent]==fSearchDataType &&
132 (fSearchSpecification==kAliHLTVoidDataSpec || fBlockDescList[fCurrent]==fSearchSpecification) &&
512302d3 133 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent)==fSearchHandlerType) &&
0f1882a7 134 (!CheckStatusFlag(kBlockSelection) || fBlockDescList[fCurrent].IsSelected()) &&
135 (!CheckStatusFlag(kSkipProcessed) || !fBlockDescList[fCurrent].IsProcessed())) {
136 iResult=fBlockDescList[fCurrent].GetIndex();
049b43b2 137 // TODO: check the byte order on the current system and the byte order of the
c5123824 138 // data block, print warning when mismatch and user did not check
13398559 139 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
06f53caf 140 CheckByteOrder();
049b43b2 141 /*
142 if (blockBO!=fByteOrder) {
143 SetStatusFlag(kByteOrderWarning);
144
145 }
146 */
147 ClearStatusFlag(kByteOrderChecked);
148
149 // TODO: check the alignment on the current system and the alignment of the
c5123824 150 // data block, print warning when mismatch and user did not check
049b43b2 151 ClearStatusFlag(kAlignmentChecked);
18b56222 152
153 break;
4de7334f 154 }
049b43b2 155 fCurrent++;
4de7334f 156 }
157 return iResult;
158}
159
160int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
161{
162 // see header file for class documentation
163 int iResult=-ENOENT;
0f1882a7 164 if (fCurrent<fBlockDescList.size()) {
4de7334f 165 iResult=0;
0f1882a7 166 dt=fBlockDescList[fCurrent];
167 spec=fBlockDescList[fCurrent];
4de7334f 168 }
169 return iResult;
170}
171
c5123824 172const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
173{
174 // see header file for class documentation
512302d3 175 return FindHandlerDesc(fCurrent);
c5123824 176}
177
178AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
179{
180 // see header file for class documentation
512302d3 181 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(fCurrent);
c5123824 182 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
183 return type;
184}
185
5db0e774 186AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
187{
188 // see header file for class documentation
0f1882a7 189 if (fCurrent>=fBlockDescList.size()) return AliHLTOUTInvalidIndex;
190 return fBlockDescList[fCurrent].GetIndex();
5db0e774 191}
192
4de7334f 193int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
194{
195 // see header file for class documentation
196 int iResult=-ENOENT;
197 pBuffer=NULL;
198 size=0;
0f1882a7 199 if (fCurrent<fBlockDescList.size()) {
200 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(pBuffer, size))>=0) {
4de7334f 201 fpBuffer=pBuffer;
202 }
203 }
204 return iResult;
205}
206
207int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
208{
209 // see header file for class documentation
210 int iResult=0;
211 if (pBuffer==fpBuffer) {
212 fpBuffer=NULL;
213 } else {
b005ef92 214 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "ReleaseDataBuffer" , __FILE__ , __LINE__ , "buffer %p does not match the provided one %p", pBuffer, fpBuffer);
4de7334f 215 }
216 return iResult;
217}
218
c5123824 219AliHLTModuleAgent* AliHLTOUT::GetAgent()
220{
221 // see header file for class documentation
222 AliHLTModuleAgent* pAgent=NULL;
512302d3 223 pAgent=FindHandlerDesc(fCurrent);
c5123824 224 return pAgent;
225}
226
626bfcc1 227AliHLTOUTHandler* AliHLTOUT::GetHandler()
228{
229 // see header file for class documentation
230 AliHLTOUTHandler* pHandler=NULL;
512302d3 231 pHandler=FindHandlerDesc(fCurrent);
626bfcc1 232 return pHandler;
233}
234
c5123824 235int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
236{
237 // see header file for class documentation
b005ef92 238 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "WriteESD" , __FILE__ , __LINE__ , "method not implemented in base class");
c5123824 239 return -ENOSYS;
240}
241
4de7334f 242int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
243{
62bb3cd4 244 // see header file for class documentation
049b43b2 245 if (!CheckStatusFlag(kCollecting)) return -EPERM;
4de7334f 246 int iResult=0;
247 fBlockDescList.push_back(desc);
248 return iResult;
62bb3cd4 249}
049b43b2 250
13398559 251AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
049b43b2 252{
5db0e774 253 // see header file for class documentation
0f1882a7 254 if (fCurrent<fBlockDescList.size()) {
049b43b2 255 SetStatusFlag(kByteOrderChecked);
0f1882a7 256 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder(fBlockDescList[fCurrent].GetIndex());
049b43b2 257 return order;
258 }
259 return kInvalidByteOrder;
260}
261
13398559 262int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
049b43b2 263{
5db0e774 264 // see header file for class documentation
0f1882a7 265 if (fCurrent<fBlockDescList.size()) {
049b43b2 266 SetStatusFlag(kAlignmentChecked);
0f1882a7 267 int alignment=CheckBlockAlignment(fBlockDescList[fCurrent].GetIndex(), type);
049b43b2 268 return alignment;
269 }
270 return -ENOENT;
271}
5db0e774 272
273int AliHLTOUT::InitHandlers()
274{
275 // see header file for class documentation
276 int iResult=0;
277 AliHLTOUTIndexList remnants;
44dc7683 278 int iCount=0;
a3ef3c1d 279 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
44dc7683 280 iCount++;
5db0e774 281 remnants.push_back(GetDataBlockIndex());
282 AliHLTComponentDataType dt=kAliHLTVoidDataType;
283 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
e94eb049 284 if (GetDataBlockDescription(dt, spec)<0) break;
f94e8c27 285 bool bHaveHandler=false;
5db0e774 286 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
287 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
626bfcc1 288 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
5db0e774 289 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
c5123824 290 InsertHandler(fDataHandlers, entry);
5db0e774 291 remnants.pop_back();
f94e8c27 292 bHaveHandler=true;
4c4b4801 293 if (fbVerbose) {
294 stringstream sout;
295 sout << "adding handler for block " << AliHLTComponent::DataType2Text(dt).c_str()
296 << " 0x" << setfill('0') << setw(8) << hex << spec;
297 cout << sout.str() << endl;
298 }
5db0e774 299 break;
300 }
301 }
f94e8c27 302 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
303 // ESDs are handled by the framework
304 remnants.pop_back();
305 }
5db0e774 306 }
44dc7683 307
308 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
309 // criterion
310 if (GetNofDataBlocks()>iCount) {
b005ef92 311 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, GetNofDataBlocks());
44dc7683 312 }
313
314 // warning if handler not found
5db0e774 315 if (remnants.size()>0) {
b005ef92 316 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "no handlers found for %d data blocks out of %d", remnants.size(), iCount);
13398559 317 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
8decd484 318 for (AliHLTOUTIndexList::iterator element=remnants.begin();
319 element!=remnants.end() && block!=fBlockDescList.end();
320 element++) {
5db0e774 321 for (int trials=0; trials<2; trials++) {
322 do {
323 // we start searching the index from the current position in the block list
324 if ((*block).GetIndex()==*element) break;
325 } while ((++block)!=fBlockDescList.end());
326 if (block==fBlockDescList.end()) {
327 // rewind and try again
328 block=fBlockDescList.begin();
329 }
330 }
331 assert(block!=fBlockDescList.end());
5db0e774 332 }
333 }
4c4b4801 334
335 if (fbVerbose) Print();
336
5db0e774 337 return iResult;
338}
339
c5123824 340int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
5db0e774 341{
342 // see header file for class documentation
343 int iResult=0;
c5123824 344 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
b005ef92 345 for (; element!=list.end();
346 element++) {
5db0e774 347 if (entry==(*element)) break;
5db0e774 348 }
c5123824 349 if (element==list.end()) {
350 list.push_back(entry);
5db0e774 351 } else {
a3ef3c1d 352 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
5db0e774 353 }
354 return iResult;
355}
356
b005ef92 357int AliHLTOUT::FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
358{
359 // see header file for class documentation
360 int iResult=0;
361 for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, handlerType);
362 iResult>=0;
363 iResult=SelectNextDataBlock()) {
364 AliHLTComponentDataType dt=kAliHLTVoidDataType;
365 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
366 GetDataBlockDescription(dt, spec);
367 AliHLTOUTHandler* pHandler=GetHandler();
368 if (!pHandler) {
369 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "FillHandlerList" , __FILE__ , __LINE__ ,
370 "missing HLTOUT handler for block of type kChain: agent %s, data type %s, specification %#x, ... skipping data block",
371 GetAgent()?GetAgent()->GetModuleId():"invalid",
372 AliHLTComponent::DataType2Text(dt).c_str(), spec);
373 } else {
374 InsertHandler(list, GetDataBlockHandlerDesc());
375 }
376 }
377 // TODO: the return value of SelectFirst/NextDataBlock must be
378 // changed in order to avoid this check
379 if (iResult==-ENOENT) iResult=0;
380
381 return iResult;
382}
383
384int AliHLTOUT::RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list)
385{
386 // see header file for class documentation
387 int iResult=0;
388 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
389 while (element!=list.end()) {
390 if (element->IsEmpty()) {
391 AliHLTOUTHandler* pHandler=*element;
392 AliHLTModuleAgent* pAgent=*element;
393 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*element;
394 if (FindHandler(list, desc)>=0) {
395 element=list.erase(element);
396 if (pAgent) {
397 pAgent->DeleteOutputHandler(pHandler);
398 }
399 // we are already at the next element
400 continue;
401 }
402 }
403 element++;
404 }
405 return iResult;
406}
407
408int AliHLTOUT::FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc)
409{
410 // see header file for class documentation
411 for (int i=0; i<(int)list.size(); i++) {
412 if (list[i]==desc) return i;
413 }
414 return -ENOENT;
415}
416
417int AliHLTOUT::InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list)
418{
419 // see header file for class documentation
420 for (AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
421 element!=list.end();
422 element++) {
423 element->InvalidateBlocks();
424 }
425 return 0;
426}
427
44dc7683 428const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
626bfcc1 429{
430 // see header file for class documentation
f3c1d403 431 if (blockIndex<fBlockDescList.size()) {
432 return fBlockDescList[blockIndex].GetHandlerDesc();
626bfcc1 433 }
44dc7683 434 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
626bfcc1 435}
436
437AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
438 :
439 fpHandler(NULL),
440 fpHandlerDesc(NULL),
441 fpAgent(NULL),
442 fBlocks()
443{
444 // see header file for class documentation
445}
446
5db0e774 447AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
448 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
449 AliHLTModuleAgent* pAgent,
450 AliHLTUInt32_t index)
451 :
452 fpHandler(pHandler),
626bfcc1 453 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 454 fpAgent(pAgent),
455 fBlocks()
456{
457 // see header file for class documentation
626bfcc1 458 *fpHandlerDesc=handlerDesc;
5db0e774 459 fBlocks.push_back(index);
460}
461
462AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
463 :
464 fpHandler(src.fpHandler),
626bfcc1 465 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 466 fpAgent(src.fpAgent),
467 fBlocks()
468{
469 // see header file for class documentation
626bfcc1 470 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 471 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
472}
473
fb24bec7 474AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
475{
476 // see header file for class documentation
626bfcc1 477 if (fpHandlerDesc) delete fpHandlerDesc;
478 fpHandlerDesc=NULL;
fb24bec7 479}
480
5db0e774 481AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
482{
483 // see header file for class documentation
484 fpHandler=src.fpHandler;
44dc7683 485 if (src.fpHandlerDesc)
486 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 487 fpAgent=src.fpAgent;
488 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
489 return *this;
490}
491
18b56222 492AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
493{
494 // see header file for class documentation
b0914d2e 495 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
5db0e774 496}
497
fb24bec7 498bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
499{
18b56222 500 // see header file for class documentation
a3ef3c1d 501 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
502 assert(entry.fpAgent==fpAgent);
503 if (entry.fpAgent!=fpAgent) return false;
504 return true;
505}
506
44dc7683 507bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
508{
509 // see header file for class documentation
510 if (!fpHandlerDesc) return false;
511 return *fpHandlerDesc==handlerType;
512}
513
b005ef92 514bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const
515{
516 // see header file for class documentation
517 if (!fpHandlerDesc) return false;
518 return *fpHandlerDesc==desc;
519}
520
a3ef3c1d 521void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
522{
523 // see header file for class documentation
524 AliHLTOUTIndexList::iterator element;
525 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
526 AddIndex(*element);
527 }
fb24bec7 528}
529
18b56222 530void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
531{
532 // see header file for class documentation
5db0e774 533 fBlocks.push_back(index);
534}
626bfcc1 535
0f1882a7 536bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index) const
200853e2 537{
538 // see header file for class documentation
a3ef3c1d 539 AliHLTOUTIndexList::iterator element;
0f1882a7 540 for (unsigned int i=0; i<fBlocks.size(); i++) {
541 if (fBlocks[i]==index) return true;
a3ef3c1d 542 }
200853e2 543 return false;
544}
545
626bfcc1 546const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
44dc7683 547
ff3b6fed 548AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
44dc7683 549{
550 // see header file for class documentation
551 return ((src & 0xFFULL) << 56) |
552 ((src & 0xFF00ULL) << 40) |
553 ((src & 0xFF0000ULL) << 24) |
554 ((src & 0xFF000000ULL) << 8) |
555 ((src & 0xFF00000000ULL) >> 8) |
556 ((src & 0xFF0000000000ULL) >> 24) |
557 ((src & 0xFF000000000000ULL) >> 40) |
558 ((src & 0xFF00000000000000ULL) >> 56);
559}
560
ff3b6fed 561AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
44dc7683 562{
563 // see header file for class documentation
564 return ((src & 0xFFULL) << 24) |
565 ((src & 0xFF00ULL) << 8) |
566 ((src & 0xFF0000ULL) >> 8) |
567 ((src & 0xFF000000ULL) >> 24);
568}
c1292031 569
570AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
571{
572 // see header file for class documentation
466d4e62 573 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTRawReader", "libHLTrec.so");
c1292031 574 if (instance) {
575 instance->SetParam(pRawReader);
576 }
577 return instance;
578}
579
580AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
581{
582 // see header file for class documentation
466d4e62 583 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
c1292031 584 if (instance) {
585 instance->SetParam(pDigitTree, event);
586 }
587 return instance;
588}
589
466d4e62 590AliHLTOUT* AliHLTOUT::New(const char* filename, int event)
591{
592 // see header file for class documentation
593 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
594 if (instance) {
595 instance->SetParam(filename, event);
c1292031 596 }
597 return instance;
598}
599
600void AliHLTOUT::Delete(AliHLTOUT* pInstance)
601{
602 // see header file for class documentation
603 if (!pInstance) return;
b005ef92 604 if (pInstance==fgGlobalInstance) return;
c1292031 605
606 // check if the library is still there in order to have the
607 // destructor available
608 TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
609 TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
610 if (!pCl1 && !pCl2) {
611 AliHLTLogging log;
612 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
613 return;
614 }
615
616 delete pInstance;
617}
618
619void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
620{
621 // see header file for class documentation
622 // default implementation, we should never get here
623 // this function can only be called from the class itsself and
624 // is intended to be used with the New functions. If we get into
625 // the default implementation there is a class mismatch.
626 assert(0);
b005ef92 627 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 628}
629
630void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
631{
632 // see header file for class documentation
633 // default implementation, we should never get here
634 // this function can only be called from the class itsself and
635 // is intended to be used with the New functions. If we get into
636 // the default implementation there is a class mismatch.
637 assert(0);
b005ef92 638 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 639}
0f1882a7 640
466d4e62 641void AliHLTOUT::SetParam(const char* /*filename*/, int /*event*/)
642{
643 // see header file for class documentation
644 // default implementation, we should never get here
645 // this function can only be called from the class itsself and
646 // is intended to be used with the New functions. If we get into
647 // the default implementation there is a class mismatch.
648 assert(0);
649 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
650}
651
0f1882a7 652int AliHLTOUT::SelectDataBlock()
653{
654 // see header file for class documentation
655 int iResult=0;
656 if (fCurrent>=fBlockDescList.size()) return 0;
657 fBlockDescList[fCurrent].Select(true);
658 EnableBlockSelection();
659 return iResult;
660}
661
e13512e4 662int AliHLTOUT::SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerEntry)
0f1882a7 663{
664 // see header file for class documentation
665 int iResult=0;
e13512e4 666 if (!pHandlerEntry) return 0;
0f1882a7 667
e13512e4 668 AliHLTModuleAgent* pAgent=*pHandlerEntry;
669 AliHLTLogging log;
670 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", "selecting blocks for handler %s", pAgent->GetModuleId());
0f1882a7 671 AliHLTOUTBlockDescriptorVector::iterator element;
672 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
673 block!=fBlockDescList.end();
674 block++) {
e13512e4 675 if (block->GetHandlerDesc()==*pHandlerEntry && pHandlerEntry->HasIndex(block->GetIndex())) {
0f1882a7 676 block->Select(true);
e13512e4 677 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " select block %s", AliHLTComponent::DataType2Text(*block).c_str());
678 } else {
679 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " skip block %s", AliHLTComponent::DataType2Text(*block).c_str());
0f1882a7 680 block->Select(false);
e13512e4 681 }
0f1882a7 682 }
683 EnableBlockSelection();
e13512e4 684
685 // Matthias 2009-07-03 bugfix: the fCurrent position was not reset at that
686 // place. Also I think the data type and specification must be set in order
687 // to make SelectFirst/NextDataBlock working on the selected collection
688 // of data blocks
689 AliHLTModuleAgent::AliHLTOUTHandlerDesc pHandlerDesc=*pHandlerEntry;
690 fSearchDataType=pHandlerDesc;
691 fSearchSpecification=kAliHLTVoidDataSpec;
692 fSearchHandlerType=pHandlerDesc;
693 fCurrent=0;
0f1882a7 694
695 return iResult;
696}
697
698int AliHLTOUT::EnableBlockSelection()
699{
700 // see header file for class documentation
701 SetStatusFlag(kBlockSelection);
702 return 0;
703}
704
705int AliHLTOUT::DisableBlockSelection()
706{
707 // see header file for class documentation
708 ClearStatusFlag(kBlockSelection);
709 return 0;
710}
711
712int AliHLTOUT::ResetBlockSelection()
713{
714 // see header file for class documentation
715 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
716 block!=fBlockDescList.end();
717 block++) {
718 block->Select(false);
719 }
720 return 0;
721}
722
723int AliHLTOUT::MarkDataBlockProcessed()
724{
725 // see header file for class documentation
726 int iResult=0;
727 if (fCurrent>=fBlockDescList.size()) return 0;
728 fBlockDescList[fCurrent].MarkProcessed();
729 return iResult;
730}
731
732int AliHLTOUT::MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc)
733{
734 // see header file for class documentation
735 int iResult=0;
736 if (!pHandlerDesc) return 0;
737
738 AliHLTOUTBlockDescriptorVector::iterator element;
739 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
740 block!=fBlockDescList.end();
741 block++) {
f3c1d403 742 if (block->GetHandlerDesc()==*pHandlerDesc && pHandlerDesc->HasIndex(block->GetIndex()))
0f1882a7 743 block->MarkProcessed();
744 }
745
746 return iResult;
747}
748
749int AliHLTOUT::AddSubCollection(AliHLTOUT* pCollection)
750{
751 // see header file for class documentation
752 int iResult=0;
753 if (!pCollection) return 0;
754
d4a18597 755 SetStatusFlag(kCollecting);
0f1882a7 756 int index=-1;
757 for (index=pCollection->SelectFirstDataBlock();
758 index>=0;
759 index=pCollection->SelectNextDataBlock()) {
760 AliHLTComponentDataType dt=kAliHLTVoidDataType;
761 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
762 pCollection->GetDataBlockDescription(dt, spec);
763 AliHLTOUTBlockDescriptor desc(dt, spec, index, pCollection);
764 AddBlockDescriptor(desc);
765 iResult++;
766 }
767 if (iResult>0) {
4562bf66 768 if (CheckStatusFlag(kIsSubCollection)) {
769 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "AddSubCollection" , __FILE__ , __LINE__ , "HLTOUT object %p has already been added as sub-collection", pCollection);
770 } else {
771 pCollection->SetStatusFlag(kIsSubCollection);
772 }
0f1882a7 773 }
d4a18597 774 ClearStatusFlag(kCollecting);
0f1882a7 775
776 return iResult;
777}
778
779int AliHLTOUT::ReleaseSubCollection(AliHLTOUT* pCollection)
780{
781 // see header file for class documentation
782 int iResult=0;
783 if (!pCollection) return 0;
784
b005ef92 785 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
786 while (block!=fBlockDescList.end()) {
0f1882a7 787 if ((*block)==pCollection) {
b005ef92 788 block=fBlockDescList.erase(block);
789 continue;
0f1882a7 790 }
b005ef92 791 block++;
0f1882a7 792 }
4562bf66 793 pCollection->ClearStatusFlag(kIsSubCollection);
0f1882a7 794
795 return iResult;
796}
b005ef92 797
798int AliHLTOUT::Reset()
799{
800 // see header file for class documentation
801 int iResult=0;
802 AliHLTOUTPVector subCollections;
803 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
804 while (block!=fBlockDescList.end()) {
d4a18597 805 if (!((*block)==this)) {
b005ef92 806 AliHLTOUTPVector::iterator collection=subCollections.begin();
807 for (; collection!=subCollections.end(); collection++)
808 if((*block)==*collection) break;
809 if (collection==subCollections.end())
810 subCollections.push_back(block->GetCollection());
811 }
812 block=fBlockDescList.erase(block);
813 }
814
815 for (AliHLTOUTPVector::iterator collection=subCollections.begin();
4562bf66 816 collection!=subCollections.end(); collection++) {
b005ef92 817 (*collection)->Reset();
4562bf66 818 (*collection)->ClearStatusFlag(kIsSubCollection);
819 }
b005ef92 820
821 ResetInput();
c63e8be4 822 fCurrentEventId=kAliHLTVoidEventID;
b005ef92 823
824 return iResult;
825}
826
827int AliHLTOUT::ResetInput()
828{
829 // default implementation, nothing to do
830 return 0;
831}
f3c1d403 832
833const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTBlockDescriptor::GetHandlerDesc()
834{
835 // see header file for class documentation
836 if (fpCollection) {
837 AliHLTOUTHandlerListEntryVector::iterator element=fpCollection->fDataHandlers.begin();
838 while (element!=fpCollection->fDataHandlers.end()) {
839 if (element->HasIndex(GetIndex())) {
840 return *element;
841 }
842 element++;
843 }
844 }
845 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
846}
e5701dcf 847
848TObject* AliHLTOUT::GetDataObject()
849{
850 // see header file for class documentation
851 if (fpDataObject) {
852 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
853 ReleaseDataBuffer(fpObjectBuffer);
854 }
855 fpObjectBuffer=NULL;
856 fObjectBufferSize=0;
857 fpDataObject=NULL;
858
859 if (GetDataBuffer(fpObjectBuffer, fObjectBufferSize)>=0) {
860 fpDataObject=AliHLTMessage::Extract(fpObjectBuffer, fObjectBufferSize);
861 } else {
862 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "can not fetch data buffer");
863 }
864
865 return fpDataObject;
866}
867
868int AliHLTOUT::ReleaseDataObject(TObject* pObject)
869{
870 // see header file for class documentation
871 if (!pObject) return -EINVAL;
872 if (pObject!=fpDataObject) {
873 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "attempt to release wrong data object %p, expected %p", pObject, fpDataObject);
874 return -EINVAL;
875 }
876
877 delete fpDataObject;
878 fpDataObject=NULL;
879 ReleaseDataBuffer(fpObjectBuffer);
880 fpObjectBuffer=NULL;
881 fObjectBufferSize=0;
882
883 return 0;
884}
c63e8be4 885
886void AliHLTOUT::SetEventId(AliHLTUInt64_t id)
887{
888 // see header file for class documentation
889 if (fCurrentEventId!=kAliHLTVoidEventID && fCurrentEventId!=id) {
890 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "SetEventId" , __FILE__ , __LINE__ , "event id was already set to 0x%llx, setting now to 0x%llx", fCurrentEventId, id);
891 }
892 fCurrentEventId=id;
893}
4c4b4801 894
895void AliHLTOUT::Print(const char* option) const
896{
897 // print info
898 {
899 for (AliHLTOUTBlockDescriptorVector::const_iterator i=fBlockDescList.begin();
900 i!=fBlockDescList.end(); i++)
901 i->Print(option);
902 }
903 {
904 for (AliHLTOUTHandlerListEntryVector::const_iterator i=fDataHandlers.begin();
905 i!=fDataHandlers.end(); i++)
906 i->Print(option);
907 }
908}
909
910void AliHLTOUT::AliHLTOUTBlockDescriptor::Print(const char* /*option*/) const
911{
912 // print info
913 stringstream sout;
914 sout << "AliHLTOUTBlockDescriptor index 0x" << setfill('0') << setw(8) << hex << right << fIndex
915 << ": " << AliHLTComponent::DataType2Text(fDataType).c_str()
916 << " 0x" << setfill('0') << setw(8) << hex << fSpecification
917 << " processed " << dec << fProcessed;
918 cout << sout.str() << endl;
919}
920
921void AliHLTOUT::AliHLTOUTHandlerListEntry::Print(const char* /*option*/) const
922{
923 // print info
924 stringstream sout;
925 AliHLTModuleAgent::AliHLTOUTHandlerType type=AliHLTModuleAgent::kUnknownOutput;
926 AliHLTComponentDataType dt=kAliHLTVoidDataType;
927 if (this->fpHandlerDesc) {
928 type=*(this->fpHandlerDesc);
929 dt=*(this->fpHandlerDesc);
930 }
931 const char* stype="";
932 switch(type) {
933 case AliHLTModuleAgent::kEsd: stype="ESD"; break;
934 case AliHLTModuleAgent::kRawReader: stype="RawReader"; break;
935 case AliHLTModuleAgent::kRawStream: stype="RawStream"; break;
936 case AliHLTModuleAgent::kChain: stype="Chain"; break;
937 case AliHLTModuleAgent::kProprietary: stype="Proprietary"; break;
938 default: stype="unknown";
939 }
940 sout << "HLTOUT handler: "
941 << " " << type << " (" << stype << ")"
942 << " " << AliHLTComponent::DataType2Text(dt).c_str();
943 cout << sout.str() << endl;
944}