3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
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. */
24 // see header file for class documentation
26 // refer to README to build package
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
32 #include "AliHLTOUT.h"
34 /** ROOT macro for the implementation of ROOT specific class methods */
37 AliHLTOUT::AliHLTOUT()
39 fSearchDataType(kAliHLTVoidDataType),
40 fSearchSpecification(kAliHLTVoidDataSpec),
41 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
44 fCurrent(fBlockDescList.begin()),
49 // see header file for class documentation
51 // refer to README to build package
53 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
56 AliHLTOUT::~AliHLTOUT()
58 // see header file for class documentation
63 // see header file for class documentation
65 SetStatusFlag(kCollecting);
66 if ((iResult=GenerateIndex())>=0) {
67 if ((iResult=InitHandlers())>=0) {
70 ClearStatusFlag(kCollecting);
74 int AliHLTOUT::GetNofDataBlocks()
76 // see header file for class documentation
77 return fBlockDescList.size();
80 int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
81 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
83 // see header file for class documentation
84 if (CheckStatusFlag(kLocked)) return -EPERM;
85 fCurrent=fBlockDescList.begin();
87 fSearchSpecification=spec;
88 fSearchHandlerType=handlerType;
89 return FindAndSelectDataBlock();
92 int AliHLTOUT::SelectNextDataBlock()
94 // see header file for class documentation
95 if (CheckStatusFlag(kLocked)) return -EPERM;
96 if (fCurrent==fBlockDescList.end()) return -ENOENT;
98 return FindAndSelectDataBlock();
101 int AliHLTOUT::FindAndSelectDataBlock()
103 // see header file for class documentation
104 if (CheckStatusFlag(kLocked)) return -EPERM;
106 while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
107 if ((*fCurrent)==fSearchDataType &&
108 (fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification) &&
109 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent->GetIndex())==fSearchHandlerType)) {
110 iResult=fCurrent->GetIndex();
111 // TODO: check the byte order on the current system and the byte order of the
112 // data block, print warning when mismatch and user did not check
113 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
116 if (blockBO!=fByteOrder) {
117 SetStatusFlag(kByteOrderWarning);
121 ClearStatusFlag(kByteOrderChecked);
123 // TODO: check the alignment on the current system and the alignment of the
124 // data block, print warning when mismatch and user did not check
125 ClearStatusFlag(kAlignmentChecked);
134 int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
136 // see header file for class documentation
138 if (fCurrent!=fBlockDescList.end()) {
146 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
148 // see header file for class documentation
149 return FindHandlerDesc(GetDataBlockIndex());
152 AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
154 // see header file for class documentation
155 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(GetDataBlockIndex());
156 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
160 AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
162 // see header file for class documentation
163 if (fCurrent==fBlockDescList.end()) return AliHLTOUTInvalidIndex;
164 return fCurrent->GetIndex();
167 int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
169 // see header file for class documentation
173 if (fCurrent!=fBlockDescList.end()) {
174 if ((iResult=GetDataBuffer(fCurrent->GetIndex(), pBuffer, size))>=0) {
181 int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
183 // see header file for class documentation
185 if (pBuffer==fpBuffer) {
188 HLTWarning("buffer %p does not match the provided one %p", pBuffer, fpBuffer);
193 AliHLTModuleAgent* AliHLTOUT::GetAgent()
195 // see header file for class documentation
196 AliHLTModuleAgent* pAgent=NULL;
197 pAgent=FindHandlerDesc(GetDataBlockIndex());
201 AliHLTOUTHandler* AliHLTOUT::GetHandler()
203 // see header file for class documentation
204 AliHLTOUTHandler* pHandler=NULL;
205 pHandler=FindHandlerDesc(GetDataBlockIndex());
209 int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
211 // see header file for class documentation
212 HLTWarning("method not implemented in base class");
216 int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
218 // see header file for class documentation
219 if (!CheckStatusFlag(kCollecting)) return -EPERM;
221 fBlockDescList.push_back(desc);
225 AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
227 // see header file for class documentation
228 if (fCurrent!=fBlockDescList.end()) {
229 SetStatusFlag(kByteOrderChecked);
230 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder((*fCurrent).GetIndex());
233 return kInvalidByteOrder;
236 int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
238 // see header file for class documentation
239 if (fCurrent!=fBlockDescList.end()) {
240 SetStatusFlag(kAlignmentChecked);
241 int alignment=CheckBlockAlignment((*fCurrent).GetIndex(), type);
247 int AliHLTOUT::InitHandlers()
249 // see header file for class documentation
251 AliHLTOUTIndexList remnants;
253 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
255 remnants.push_back(GetDataBlockIndex());
256 AliHLTComponentDataType dt=kAliHLTVoidDataType;
257 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
258 if (GetDataBlockDescription(dt, spec)<0) break;
259 bool bHaveHandler=false;
260 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
261 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
262 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
263 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
264 InsertHandler(fDataHandlers, entry);
270 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
271 // ESDs are handled by the framework
276 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
278 if (GetNofDataBlocks()>iCount) {
279 HLTWarning("incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, iCount);
282 // warning if handler not found
283 if (remnants.size()>0) {
284 HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), iCount);
285 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
286 for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
287 for (int trials=0; trials<2; trials++) {
289 // we start searching the index from the current position in the block list
290 if ((*block).GetIndex()==*element) break;
291 } while ((++block)!=fBlockDescList.end());
292 if (block==fBlockDescList.end()) {
293 // rewind and try again
294 block=fBlockDescList.begin();
297 assert(block!=fBlockDescList.end());
298 if (block!=fBlockDescList.end()) {
299 HLTDebug(" %s", AliHLTComponent::DataType2Text((AliHLTComponentDataType)*block).c_str());
306 int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
308 // see header file for class documentation
310 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
311 while (element!=list.end()) {
312 if (entry==(*element)) break;
315 if (element==list.end()) {
316 list.push_back(entry);
318 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
323 const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
325 // see header file for class documentation
326 AliHLTOUTHandlerListEntryVector::iterator element=fDataHandlers.begin();
327 while (element!=fDataHandlers.end()) {
328 if (element->HasIndex(blockIndex)) {
333 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
336 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
343 // see header file for class documentation
346 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
347 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
348 AliHLTModuleAgent* pAgent,
349 AliHLTUInt32_t index)
352 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
356 // see header file for class documentation
357 *fpHandlerDesc=handlerDesc;
358 fBlocks.push_back(index);
361 AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
363 fpHandler(src.fpHandler),
364 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
365 fpAgent(src.fpAgent),
368 // see header file for class documentation
369 *fpHandlerDesc=*src.fpHandlerDesc;
370 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
373 AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
375 // see header file for class documentation
376 if (fpHandlerDesc) delete fpHandlerDesc;
380 AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
382 // see header file for class documentation
383 fpHandler=src.fpHandler;
384 if (src.fpHandlerDesc)
385 *fpHandlerDesc=*src.fpHandlerDesc;
387 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
391 AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
393 // see header file for class documentation
394 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
397 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
399 // see header file for class documentation
400 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
401 assert(entry.fpAgent==fpAgent);
402 if (entry.fpAgent!=fpAgent) return false;
406 bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
408 // see header file for class documentation
409 if (!fpHandlerDesc) return false;
410 return *fpHandlerDesc==handlerType;
413 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
415 // see header file for class documentation
416 AliHLTOUTIndexList::iterator element;
417 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
422 void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
424 // see header file for class documentation
425 fBlocks.push_back(index);
428 bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index)
430 // see header file for class documentation
431 AliHLTOUTIndexList::iterator element;
432 for (element=fBlocks.begin(); element!=fBlocks.end(); element++) {
433 if (*element==index) return true;
438 const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
440 AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
442 // see header file for class documentation
443 return ((src & 0xFFULL) << 56) |
444 ((src & 0xFF00ULL) << 40) |
445 ((src & 0xFF0000ULL) << 24) |
446 ((src & 0xFF000000ULL) << 8) |
447 ((src & 0xFF00000000ULL) >> 8) |
448 ((src & 0xFF0000000000ULL) >> 24) |
449 ((src & 0xFF000000000000ULL) >> 40) |
450 ((src & 0xFF00000000000000ULL) >> 56);
453 AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
455 // see header file for class documentation
456 return ((src & 0xFFULL) << 24) |
457 ((src & 0xFF00ULL) << 8) |
458 ((src & 0xFF0000ULL) >> 8) |
459 ((src & 0xFF000000ULL) >> 24);