3 //**************************************************************************
4 //* This file is property of and copyright by the *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTOUT.cxx
20 /// @author Matthias Richter
22 /// @brief The control class for HLTOUT data.
27 #include "AliHLTOUT.h"
28 #include "AliHLTMessage.h"
29 #include "AliHLTMisc.h"
38 /** ROOT macro for the implementation of ROOT specific class methods */
41 AliHLTOUT::AliHLTOUT()
43 fSearchDataType(kAliHLTVoidDataType),
44 fSearchSpecification(kAliHLTVoidDataSpec),
45 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
46 fFlags(kSkipProcessed),
54 , fpObjectBuffer(NULL)
55 , fObjectBufferSize(0)
56 , fCurrentEventId(kAliHLTVoidEventID)
60 // The control class for HLTOUT data
61 // see header file for class documentation
62 // author Matthias Richter
65 AliHLTOUT::~AliHLTOUT()
68 if (CheckStatusFlag(kIsSubCollection)) {
69 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "~AliHLTOUT" , __FILE__ , __LINE__ , "severe internal error: collection has not been released, potential crash due to invalid pointer");
73 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
77 AliHLTOUT* AliHLTOUT::fgGlobalInstance=NULL;
81 // see header file for class documentation
84 // ignore if already initialized
85 if (fBlockDescList.size()>0) {
89 SetStatusFlag(kCollecting);
90 if ((iResult=GenerateIndex())>=0) {
91 if ((iResult=InitHandlers())>=0) {
94 ClearStatusFlag(kCollecting);
98 int AliHLTOUT::GetNofDataBlocks()
100 // get number of data blocks
101 return fBlockDescList.size();
104 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
105 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType,
108 // select the first data block according to data type, specification and
112 fSearchSpecification=spec;
113 fSearchHandlerType=handlerType;
114 if (skipProcessed) SetStatusFlag(kSkipProcessed);
115 else ClearStatusFlag(kSkipProcessed);
116 return FindAndSelectDataBlock();
119 int AliHLTOUT::SelectNextDataBlock()
121 // select next data block according to selection criteria specified
122 // for SelectFirstDataBlock
123 if (fCurrent>=fBlockDescList.size()) return -ENOENT;
125 return FindAndSelectDataBlock();
128 int AliHLTOUT::FindAndSelectDataBlock()
130 // Select data block according to data type and specification, internal function
131 // invoked by SelectFirstDataBlock/SelectNextDataBlock
132 if (CheckStatusFlag(kLocked)) return -EPERM;
134 while (fCurrent<fBlockDescList.size() && iResult==-ENOENT) {
135 if (fBlockDescList[fCurrent]==fSearchDataType &&
136 (fSearchSpecification==kAliHLTVoidDataSpec || fBlockDescList[fCurrent]==fSearchSpecification) &&
137 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent)==fSearchHandlerType) &&
138 (!CheckStatusFlag(kBlockSelection) || fBlockDescList[fCurrent].IsSelected()) &&
139 (!CheckStatusFlag(kSkipProcessed) || !fBlockDescList[fCurrent].IsProcessed())) {
140 iResult=fBlockDescList[fCurrent].GetIndex();
141 // TODO: check the byte order on the current system and the byte order of the
142 // data block, print warning when mismatch and user did not check
143 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
146 if (blockBO!=fByteOrder) {
147 SetStatusFlag(kByteOrderWarning);
151 ClearStatusFlag(kByteOrderChecked);
153 // TODO: check the alignment on the current system and the alignment of the
154 // data block, print warning when mismatch and user did not check
155 ClearStatusFlag(kAlignmentChecked);
164 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
166 // fill data type and specification
168 if (fCurrent<fBlockDescList.size()) {
170 dt=fBlockDescList[fCurrent];
171 spec=fBlockDescList[fCurrent];
176 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
178 // Get handler descriptor of the selected data block.
179 return FindHandlerDesc(fCurrent);
182 AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
184 // Get handler type of the selected data block.
185 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(fCurrent);
186 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
190 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
192 // Get the index of the current data block.
193 if (fCurrent>=fBlockDescList.size()) return AliHLTOUTInvalidIndex;
194 return fBlockDescList[fCurrent].GetIndex();
197 int AliHLTOUT::GetDataBuffer(AliHLTComponentBlockData& desc)
199 // fill block data descriptor and select the current data buffer
200 // buffer has to be released using ReleaseDataBuffer
202 if (fCurrent<fBlockDescList.size()) {
203 AliHLTComponent::FillBlockData(desc);
204 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, desc.fSize))>=0) {
205 desc.fPtr=const_cast<void*>(reinterpret_cast<const void*>(fpBuffer));
206 desc.fDataType=fBlockDescList[fCurrent];
207 desc.fSpecification=fBlockDescList[fCurrent];
213 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
215 // select and return the current data buffer
216 // buffer has to be released using ReleaseDataBuffer
220 if (fCurrent<fBlockDescList.size()) {
221 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(fpBuffer, size))>=0) {
228 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
230 // release data buffer, previously returned by GetDataBuffer
232 if (pBuffer==fpBuffer) {
235 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "ReleaseDataBuffer" , __FILE__ , __LINE__ , "buffer %p does not match the provided one %p", pBuffer, fpBuffer);
240 AliHLTModuleAgent* AliHLTOUT::GetAgent()
242 // get module agent of the selected data block
243 AliHLTModuleAgent* pAgent=NULL;
244 pAgent=FindHandlerDesc(fCurrent);
248 AliHLTOUTHandler* AliHLTOUT::GetHandler()
250 // get HLTOUT handler of the selected data block
251 AliHLTOUTHandler* pHandler=NULL;
252 pHandler=FindHandlerDesc(fCurrent);
256 int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
258 // default function, child must overload
259 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "WriteESD" , __FILE__ , __LINE__ , "method not implemented in base class");
263 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
265 // add new block descriptor
266 if (!CheckStatusFlag(kCollecting)) return -EPERM;
268 fBlockDescList.push_back(desc);
272 AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
274 // check the byte order of the current data block
275 // NOTE: this functionality has not been tested and development was hardly finished
276 if (fCurrent<fBlockDescList.size()) {
277 SetStatusFlag(kByteOrderChecked);
278 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder(fBlockDescList[fCurrent].GetIndex());
281 return kInvalidByteOrder;
284 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
286 // check alignment of the current data block
287 // NOTE: this functionality has not been tested and development was hardly finished
288 if (fCurrent<fBlockDescList.size()) {
289 SetStatusFlag(kAlignmentChecked);
290 int alignment=CheckBlockAlignment(fBlockDescList[fCurrent].GetIndex(), type);
296 int AliHLTOUT::InitHandlers()
298 // init handlers for all registered blocks
300 AliHLTOUTIndexList remnants;
302 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
304 remnants.push_back(GetDataBlockIndex());
305 AliHLTComponentDataType dt=kAliHLTVoidDataType;
306 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
307 if (GetDataBlockDescription(dt, spec)<0) break;
308 bool bHaveHandler=false;
309 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
310 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
311 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
312 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
313 InsertHandler(fDataHandlers, entry);
318 sout << "adding handler for block " << AliHLTComponent::DataType2Text(dt).c_str()
319 << " 0x" << setfill('0') << setw(8) << hex << spec;
320 cout << sout.str() << endl;
325 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
326 // ESDs are handled by the framework
331 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
333 if (GetNofDataBlocks()>iCount) {
334 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, GetNofDataBlocks());
337 // warning if handler not found
338 if (remnants.size()>0) {
339 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "no handlers found for %d data blocks out of %d", remnants.size(), iCount);
340 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
341 for (AliHLTOUTIndexList::iterator element=remnants.begin();
342 element!=remnants.end() && block!=fBlockDescList.end();
344 for (int trials=0; trials<2; trials++) {
346 // we start searching the index from the current position in the block list
347 if ((*block).GetIndex()==*element) break;
348 } while ((++block)!=fBlockDescList.end());
349 if (block==fBlockDescList.end()) {
350 // rewind and try again
351 block=fBlockDescList.begin();
354 assert(block!=fBlockDescList.end());
358 if (fbVerbose) Print();
363 int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
365 // insert handler into list, called from child implementations
367 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
368 for (; element!=list.end();
370 if (entry==(*element)) break;
372 if (element==list.end()) {
373 list.push_back(entry);
375 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
380 int AliHLTOUT::FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
382 // fill a list according to specified handler type
384 for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, handlerType);
386 iResult=SelectNextDataBlock()) {
387 AliHLTComponentDataType dt=kAliHLTVoidDataType;
388 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
389 GetDataBlockDescription(dt, spec);
390 AliHLTOUTHandler* pHandler=GetHandler();
392 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "FillHandlerList" , __FILE__ , __LINE__ ,
393 "missing HLTOUT handler for block of type kChain: agent %s, data type %s, specification %#x, ... skipping data block",
394 GetAgent()?GetAgent()->GetModuleId():"invalid",
395 AliHLTComponent::DataType2Text(dt).c_str(), spec);
397 InsertHandler(list, GetDataBlockHandlerDesc());
400 // TODO: the return value of SelectFirst/NextDataBlock must be
401 // changed in order to avoid this check
402 if (iResult==-ENOENT) iResult=0;
407 int AliHLTOUT::RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list)
409 // remove empty handlers from list
411 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
412 while (element!=list.end()) {
413 if (element->IsEmpty()) {
414 AliHLTOUTHandler* pHandler=*element;
415 AliHLTModuleAgent* pAgent=*element;
416 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*element;
417 if (FindHandler(list, desc)>=0) {
418 element=list.erase(element);
420 pAgent->DeleteOutputHandler(pHandler);
422 // we are already at the next element
431 int AliHLTOUT::FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc)
433 // find handler according to descriptor
434 for (int i=0; i<(int)list.size(); i++) {
435 if (list[i]==desc) return i;
440 int AliHLTOUT::InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list)
442 // invalidate all handlers in a list
443 for (AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
446 element->InvalidateBlocks();
451 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
453 // get handler description
454 if (blockIndex<fBlockDescList.size()) {
455 return fBlockDescList[blockIndex].GetHandlerDesc();
457 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::VoidHandlerListEntry());
460 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
467 // default constructor
470 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
471 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
472 AliHLTModuleAgent* pAgent,
473 AliHLTUInt32_t index)
476 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
481 *fpHandlerDesc=handlerDesc;
482 fBlocks.push_back(index);
485 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
487 fpHandler(src.fpHandler),
488 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
489 fpAgent(src.fpAgent),
493 *fpHandlerDesc=*src.fpHandlerDesc;
494 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
497 AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
500 if (fpHandlerDesc) delete fpHandlerDesc;
504 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
506 // assignment operator
507 if (this==&src) return *this;
508 fpHandler=src.fpHandler;
509 if (src.fpHandlerDesc)
510 *fpHandlerDesc=*src.fpHandlerDesc;
512 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
516 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
519 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
522 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
524 // comparison operator
525 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
526 assert(entry.fpAgent==fpAgent);
527 if (entry.fpAgent!=fpAgent) return false;
531 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
533 // comparison operator
534 if (!fpHandlerDesc) return false;
535 return *fpHandlerDesc==handlerType;
538 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const
540 // comparison operator
541 if (!fpHandlerDesc) return false;
542 return *fpHandlerDesc==desc;
545 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(const AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
547 // add block index, a handler can serve multiple blocks
548 AliHLTOUTIndexList::const_iterator element;
549 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
554 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
556 // add block index, a handler can serve multiple blocks
557 fBlocks.push_back(index);
560 bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index) const
562 // check if handler serves the specified block
563 AliHLTOUTIndexList::iterator element;
564 for (unsigned int i=0; i<fBlocks.size(); i++) {
565 if (fBlocks[i]==index) return true;
570 const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
572 AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
574 // swap a 64 bit number
575 return ((src & 0xFFULL) << 56) |
576 ((src & 0xFF00ULL) << 40) |
577 ((src & 0xFF0000ULL) << 24) |
578 ((src & 0xFF000000ULL) << 8) |
579 ((src & 0xFF00000000ULL) >> 8) |
580 ((src & 0xFF0000000000ULL) >> 24) |
581 ((src & 0xFF000000000000ULL) >> 40) |
582 ((src & 0xFF00000000000000ULL) >> 56);
585 AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
587 // swap a 32 bit number
588 return ((src & 0xFFULL) << 24) |
589 ((src & 0xFF00ULL) << 8) |
590 ((src & 0xFF0000ULL) >> 8) |
591 ((src & 0xFF000000ULL) >> 24);
594 AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
596 // transparently create HLTOUT implementation for AliRawReader
597 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTRawReader", "libHLTrec.so");
599 instance->SetParam(pRawReader);
604 AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
606 // transparently create HLTOUT implementation for digit tree
607 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
609 instance->SetParam(pDigitTree, event);
614 AliHLTOUT* AliHLTOUT::New(const char* filename, int event)
616 // transparently create HLTOUT implementation for raw file
617 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
619 instance->SetParam(filename, event);
624 void AliHLTOUT::Delete(AliHLTOUT* pInstance)
626 // delete the HLTOUT instance
627 // check if the library is still there in order to have the
628 // destructor available
630 if (!pInstance) return;
631 if (pInstance==fgGlobalInstance) return;
633 TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
634 TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
635 if (!pCl1 && !pCl2) {
637 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
644 void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
646 // see header file for class documentation
647 // default implementation, we should never get here
648 // this function can only be called from the class itsself and
649 // is intended to be used with the New functions. If we get into
650 // the default implementation there is a class mismatch.
652 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
655 void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
657 // see header file for class documentation
658 // default implementation, we should never get here
659 // this function can only be called from the class itsself and
660 // is intended to be used with the New functions. If we get into
661 // the default implementation there is a class mismatch.
663 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
666 void AliHLTOUT::SetParam(const char* /*filename*/, int /*event*/)
668 // see header file for class documentation
669 // default implementation, we should never get here
670 // this function can only be called from the class itsself and
671 // is intended to be used with the New functions. If we get into
672 // the default implementation there is a class mismatch.
674 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
677 int AliHLTOUT::SelectDataBlock()
679 // mark the current data block for processing
681 if (fCurrent>=fBlockDescList.size()) return 0;
682 fBlockDescList[fCurrent].Select(true);
683 EnableBlockSelection();
687 int AliHLTOUT::SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerEntry)
689 // mark all data blocks served by specified handler for processing
691 if (!pHandlerEntry) return 0;
693 AliHLTModuleAgent* pAgent=*pHandlerEntry;
695 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", "selecting blocks for handler %s", pAgent->GetModuleId());
696 AliHLTOUTBlockDescriptorVector::iterator element;
697 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
698 block!=fBlockDescList.end();
700 if (block->GetHandlerDesc()==*pHandlerEntry && pHandlerEntry->HasIndex(block->GetIndex())) {
702 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " select block %s", AliHLTComponent::DataType2Text(*block).c_str());
704 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " skip block %s", AliHLTComponent::DataType2Text(*block).c_str());
705 block->Select(false);
708 EnableBlockSelection();
710 // Matthias 2009-07-03 bugfix: the fCurrent position was not reset at that
711 // place. Also I think the data type and specification must be set in order
712 // to make SelectFirst/NextDataBlock working on the selected collection
714 AliHLTModuleAgent::AliHLTOUTHandlerDesc pHandlerDesc=*pHandlerEntry;
715 fSearchDataType=pHandlerDesc;
716 fSearchSpecification=kAliHLTVoidDataSpec;
717 fSearchHandlerType=pHandlerDesc;
723 int AliHLTOUT::EnableBlockSelection()
725 // enable block selection, in this mode only the blocks marked for
726 // processing can be accessed
727 SetStatusFlag(kBlockSelection);
731 int AliHLTOUT::DisableBlockSelection()
733 // disable block selection
734 ClearStatusFlag(kBlockSelection);
738 int AliHLTOUT::ResetBlockSelection()
740 // reset the 'selected' flag for all blocks
741 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
742 block!=fBlockDescList.end();
744 block->Select(false);
749 int AliHLTOUT::MarkDataBlockProcessed()
751 // mark the current data block as 'processed'
753 if (fCurrent>=fBlockDescList.size()) return 0;
754 fBlockDescList[fCurrent].MarkProcessed();
758 int AliHLTOUT::MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc)
760 // mark all data blocks served by handler as processed
762 if (!pHandlerDesc) return 0;
764 AliHLTOUTBlockDescriptorVector::iterator element;
765 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
766 block!=fBlockDescList.end();
768 if (block->GetHandlerDesc()==*pHandlerDesc && pHandlerDesc->HasIndex(block->GetIndex()))
769 block->MarkProcessed();
775 int AliHLTOUT::AddSubCollection(AliHLTOUT* pCollection)
777 // add a sub-collection to the HLTOUT instance
778 // all blocks of the sub-collection are accessed transparently through the master instance
780 if (!pCollection) return 0;
782 SetStatusFlag(kCollecting);
784 for (index=pCollection->SelectFirstDataBlock();
786 index=pCollection->SelectNextDataBlock()) {
787 AliHLTComponentDataType dt=kAliHLTVoidDataType;
788 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
789 pCollection->GetDataBlockDescription(dt, spec);
790 AliHLTOUTBlockDescriptor desc(dt, spec, index, pCollection);
791 AddBlockDescriptor(desc);
795 if (CheckStatusFlag(kIsSubCollection)) {
796 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "AddSubCollection" , __FILE__ , __LINE__ , "HLTOUT object %p has already been added as sub-collection", pCollection);
798 pCollection->SetStatusFlag(kIsSubCollection);
801 ClearStatusFlag(kCollecting);
806 int AliHLTOUT::ReleaseSubCollection(AliHLTOUT* pCollection)
808 // release a sub-collection
810 if (!pCollection) return 0;
812 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
813 while (block!=fBlockDescList.end()) {
814 if ((*block)==pCollection) {
815 block=fBlockDescList.erase(block);
820 pCollection->ClearStatusFlag(kIsSubCollection);
825 int AliHLTOUT::Reset()
827 // reset HLTOUT instance
828 // clears all blocks and handler descriptions
830 AliHLTOUTPVector subCollections;
831 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
832 while (block!=fBlockDescList.end()) {
833 if (!((*block)==this)) {
834 AliHLTOUTPVector::iterator collection=subCollections.begin();
835 for (; collection!=subCollections.end(); collection++)
836 if((*block)==*collection) break;
837 if (collection==subCollections.end())
838 subCollections.push_back(block->GetCollection());
840 block=fBlockDescList.erase(block);
843 for (AliHLTOUTPVector::iterator collection=subCollections.begin();
844 collection!=subCollections.end(); collection++) {
845 (*collection)->Reset();
846 (*collection)->ClearStatusFlag(kIsSubCollection);
850 fCurrentEventId=kAliHLTVoidEventID;
855 int AliHLTOUT::ResetInput()
857 // default implementation, nothing to do
861 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTBlockDescriptor::GetHandlerDesc()
863 // see header file for class documentation
865 AliHLTOUTHandlerListEntryVector::iterator element=fpCollection->fDataHandlers.begin();
866 while (element!=fpCollection->fDataHandlers.end()) {
867 if (element->HasIndex(GetIndex())) {
873 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::VoidHandlerListEntry());
876 TObject* AliHLTOUT::GetDataObject()
878 // check if the current block encodes a ROOT object and expand it
880 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
881 ReleaseDataBuffer(fpObjectBuffer);
887 if (GetDataBuffer(fpObjectBuffer, fObjectBufferSize)>=0) {
888 fpDataObject=AliHLTMessage::Extract(fpObjectBuffer, fObjectBufferSize);
890 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "can not fetch data buffer");
896 int AliHLTOUT::ReleaseDataObject(TObject* pObject)
898 // release a ROOT object previously expanded from the currentr data block
899 if (!pObject) return -EINVAL;
900 if (pObject!=fpDataObject) {
901 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "attempt to release wrong data object %p, expected %p", pObject, fpDataObject);
907 ReleaseDataBuffer(fpObjectBuffer);
914 void AliHLTOUT::SetEventId(AliHLTUInt64_t id)
917 if (fCurrentEventId!=kAliHLTVoidEventID && fCurrentEventId!=id) {
918 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "SetEventId" , __FILE__ , __LINE__ , "event id was already set to 0x%llx, setting now to 0x%llx", fCurrentEventId, id);
923 void AliHLTOUT::Print(const char* option) const
927 for (AliHLTOUTBlockDescriptorVector::const_iterator i=fBlockDescList.begin();
928 i!=fBlockDescList.end(); i++)
932 for (AliHLTOUTHandlerListEntryVector::const_iterator i=fDataHandlers.begin();
933 i!=fDataHandlers.end(); i++)
938 void AliHLTOUT::AliHLTOUTBlockDescriptor::Print(const char* /*option*/) const
942 sout << "AliHLTOUTBlockDescriptor index 0x" << setfill('0') << setw(8) << hex << right << fIndex
943 << ": " << AliHLTComponent::DataType2Text(fDataType).c_str()
944 << " 0x" << setfill('0') << setw(8) << hex << fSpecification
945 << " processed " << dec << fProcessed;
946 cout << sout.str() << endl;
949 void AliHLTOUT::AliHLTOUTHandlerListEntry::Print(const char* /*option*/) const
953 AliHLTModuleAgent::AliHLTOUTHandlerType type=AliHLTModuleAgent::kUnknownOutput;
954 AliHLTComponentDataType dt=kAliHLTVoidDataType;
955 if (this->fpHandlerDesc) {
956 type=*(this->fpHandlerDesc);
957 dt=*(this->fpHandlerDesc);
959 const char* stype="";
961 case AliHLTModuleAgent::kEsd: stype="ESD"; break;
962 case AliHLTModuleAgent::kRawReader: stype="RawReader"; break;
963 case AliHLTModuleAgent::kRawStream: stype="RawStream"; break;
964 case AliHLTModuleAgent::kChain: stype="Chain"; break;
965 case AliHLTModuleAgent::kProprietary: stype="Proprietary"; break;
966 default: stype="unknown";
968 sout << "HLTOUT handler: "
969 << " " << type << " (" << stype << ")"
970 << " " << AliHLTComponent::DataType2Text(dt).c_str();
971 cout << sout.str() << endl;