]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
adding huffnam coding base class and data deflater using it (Thorsten)
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3dd8541e 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//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
f23a6e1a 19
0007ed52 20// @file AliHLTComponent.cxx
21// @author Matthias Richter, Timm Steinbeck
22// @date
23// @brief Base class implementation for HLT components. */
24// @note The class is both used in Online (PubSub) and Offline (AliRoot)
25// context
26
f23a6e1a 27
0c0c9d99 28#if __GNUC__>= 3
f23a6e1a 29using namespace std;
30#endif
31
66043029 32//#include "AliHLTStdIncludes.h"
f23a6e1a 33#include "AliHLTComponent.h"
34#include "AliHLTComponentHandler.h"
a655eae3 35#include "AliHLTMessage.h"
adb91bc3 36#include "AliHLTCTPData.h"
76390ea0 37#include "AliHLTErrorGuard.h"
89413559 38#include "AliRawDataHeader.h"
70ed7d01 39#include "TString.h"
ed504011 40#include "TMath.h"
a655eae3 41#include "TObjArray.h"
79c114b5 42#include "TObjectTable.h"
a655eae3 43#include "TClass.h"
90ebac25 44#include "TStopwatch.h"
cf9cf07e 45#include "TFormula.h"
cc095616 46#include "TUUID.h"
47#include "TMD5.h"
48#include "TRandom3.h"
79c114b5 49#include "AliHLTMemoryFile.h"
579d9eb7 50#include "AliHLTMisc.h"
ec25e4ca 51#include <cassert>
bee8f777 52#include <ctime>
0da432fa 53#include <stdint.h>
f23a6e1a 54
9ace7282 55/**
56 * default compression level for ROOT objects
57 */
58#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
2e3fd14f 59#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
9ace7282 60
b22e91eb 61/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 62ClassImp(AliHLTComponent);
63
64/** stopwatch macro using the stopwatch guard */
65#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
66//#define ALIHLTCOMPONENT_STOPWATCH(type)
67
68/** stopwatch macro for operations of the base class */
69#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
70/** stopwatch macro for operations of the detector algorithm (DA) */
71#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 72
f23a6e1a 73AliHLTComponent::AliHLTComponent()
85869391 74 :
53feaef5 75 fEnvironment(),
3cde846d 76 fCurrentEvent(0),
a655eae3 77 fEventCount(-1),
78 fFailedEvents(0),
79 fCurrentEventData(),
80 fpInputBlocks(NULL),
81 fCurrentInputBlock(-1),
82 fSearchDataType(kAliHLTVoidDataType),
83 fClassName(),
84 fpInputObjects(NULL),
85 fpOutputBuffer(NULL),
86 fOutputBufferSize(0),
87 fOutputBufferFilled(0),
90ebac25 88 fOutputBlocks(),
79c114b5 89 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 90 fMemFiles(),
91 fpRunDesc(NULL),
82c58a87 92 fCDBSetRunNoFunc(false),
a0aeb701 93 fChainId(),
48abe484 94 fChainIdCrc(0),
a0aeb701 95 fpBenchmark(NULL),
78d29060 96 fFlags(0),
abb52c8f 97 fEventType(gkAliEventTypeUnknown),
eafbc306 98 fComponentArgs(),
99 fEventDoneData(NULL),
9ace7282 100 fEventDoneDataSize(0),
101 fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
b3f4766b 102 , fLastObjectSize(0)
adb91bc3 103 , fpCTPData(NULL)
9d4d4b02 104 , fPushbackPeriod(0)
105 , fLastPushBackTime(-1)
70ed7d01 106{
107 // see header file for class documentation
108 // or
109 // refer to README to build package
110 // or
111 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 112 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 113 if (fgpComponentHandler)
114 fgpComponentHandler->ScheduleRegister(this);
7c781d33 115 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 116}
117
f23a6e1a 118AliHLTComponent::~AliHLTComponent()
119{
70ed7d01 120 // see header file for function documentation
a0aeb701 121 if (fpBenchmark) delete fpBenchmark;
122 fpBenchmark=NULL;
123
8451168b 124 CleanupInputObjects();
4498d7d1 125 if (fpStopwatches!=NULL) delete fpStopwatches;
126 fpStopwatches=NULL;
2be3f004 127 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 128 while (element!=fMemFiles.end()) {
129 if (*element) {
130 if ((*element)->IsClosed()==0) {
131 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
132 // close but do not flush as we dont know whether the buffer is still valid
29312178 133 (*element)->CloseMemoryFile(0);
79c114b5 134 }
135 delete *element;
136 *element=NULL;
137 }
138 element++;
139 }
45c0a780 140 if (fpRunDesc) {
141 delete fpRunDesc;
142 fpRunDesc=NULL;
143 }
eafbc306 144 if (fEventDoneData)
145 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
cf9cf07e 146 fEventDoneData=NULL;
147
adb91bc3 148 if (fpCTPData) {
149 delete fpCTPData;
cf9cf07e 150 }
adb91bc3 151 fpCTPData=NULL;
f23a6e1a 152}
153
70ed7d01 154AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 155
85869391 156int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
157{
70ed7d01 158 // see header file for function documentation
85869391 159 int iResult=0;
70ed7d01 160 if (fgpComponentHandler==NULL || bOverwrite!=0)
161 fgpComponentHandler=pCH;
85869391 162 else
163 iResult=-EPERM;
164 return iResult;
165}
166
70ed7d01 167int AliHLTComponent::UnsetGlobalComponentHandler()
168{
169 // see header file for function documentation
85869391 170 return SetGlobalComponentHandler(NULL,1);
171}
172
c528fdc6 173int AliHLTComponent::SetComponentEnvironment(const AliHLTAnalysisEnvironment* comenv, void* environParam)
f23a6e1a 174{
70ed7d01 175 // see header file for function documentation
66108417 176 HLTLogKeyword(fChainId.c_str());
f23a6e1a 177 int iResult=0;
f7561f8d 178 if (comenv) {
a3c9b745 179 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
180 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
181 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 182 fEnvironment.fParam=environParam;
f23a6e1a 183 }
c528fdc6 184 return iResult;
185}
186
187int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
188{
189 // see header file for function documentation
190 HLTLogKeyword(fChainId.c_str());
191 int iResult=0;
192 if (comenv) {
193 SetComponentEnvironment(comenv, environParam);
194 }
9d4d4b02 195 fPushbackPeriod=0;
196 fLastPushBackTime=-1;
197
abb52c8f 198 fComponentArgs="";
8451168b 199 const char** pArguments=NULL;
200 int iNofChildArgs=0;
201 TString argument="";
202 int bMissingParam=0;
203 if (argc>0) {
204 pArguments=new const char*[argc];
205 if (pArguments) {
206 for (int i=0; i<argc && iResult>=0; i++) {
abb52c8f 207 if (fComponentArgs.size()>0) fComponentArgs+=" ";
208 fComponentArgs+=argv[i];
8451168b 209 argument=argv[i];
210 if (argument.IsNull()) continue;
211
212 // benchmark
66108417 213 if (argument.CompareTo("-benchmark")==0) {
8451168b 214
66108417 215 // -loglevel=
216 } else if (argument.BeginsWith("-loglevel=")) {
217 TString parameter=argument.ReplaceAll("-loglevel=", "");
8451168b 218 parameter.Remove(TString::kLeading, ' '); // remove all blanks
219 if (parameter.BeginsWith("0x") &&
220 parameter.Replace(0,2,"",0).IsHex()) {
bd6cac58 221 unsigned int loglevel=kHLTLogNone;
222 sscanf(parameter.Data(),"%x", &loglevel);
223 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
8451168b 224 } else {
225 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
226 iResult=-EINVAL;
227 }
9ace7282 228 // -object-compression=
229 } else if (argument.BeginsWith("-object-compression=")) {
230 argument.ReplaceAll("-object-compression=", "");
231 if (argument.IsDigit()) {
232 fCompressionLevel=argument.Atoi();
233 if (fCompressionLevel<0 || fCompressionLevel>9) {
234 HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
235 fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
236 }
237 } else {
238 HLTError("wrong parameter for argument -object-compression, number expected");
239 }
9d4d4b02 240 // -pushback-period=
241 } else if (argument.BeginsWith("-pushback-period=")) {
242 argument.ReplaceAll("-pushback-period=", "");
243 if (argument.IsDigit()) {
244 fPushbackPeriod=argument.Atoi();
245 } else {
246 HLTError("wrong parameter for argument -pushback-period, number expected");
247 }
78d29060 248 // -disable-component-stat
249 } else if (argument.CompareTo("-disable-component-stat")==0) {
250 fFlags|=kDisableComponentStat;
8451168b 251 } else {
252 pArguments[iNofChildArgs++]=argv[i];
253 }
254 }
255 } else {
256 iResult=-ENOMEM;
257 }
258 }
259 if (bMissingParam) {
260 HLTError("missing parameter for argument %s", argument.Data());
261 iResult=-EINVAL;
262 }
5ef2a37b 263 if (iResult>=0) {
264 iResult=CheckOCDBEntries();
265 }
8451168b 266 if (iResult>=0) {
267 iResult=DoInit(iNofChildArgs, pArguments);
268 }
a0aeb701 269 if (iResult>=0) {
270 fEventCount=0;
271
272 // find out if the component wants to get the steering events
273 // explicitly
274 AliHLTComponentDataTypeList inputDt;
275 GetInputDataTypes(inputDt);
78d29060 276 bool bRequireSteeringBlocks=false;
a0aeb701 277 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
78d29060 278 dt!=inputDt.end() && !bRequireSteeringBlocks;
a0aeb701 279 dt++) {
78d29060 280 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
281 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
282 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
283 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
284 bRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
a0aeb701 285 }
78d29060 286 if (bRequireSteeringBlocks) fFlags|=kRequireSteeringBlocks;
a0aeb701 287 }
8451168b 288 if (pArguments) delete [] pArguments;
a0aeb701 289
78d29060 290#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 291 // benchmarking stopwatch for the component statistics
292 fpBenchmark=new TStopwatch;
78d29060 293#endif // HLT_COMPONENT_STATISTICS
a0aeb701 294
f23a6e1a 295 return iResult;
296}
297
298int AliHLTComponent::Deinit()
299{
70ed7d01 300 // see header file for function documentation
66108417 301 HLTLogKeyword(fChainId.c_str());
f23a6e1a 302 int iResult=0;
303 iResult=DoDeinit();
559631d5 304 if (fpRunDesc) {
cf9cf07e 305 // TODO: the warning should be kept, but the condition is wrong since the
306 // AliHLTRunDesc is set before the SOR event in the SetRunDescription
307 // method. A couple of state flags should be defined but that is a bit more
308 // work to do. For the moment disable the warning (2009-07-01)
bee8f777 309 // 2009-09-08: now, the info is not cleared in the ProcessEvent, because it
310 // might be needed by components during the event processing.
cf9cf07e 311 //HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
559631d5 312 AliHLTRunDesc* pRunDesc=fpRunDesc;
313 fpRunDesc=NULL;
314 delete pRunDesc;
315 }
adb91bc3 316 if (fpCTPData) {
317 delete fpCTPData;
cf9cf07e 318 }
adb91bc3 319 fpCTPData=NULL;
cf9cf07e 320
579d9eb7 321 fEventCount=0;
78d29060 322 fFlags=0;
f23a6e1a 323 return iResult;
324}
fa2e9b7c 325
82c58a87 326int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 327{
82c58a87 328 // see header file for function documentation
579d9eb7 329 int iResult=0;
c528fdc6 330 HLTInfo("Using CDB: %s", cdbPath);
703bcca6 331 if (pHandler) {
82c58a87 332 // I have to think about separating the library handling from the
c528fdc6 333 // component handler. Requiring the component handler here is not
82c58a87 334 // the cleanest solution.
c528fdc6 335 // We presume the library already to be loaded, which is the case
336 // because it is loaded in the initialization of the logging functionality
337 //
579d9eb7 338 // find the symbol
82c58a87 339 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 340 if (pFunc) {
703bcca6 341 TString path;
342 if (cdbPath && cdbPath[0]!=0) {
343 path=cdbPath;
344 // very temporary fix, have to check for other formats
345 if (!path.BeginsWith("local://")) {
346 path="local://";
347 path+=cdbPath;
348 }
8f30c1ea 349 }
350 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 351 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
352 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
353 "can not find function to set CDB run no");
354 }
355 }
579d9eb7 356 } else {
357 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
358 "can not find initialization function");
359 iResult=-ENOSYS;
53feaef5 360 }
82c58a87 361 } else {
362 iResult=-EINVAL;
363 }
579d9eb7 364 return iResult;
365}
366
367int AliHLTComponent::SetCDBRunNo(int runNo)
368{
82c58a87 369 // see header file for function documentation
370 if (!fCDBSetRunNoFunc) return 0;
371 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 372}
373
45c0a780 374int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
375{
376 // see header file for function documentation
377 if (!desc) return -EINVAL;
378 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
379 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
380 return -EINVAL;
381 }
382
383 if (!fpRunDesc) {
384 fpRunDesc=new AliHLTRunDesc;
385 if (!fpRunDesc) return -ENOMEM;
386 *fpRunDesc=kAliHLTVoidRunDesc;
387 }
388
389 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
390 HLTWarning("Run description has already been set");
391 }
392 *fpRunDesc=*desc;
393 SetCDBRunNo(fpRunDesc->fRunNo);
394 // TODO: we have to decide about the runType
395 return 0;
396}
397
9a0ef890 398int AliHLTComponent::SetComponentDescription(const char* desc)
399{
48abe484 400 // see header file for function documentation
9a0ef890 401 int iResult=0;
402 if (!desc) return 0;
403
404 TString descriptor=desc;
405 TObjArray* pTokens=descriptor.Tokenize(" ");
406 if (pTokens) {
77fd699f 407 for (int i=0; i<pTokens->GetEntriesFast() && iResult>=0; i++) {
704972af 408 TString argument=pTokens->At(i++)->GetName();
9a0ef890 409 if (!argument || argument.IsNull()) continue;
410
a3c9b745 411 // chainid
412 if (argument.BeginsWith("chainid")) {
413 argument.ReplaceAll("chainid", "");
9a0ef890 414 if (argument.BeginsWith("=")) {
415 fChainId=argument.Replace(0,1,"");
48abe484 416 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
417 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 418 } else {
419 fChainId="";
420 }
421 } else {
48abe484 422 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 423 }
424 }
b09d01b5 425 delete pTokens;
9a0ef890 426 }
427
428 return iResult;
429}
430
02bc7a5f 431int AliHLTComponent::ConfigureFromArgumentString(int argc, const char** argv)
432{
704972af 433 // Configure from an array of argument strings
434 // Function supports individual arguments in the argv array and arguments
435 // separated by blanks.
436 //
437 // Each argv entry can contain blanks, quotes and newlines. Newlines are interpreted
438 // as blanks. Enclosing quotes deactivate blank as delimiter.
439 // The separated arguments are stored in an array of strings, and the pointers to
440 // those strings in an array of pointers. The latter is used in the custom argument
441 // scan of the component.
442
02bc7a5f 443 int iResult=0;
704972af 444 vector<string> stringarray; // array of argument copies
445 // array of pointers to the argument copies
446 // note: not necessarily in sync with the entries in stringarray
447 // can contain any pointer to valid arguments in arbitrary sequence
448 vector<const char*> ptrarray;
449
02bc7a5f 450 TString argument="";
451 int i=0;
452 for (i=0; i<argc && iResult>=0; i++) {
d9b2cd1d 453 argument=argv[i];
ba91c7bd 454 if (argument.IsWhitespace()) continue;
455
58f0fd47 456 // special handling for single component arguments ending with
704972af 457 // a sequence of blanks. All characters until the first occurence
458 // of a blank are removed. If the remainder contains only whitespaces
459 // the argument is a single argument, just having whitespaces at the end.
58f0fd47 460 argument.Remove(0, argument.First(' '));
461 if (argument.IsWhitespace()) {
704972af 462 ptrarray.push_back(argv[i]);
58f0fd47 463 continue;
464 }
465
704972af 466 // outer loop checks for enclosing quotes
467 // extra blank to insert blank token before leading quotes, then
468 // quoted arguments are always the even ones
58f0fd47 469 argument=" ";
470 argument+=argv[i];
471 // insert blank in consecutive quotes to correctly tokenize
472 argument.ReplaceAll("''", "' '");
473 // replace newlines by blanks
474 argument.ReplaceAll("\n", " ");
02bc7a5f 475 if (argument.IsNull()) continue;
58f0fd47 476 TObjArray* pTokensQuote=argument.Tokenize("'");
477 if (pTokensQuote) {
478 if (pTokensQuote->GetEntriesFast()>0) {
479 for (int k=0; k<pTokensQuote->GetEntriesFast(); k++) {
704972af 480 argument=pTokensQuote->At(k)->GetName();
58f0fd47 481 if (argument.IsWhitespace()) continue;
482 if (k%2) {
483 // every second entry is enclosed by quotes and thus
484 // one single argument
704972af 485 stringarray.push_back(argument.Data());
486 ptrarray.push_back(stringarray.back().c_str());
58f0fd47 487 } else {
02bc7a5f 488 TObjArray* pTokens=argument.Tokenize(" ");
489 if (pTokens) {
44869670 490 if (pTokens->GetEntriesFast()>0) {
02bc7a5f 491 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
704972af 492 TString data=pTokens->At(n)->GetName();
493 if (!data.IsNull() && !data.IsWhitespace()) {
494 stringarray.push_back(data.Data());
495 ptrarray.push_back(stringarray.back().c_str());
44869670 496 }
02bc7a5f 497 }
02bc7a5f 498 }
499 delete pTokens;
58f0fd47 500 }
501 }
502 }
58f0fd47 503 }
504 delete pTokensQuote;
02bc7a5f 505 }
506 }
507
704972af 508 for (i=0; (unsigned)i<ptrarray.size() && iResult>=0;) {
509 int result=ScanConfigurationArgument(ptrarray.size()-i, &ptrarray[i]);
02bc7a5f 510 if (result==0) {
704972af 511 HLTWarning("unknown component argument %s", ptrarray[i]);
02bc7a5f 512 i++;
513 } else if (result>0) {
514 i+=result;
515 } else {
516 iResult=result;
517 if (iResult==-EINVAL) {
704972af 518 HLTError("unknown argument %s", ptrarray[i]);
02bc7a5f 519 } else if (iResult==-EPROTO) {
704972af 520 HLTError("missing/wrong parameter for argument %s (%s)", ptrarray[i], (ptrarray.size()>(unsigned)i+1)?ptrarray[i+1]:"missing");
02bc7a5f 521 } else {
704972af 522 HLTError("scan of argument %s failed (%d)", ptrarray[i], iResult);
02bc7a5f 523 }
524 }
525 }
526
527 return iResult;
528}
529
f651054f 530int AliHLTComponent::ConfigureFromCDBTObjString(const char* entries, const char* key)
02bc7a5f 531{
f651054f 532 // load a list of OCDB objects and configure from the objects
533 // can either be a TObjString or a TMap with a TObjString:TObjString key-value pair
02bc7a5f 534 int iResult=0;
535 TString arguments;
536 TString confEntries=entries;
537 TObjArray* pTokens=confEntries.Tokenize(" ");
538 if (pTokens) {
539 for (int n=0; n<pTokens->GetEntriesFast(); n++) {
704972af 540 const char* path=pTokens->At(n)->GetName();
02bc7a5f 541 const char* chainId=GetChainId();
f651054f 542 HLTInfo("configure from entry \"%s\"%s%s, chain id %s", path, key?" key ":"",key?key:"", (chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
543 TObject* pOCDBObject = LoadAndExtractOCDBObject(path, key);
02bc7a5f 544 if (pOCDBObject) {
545 TObjString* pString=dynamic_cast<TObjString*>(pOCDBObject);
f651054f 546 if (!pString) {
547 TMap* pMap=dynamic_cast<TMap*>(pOCDBObject);
548 if (pMap) {
549 // this is the case where no key has been specified and the OCDB
550 // object is a TMap, search for the default key
551 TObject* pObject=pMap->GetValue("default");
552 if (pObject && (pString=dynamic_cast<TObjString*>(pObject))!=NULL) {
553 HLTInfo("using default key of TMap of configuration object \"%s\"", path);
554 } else {
555 HLTError("no default key available in TMap of configuration object \"%s\"", path);
556 iResult=-ENOENT;
557 break;
558 }
559 }
560 }
561
02bc7a5f 562 if (pString) {
563 HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
564 arguments+=pString->GetString().Data();
565 arguments+=" ";
566 } else {
f651054f 567 HLTError("configuration object \"%s\"%s%s has wrong type, required TObjString", path, key?" key ":"",key?key:"");
02bc7a5f 568 iResult=-EINVAL;
569 }
570 } else {
571 HLTError("can not fetch object \"%s\" from OCDB", path);
572 iResult=-ENOENT;
573 }
574 }
575 delete pTokens;
576 }
577 if (iResult>=0 && !arguments.IsNull()) {
578 const char* array=arguments.Data();
579 iResult=ConfigureFromArgumentString(1, &array);
580 }
581 return iResult;
582}
583
457005a2 584TObject* AliHLTComponent::LoadAndExtractOCDBObject(const char* path, int version, int subVersion, const char* key) const
02bc7a5f 585{
586 // see header file for function documentation
587 AliCDBEntry* pEntry=AliHLTMisc::Instance().LoadOCDBEntry(path, GetRunNo(), version, subVersion);
588 if (!pEntry) return NULL;
f651054f 589 TObject* pObject=AliHLTMisc::Instance().ExtractObject(pEntry);
590 TMap* pMap=dynamic_cast<TMap*>(pObject);
591 if (pMap && key) {
592 pObject=pMap->GetValue(key);
593 if (!pObject) {
594 pObject=pMap->GetValue("default");
595 if (pObject) {
596 HLTWarning("can not find object for key \"%s\" in TMap of configuration object \"%s\", using key \"default\"", key, path);
597 }
598 }
599 if (!pObject) {
600 HLTError("can not find object for key \"%s\" in TMap of configuration object \"%s\"", key, path);
601 return NULL;
602 }
603 }
604 return pObject;
02bc7a5f 605}
606
579d9eb7 607int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
608{
609 // default implementation, childs can overload
b543e186 610 HLTLogKeyword("dummy");
53feaef5 611 return 0;
612}
613
614int AliHLTComponent::DoDeinit()
615{
579d9eb7 616 // default implementation, childs can overload
b543e186 617 HLTLogKeyword("dummy");
579d9eb7 618 return 0;
619}
620
621int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
622{
623 // default implementation, childs can overload
b543e186 624 HLTLogKeyword("dummy");
625 return 0;
626}
627
628int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
629{
630 // default implementation, childs can overload
631 HLTLogKeyword("dummy");
53feaef5 632 return 0;
633}
634
02bc7a5f 635int AliHLTComponent::ScanConfigurationArgument(int /*argc*/, const char** /*argv*/)
636{
637 // default implementation, childs can overload
638 HLTLogKeyword("dummy");
639 HLTWarning("The function needs to be implemented by the component");
640 return 0;
641}
642
45c0a780 643int AliHLTComponent::StartOfRun()
644{
645 // default implementation, childs can overload
646 HLTLogKeyword("dummy");
647 return 0;
648}
649
650int AliHLTComponent::EndOfRun()
651{
652 // default implementation, childs can overload
653 HLTLogKeyword("dummy");
654 return 0;
655}
656
657
2be3f004 658int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 659{
82c58a87 660 // default implementation, childs can overload
3a7c0444 661 HLTLogKeyword("dummy");
de6593d0 662 return 0;
663}
664
5ef2a37b 665void AliHLTComponent::GetOCDBObjectDescription( TMap* const /*targetArray*/)
666{
667 // default implementation, childs can overload
668 HLTLogKeyword("dummy");
669}
670
671int AliHLTComponent::CheckOCDBEntries(const TMap* const externList)
672{
673 // check the availability of the OCDB entry descriptions in the TMap
674 // key : complete OCDB path of the entry
675 // value : auxiliary object - short description
676 // if the external map was not provided the function invokes
677 // interface function GetOCDBObjectDescription() to retrieve the list.
678 int iResult=0;
679 if (externList) {
680 iResult=AliHLTMisc::Instance().CheckOCDBEntries(externList);
681 } else {
682 TMap* pMap=new TMap;
683 if (pMap) {
684 pMap->SetOwnerKeyValue(kTRUE);
685 GetOCDBObjectDescription(pMap);
686 iResult=AliHLTMisc::Instance().CheckOCDBEntries(pMap);
687 delete pMap;
688 pMap=NULL;
689 }
690 }
691
692 return iResult;
693}
694
70ed7d01 695void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
696{
697 // see header file for function documentation
9ce4bf4a 698 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
699 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
bd2a51b0 700 strncat( output, ":", 1 );
9ce4bf4a 701 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 702}
703
fbdb63fd 704string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 705{
70ed7d01 706 // see header file for function documentation
9ce4bf4a 707 string out("");
fbdb63fd 708
58f0fd47 709 // 'typeid' 'origin'
710 // aligned to 8 and 4 chars respectively, blocks enclosed in quotes and
711 // separated by blank e.g.
712 // 'DDL_RAW ' 'TPC '
713 if (mode==3) {
714 int i=0;
715 char tmp[8];
716 out+="'";
717 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
718 unsigned char* puc=(unsigned char*)type.fID;
719 if (puc[i]<32)
720 sprintf(tmp, "\\%x", type.fID[i]);
721 else
722 sprintf(tmp, "%c", type.fID[i]);
723 out+=tmp;
724 }
725 out+="' '";
726 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
727 unsigned char* puc=(unsigned char*)type.fOrigin;
728 if ((puc[i])<32)
729 sprintf(tmp, "\\%x", type.fOrigin[i]);
730 else
731 sprintf(tmp, "%c", type.fOrigin[i]);
732 out+=tmp;
733 }
734 out+="'";
735 return out;
736 }
737
738 // origin typeid as numbers separated by colon e.g.
739 // aligned to 8 and 4 chars respectively, all characters separated by
740 // quotes, e.g.
741 // '84'80'67'32':'68'68'76'95'82'65'87'32'
fbdb63fd 742 if (mode==2) {
743 int i=0;
744 char tmp[8];
745 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
746 sprintf(tmp, "'%d", type.fOrigin[i]);
747 out+=tmp;
748 }
749 out+="':'";
750 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
751 sprintf(tmp, "%d'", type.fID[i]);
752 out+=tmp;
753 }
754 return out;
755 }
756
58f0fd47 757 // origin typeid separated by colon e.g.
758 // aligned to 8 and 4 chars respectively, all characters separated by
759 // quotes, e.g.
760 // 'T'P'C' ':'D'D'L'_'R'A'W' '
fbdb63fd 761 if (mode==1) {
762 int i=0;
763 char tmp[8];
764 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
765 unsigned char* puc=(unsigned char*)type.fOrigin;
766 if ((puc[i])<32)
767 sprintf(tmp, "'\\%x", type.fOrigin[i]);
768 else
769 sprintf(tmp, "'%c", type.fOrigin[i]);
770 out+=tmp;
771 }
772 out+="':'";
773 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
774 unsigned char* puc=(unsigned char*)type.fID;
775 if (puc[i]<32)
776 sprintf(tmp, "\\%x'", type.fID[i]);
777 else
778 sprintf(tmp, "%c'", type.fID[i]);
779 out+=tmp;
780 }
781 return out;
782 }
783
58f0fd47 784 // origin typeid
785 // aligned to 8 and 4 chars respectively, separated by colon e.g.
786 // TPC :DDL_RAW
9ce4bf4a 787 if (type==kAliHLTVoidDataType) {
788 out="VOID:VOID";
789 } else {
3cde846d 790 // some gymnastics in order to avoid a '0' which is part of either or both
791 // ID and origin terminating the whole string. Unfortunately, string doesn't
792 // stop appending at the '0' if the number of elements to append was
793 // explicitely specified
794 string tmp("");
795 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
796 out.append(tmp.c_str());
9ce4bf4a 797 out.append(":");
3cde846d 798 tmp="";
799 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
800 out.append(tmp.c_str());
9ce4bf4a 801 }
802 return out;
803}
804
805
70ed7d01 806void* AliHLTComponent::AllocMemory( unsigned long size )
807{
808 // see header file for function documentation
85869391 809 if (fEnvironment.fAllocMemoryFunc)
810 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 811 HLTFatal("no memory allocation handler registered");
85869391 812 return NULL;
813}
814
2be3f004 815int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 816 AliHLTComponentBlockData** outputBlocks )
817{
818 // see header file for function documentation
9ce4bf4a 819 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 820 return -EFAULT;
fa2e9b7c 821 AliHLTUInt32_t count = blocks.size();
822 if ( !count )
823 {
824 *blockCount = 0;
825 *outputBlocks = NULL;
826 return 0;
827 }
8ede8717 828 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 829 if ( !*outputBlocks )
2d7ff710 830 return -ENOMEM;
ca8524df 831 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 832 (*outputBlocks)[i] = blocks[i];
732e8f50 833 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 834 (*outputBlocks)[i].fDataType=GetOutputDataType();
835 /* data type was set to the output data type by the PubSub AliRoot
836 Wrapper component, if data type of the block was ********:****.
837 Now handled by the component base class in order to have same
838 behavior when running embedded in AliRoot
ca8524df 839 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
840 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 841 */
ca8524df 842 }
843 }
fa2e9b7c 844 *blockCount = count;
845 return 0;
846
847}
0c0c9d99 848
0007ed52 849int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) const
70ed7d01 850{
851 // see header file for function documentation
85869391 852 if (fEnvironment.fGetEventDoneDataFunc)
853 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
854 return -ENOSYS;
855}
856
eafbc306 857int AliHLTComponent::ReserveEventDoneData( unsigned long size )
858{
859 // see header file for function documentation
860 int iResult=0;
861
6f4231a1 862 unsigned long capacity=fEventDoneDataSize;
863 if (fEventDoneData) capacity-=sizeof(AliHLTComponentEventDoneData)+fEventDoneData->fDataSize;
864 if (size>capacity) {
865 unsigned long newSize=sizeof(AliHLTComponentEventDoneData)+size+(fEventDoneDataSize-capacity);
866 AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[newSize] );
eafbc306 867 if (!newEDD)
868 return -ENOMEM;
869 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
870 newEDD->fDataSize = 0;
871 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
872 if (fEventDoneData) {
873 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
874 newEDD->fDataSize = fEventDoneData->fDataSize;
875 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
876 }
877 fEventDoneData = newEDD;
6f4231a1 878 fEventDoneDataSize = newSize;
eafbc306 879 }
880 return iResult;
881
882}
883
884int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
885{
0007ed52 886 // see header file for function documentation
eafbc306 887 if (!fEventDoneData)
888 return -ENOMEM;
889 if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
890 return -ENOSPC;
891 *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
892 fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
893 return 0;
894}
895
896void AliHLTComponent::ReleaseEventDoneData()
897{
0007ed52 898 // see header file for function documentation
899 if (fEventDoneData)
eafbc306 900 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
901 fEventDoneData = NULL;
902 fEventDoneDataSize = 0;
903}
904
905
2be3f004 906int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 907{
70ed7d01 908 // see header file for function documentation
0c0c9d99 909 int iResult=0;
910 if (pConsumer) {
8a106878 911 AliHLTComponentDataTypeList itypes;
912 AliHLTComponentDataTypeList otypes;
913 otypes.push_back(GetOutputDataType());
c57201be 914 if (MatchExactly(otypes[0],kAliHLTMultipleDataType)) {
8a106878 915 otypes.clear();
916 int count=0;
917 if ((count=GetOutputDataTypes(otypes))>0) {
918 } else if (GetComponentType()!=kSink) {
919 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
920 }
921 }
0007ed52 922 pConsumer->GetInputDataTypes(itypes);
48abe484 923 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
924 for (;otype!=otypes.end();otype++) {
925 //PrintDataTypeContent((*otype), "publisher \'%s\'");
926 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
927 if (tgtList) tgtList->push_back(*otype);
928 iResult++;
929 continue;
930 }
931
932 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
32f88fc5 933 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
48abe484 934 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
935 if (itype!=itypes.end()) {
936 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 937 iResult++;
0c0c9d99 938 }
0c0c9d99 939 }
940 } else {
941 iResult=-EINVAL;
942 }
943 return iResult;
944}
2d7ff710 945
8b97f4f1 946void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 947{
66043029 948 // see header file for function documentation
8b97f4f1 949 const char* fmt="\'%s\'";
5f5b708b 950 if (format) fmt=format;
8b97f4f1 951 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
952 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
953 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
954 dt.fID[0],
955 dt.fID[1],
956 dt.fID[2],
957 dt.fID[3],
958 dt.fID[4],
959 dt.fID[5],
960 dt.fID[6],
961 dt.fID[7],
962 dt.fOrigin[0],
963 dt.fOrigin[1],
964 dt.fOrigin[2],
965 dt.fOrigin[3]));
5f5b708b 966}
967
fbdb63fd 968void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 969{
970 // see header file for function documentation
2d7ff710 971 blockData.fStructSize = sizeof(blockData);
972 FillShmData( blockData.fShmKey );
973 blockData.fOffset = ~(AliHLTUInt32_t)0;
974 blockData.fPtr = NULL;
975 blockData.fSize = 0;
976 FillDataType( blockData.fDataType );
a655eae3 977 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 978}
979
fbdb63fd 980void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 981{
982 // see header file for function documentation
2d7ff710 983 shmData.fStructSize = sizeof(shmData);
984 shmData.fShmType = gkAliHLTComponentInvalidShmType;
985 shmData.fShmID = gkAliHLTComponentInvalidShmID;
986}
987
fbdb63fd 988void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 989{
990 // see header file for function documentation
ca8524df 991 dataType=kAliHLTAnyDataType;
2d7ff710 992}
993
70ed7d01 994void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
995{
996 // see header file for function documentation
2d7ff710 997 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
998 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
999}
1000
70ed7d01 1001void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
1002{
1003 // see header file for function documentation
7e3efc8f 1004 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
1005 if (id) {
1006 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 1007 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 1008 }
1009 if (origin) {
1010 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 1011 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 1012 }
2d7ff710 1013}
9ce4bf4a 1014
18b56222 1015void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
1016{
1017 // see header file for function documentation
1018 dt.fStructSize=sizeof(AliHLTComponentDataType);
1019 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
1020 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
1021 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
1022 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
1023}
1024
9ce4bf4a 1025void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
1026{
70ed7d01 1027 // see header file for function documentation
9ce4bf4a 1028 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
1029 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 1030 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 1031}
1032
70ed7d01 1033void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
1034{
1035 // see header file for function documentation
9ce4bf4a 1036 TString msg;
1037 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
1038 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
1039 if (dt.fID[i]!=0) msg+=dt.fID[i];
1040 else msg+="\\0";
1041 }
1042 msg+="\" Origin=\"";
1043 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
1044 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
1045 else msg+="\\0";
1046 }
1047 msg+="\"";
3cde846d 1048 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 1049}
1050
70ed7d01 1051int AliHLTComponent::GetEventCount() const
3cde846d 1052{
70ed7d01 1053 // see header file for function documentation
3cde846d 1054 return fEventCount;
1055}
1056
1057int AliHLTComponent::IncrementEventCounter()
1058{
70ed7d01 1059 // see header file for function documentation
3cde846d 1060 if (fEventCount>=0) fEventCount++;
1061 return fEventCount;
1062}
1063
66043029 1064int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 1065{
1066 // see header file for function documentation
1067 if (fpInputBlocks!=NULL) {
1068 return fCurrentEventData.fBlockCnt;
1069 }
1070 return 0;
1071}
1072
4646c6e3 1073AliHLTEventID_t AliHLTComponent::GetEventId() const
1074{
1075 // see header file for function documentation
1076 if (fpInputBlocks!=NULL) {
1077 return fCurrentEventData.fEventID;
1078 }
1079 return 0;
1080}
1081
a655eae3 1082const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
1083 const char* classname,
1084 int bForce)
1085{
1086 // see header file for function documentation
90ebac25 1087 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1088 fSearchDataType=dt;
1089 if (classname) fClassName=classname;
1090 else fClassName.clear();
1edbbe49 1091 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 1092 TObject* pObj=NULL;
1093 if (idx>=0) {
79c114b5 1094 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 1095 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1096 fCurrentInputBlock=idx;
1097 } else {
1098 }
1099 }
1100 return pObj;
1101}
1102
1103const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
1104 const char* dtOrigin,
1105 const char* classname,
1106 int bForce)
1107{
1108 // see header file for function documentation
90ebac25 1109 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1110 AliHLTComponentDataType dt;
1111 SetDataType(dt, dtID, dtOrigin);
1112 return GetFirstInputObject(dt, classname, bForce);
1113}
1114
1115const TObject* AliHLTComponent::GetNextInputObject(int bForce)
1116{
1117 // see header file for function documentation
90ebac25 1118 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 1119 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 1120 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
1121 TObject* pObj=NULL;
1122 if (idx>=0) {
1123 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
1124 fCurrentInputBlock=idx;
1125 }
1126 }
1127 return pObj;
1128}
1129
1edbbe49 1130int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 1131{
1132 // see header file for function documentation
1133 int iResult=-ENOENT;
1134 if (fpInputBlocks!=NULL) {
1135 int idx=startIdx<0?0:startIdx;
4b98eadb 1136 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 1137 if (dt!=fpInputBlocks[idx].fDataType) continue;
1138
1edbbe49 1139 if (bObject!=0) {
1140 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 1141 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
1142 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 1143 }
3dd8541e 1144 iResult=idx;
a655eae3 1145 }
1146 }
1147 return iResult;
1148}
1149
1150TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
1151{
1152 // see header file for function documentation
1153 TObject* pObj=NULL;
1154 if (fpInputBlocks!=NULL) {
4b98eadb 1155 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1156 if (fpInputBlocks[idx].fPtr) {
3294f81a 1157 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 1158 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 1159 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 1160 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 1161 TClass* objclass=msg.GetClass();
1162 pObj=msg.ReadObject(objclass);
1163 if (pObj && objclass) {
1164 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 1165 } else {
1166 }
1edbbe49 1167 //} else {
1168 } else if (bForce!=0) {
c5123824 1169 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 1170 }
1171 } else {
1172 HLTFatal("block descriptor empty");
1173 }
1174 } else {
1175 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
1176 }
1177 } else {
1178 HLTError("no input blocks available");
1179 }
1180
1181 return pObj;
1182}
1183
298ef463 1184TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 1185{
1186 // see header file for function documentation
1187 if (fpInputObjects==NULL) {
1188 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
1189 }
1190 TObject* pObj=NULL;
1191 if (fpInputObjects) {
1192 pObj=fpInputObjects->At(idx);
1193 if (pObj==NULL) {
1194 pObj=CreateInputObject(idx, bForce);
1195 if (pObj) {
1196 fpInputObjects->AddAt(pObj, idx);
1197 }
1198 }
1199 } else {
1200 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
1201 }
1202 return pObj;
1203}
1204
8451168b 1205int AliHLTComponent::CleanupInputObjects()
1206{
66043029 1207 // see header file for function documentation
8451168b 1208 if (!fpInputObjects) return 0;
1209 TObjArray* array=fpInputObjects;
1210 fpInputObjects=NULL;
3ecb06e2 1211 for (int i=0; i<array->GetEntriesFast(); i++) {
8451168b 1212 TObject* pObj=array->At(i);
79c114b5 1213 // grrr, garbage collection strikes back: When read via AliHLTMessage
1214 // (CreateInputObject), and written to a TFile afterwards, the
1215 // TFile::Close calls ROOOT's garbage collection. No clue why the
1216 // object ended up in the key list and needs to be deleted
a6c7a8bc 1217 //
1218 // Matthias 09.11.2008 follow up
1219 // This approach doesn't actually work in all cases: the object table
1220 // can be switched off globally, the flag needs to be checked here as
1221 // well in order to avoid memory leaks.
1222 // This means we have to find another solution for the problem if it
1223 // pops up again.
1224 if (pObj &&
1225 (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
1226 delete pObj;
1227 }
8451168b 1228 }
1229 delete array;
90ebac25 1230 return 0;
8451168b 1231}
1232
a655eae3 1233AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
1234{
1235 // see header file for function documentation
90ebac25 1236 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1237 AliHLTComponentDataType dt=kAliHLTVoidDataType;
1238 int idx=fCurrentInputBlock;
1239 if (pObject) {
1240 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1241 } else {
1242 HLTError("unknown object %p", pObject);
1243 }
1244 }
1245 if (idx>=0) {
4b98eadb 1246 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1247 dt=fpInputBlocks[idx].fDataType;
1248 } else {
1249 HLTFatal("severe internal error, index out of range");
1250 }
1251 }
1252 return dt;
1253}
1254
1255AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
1256{
1257 // see header file for function documentation
90ebac25 1258 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1259 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1260 int idx=fCurrentInputBlock;
1261 if (pObject) {
1262 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1263 } else {
1264 HLTError("unknown object %p", pObject);
1265 }
1266 }
1267 if (idx>=0) {
4b98eadb 1268 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 1269 iSpec=fpInputBlocks[idx].fSpecification;
1270 } else {
1271 HLTFatal("severe internal error, index out of range");
1272 }
1273 }
1274 return iSpec;
1275}
1276
c7e9e2f2 1277int AliHLTComponent::Forward(const TObject* pObject)
1278{
1279 // see header file for function documentation
1280 int iResult=0;
1281 int idx=fCurrentInputBlock;
1282 if (pObject) {
1283 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
1284 } else {
1285 HLTError("unknown object %p", pObject);
1286 iResult=-ENOENT;
1287 }
1288 }
1289 if (idx>=0) {
1290 fOutputBlocks.push_back(fpInputBlocks[idx]);
1291 }
1292 return iResult;
1293}
1294
1295int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
1296{
1297 // see header file for function documentation
1298 int iResult=0;
1299 int idx=fCurrentInputBlock;
1300 if (pBlock) {
2f52bfcd 1301 if ((idx=FindInputBlock(pBlock))>=0) {
c7e9e2f2 1302 } else {
1303 HLTError("unknown Block %p", pBlock);
1304 iResult=-ENOENT;
1305 }
1306 }
1307 if (idx>=0) {
1308 // check for fpInputBlocks pointer done in FindInputBlock
1309 fOutputBlocks.push_back(fpInputBlocks[idx]);
1310 }
1311 return iResult;
1312}
1313
a655eae3 1314const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
1315{
1316 // see header file for function documentation
90ebac25 1317 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1318 fSearchDataType=dt;
1319 fClassName.clear();
1320 int idx=FindInputBlock(fSearchDataType, 0);
1321 const AliHLTComponentBlockData* pBlock=NULL;
1322 if (idx>=0) {
1323 // check for fpInputBlocks pointer done in FindInputBlock
1324 pBlock=&fpInputBlocks[idx];
1edbbe49 1325 fCurrentInputBlock=idx;
a655eae3 1326 }
1327 return pBlock;
1328}
1329
1330const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1331 const char* dtOrigin)
1332{
1333 // see header file for function documentation
90ebac25 1334 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1335 AliHLTComponentDataType dt;
1336 SetDataType(dt, dtID, dtOrigin);
1337 return GetFirstInputBlock(dt);
1338}
1339
10b9cbf9 1340const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 1341{
1342 // see header file for function documentation
1343 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 1344 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 1345 return &fpInputBlocks[index];
1346}
1347
a655eae3 1348const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1349{
1350 // see header file for function documentation
90ebac25 1351 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1352 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1353 const AliHLTComponentBlockData* pBlock=NULL;
1354 if (idx>=0) {
1355 // check for fpInputBlocks pointer done in FindInputBlock
1356 pBlock=&fpInputBlocks[idx];
1edbbe49 1357 fCurrentInputBlock=idx;
a655eae3 1358 }
1359 return pBlock;
1360}
1361
66043029 1362int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 1363{
1364 // see header file for function documentation
1365 int iResult=-ENOENT;
1366 if (fpInputBlocks!=NULL) {
1367 if (pBlock) {
1368 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 1369 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 1370 }
1371 } else {
1372 iResult=-EINVAL;
1373 }
1374 }
1375 return iResult;
1376}
1377
1378AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1379{
1380 // see header file for function documentation
90ebac25 1381 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1382 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1383 int idx=fCurrentInputBlock;
1384 if (pBlock) {
1385 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1386 } else {
1387 HLTError("unknown Block %p", pBlock);
1388 }
1389 }
1390 if (idx>=0) {
1391 // check for fpInputBlocks pointer done in FindInputBlock
1392 iSpec=fpInputBlocks[idx].fSpecification;
1393 }
1394 return iSpec;
1395}
1396
ebdd604d 1397int AliHLTComponent::PushBack(const TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
79c114b5 1398 void* pHeader, int headerSize)
a655eae3 1399{
1400 // see header file for function documentation
90ebac25 1401 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1402 int iResult=0;
b3f4766b 1403 fLastObjectSize=0;
9d4d4b02 1404 if (fPushbackPeriod>0) {
1405 // suppress the output
1406 TDatime time;
1407 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1408 }
a655eae3 1409 if (pObject) {
1410 AliHLTMessage msg(kMESS_OBJECT);
9ace7282 1411 msg.SetCompressionLevel(fCompressionLevel);
a655eae3 1412 msg.WriteObject(pObject);
1413 Int_t iMsgLength=msg.Length();
1414 if (iMsgLength>0) {
9ace7282 1415 // Matthias Sep 2008
1416 // NOTE: AliHLTMessage does implement it's own SetLength method
1417 // which is not architecture independent. The original SetLength
1418 // stores the size always in network byte order.
1419 // I'm trying to remember the rational for that, might be that
1420 // it was just some lack of knowledge. Want to change this, but
1421 // has to be done carefullt to be backward compatible.
a655eae3 1422 msg.SetLength(); // sets the length to the first (reserved) word
9ace7282 1423
1424 // does nothing if the level is 0
1425 msg.Compress();
1426
1427 char *mbuf = msg.Buffer();
1428 if (msg.CompBuffer()) {
1429 msg.SetLength(); // set once more to have to byte order
1430 mbuf = msg.CompBuffer();
1431 iMsgLength = msg.CompLength();
1432 }
1433 assert(mbuf!=NULL);
1434 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1435 if (iResult>=0) {
9ace7282 1436 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
a655eae3 1437 }
b3f4766b 1438 fLastObjectSize=iMsgLength;
a655eae3 1439 } else {
1440 HLTError("object serialization failed for object %p", pObject);
1441 iResult=-ENOMSG;
1442 }
1443 } else {
1444 iResult=-EINVAL;
1445 }
1446 return iResult;
1447}
1448
ebdd604d 1449int AliHLTComponent::PushBack(const TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
79c114b5 1450 void* pHeader, int headerSize)
a655eae3 1451{
1452 // see header file for function documentation
90ebac25 1453 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1454 AliHLTComponentDataType dt;
1455 SetDataType(dt, dtID, dtOrigin);
79c114b5 1456 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1457}
1458
438635e3 1459int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1460 const void* pHeader, int headerSize)
a655eae3 1461{
1462 // see header file for function documentation
90ebac25 1463 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d4d4b02 1464 if (fPushbackPeriod>0) {
1465 // suppress the output
1466 TDatime time;
1467 if (fLastPushBackTime<0 || (int)time.Get()-fLastPushBackTime<fPushbackPeriod) return 0;
1468 }
1469
9d9ffd37 1470 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1471}
1472
438635e3 1473int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1474 const void* pHeader, int headerSize)
a655eae3 1475{
1476 // see header file for function documentation
90ebac25 1477 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1478 AliHLTComponentDataType dt;
1479 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1480 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1481}
1482
438635e3 1483int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1484 const void* pHeader, int iHeaderSize)
a655eae3 1485{
1486 // see header file for function documentation
1487 int iResult=0;
79c114b5 1488 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1489
1490 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1491 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1492 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1493
1494 // copy header if provided but skip if the header is the target location
1495 // in that case it has already been copied
79c114b5 1496 if (pHeader!=NULL && pHeader!=pTgt) {
1497 memcpy(pTgt, pHeader, iHeaderSize);
1498 }
1499
1500 pTgt += (AliHLTUInt8_t) iHeaderSize;
1501
438635e3 1502 // copy buffer if provided but skip if buffer is the target location
1503 // in that case it has already been copied
a655eae3 1504 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1505 memcpy(pTgt, pBuffer, iBufferSize);
1506
4b98eadb 1507 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1508 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1509 }
79c114b5 1510 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1511 } else {
1512 if (fpOutputBuffer) {
b3f4766b 1513 HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
a655eae3 1514 } else {
1515 HLTError("output buffer not available");
1516 }
1517 iResult=-ENOSPC;
1518 }
a655eae3 1519 }
438635e3 1520 if (iResult>=0) {
1521 AliHLTComponentBlockData bd;
1522 FillBlockData( bd );
1523 bd.fOffset = fOutputBufferFilled;
1524 bd.fSize = iBlkSize;
1525 bd.fDataType = dt;
1526 bd.fSpecification = spec;
1527 fOutputBlocks.push_back( bd );
1528 fOutputBufferFilled+=bd.fSize;
1529 }
1530
a655eae3 1531 return iResult;
1532}
1533
ebdd604d 1534int AliHLTComponent::EstimateObjectSize(const TObject* pObject) const
8451168b 1535{
66043029 1536 // see header file for function documentation
cc63ef09 1537 if (!pObject) return 0;
1538
1539 AliHLTMessage msg(kMESS_OBJECT);
1540 msg.WriteObject(pObject);
1541 return msg.Length();
8451168b 1542}
1543
79c114b5 1544AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1545 const char* dtOrigin,
1546 AliHLTUInt32_t spec)
1547{
1548 // see header file for function documentation
1549 ALIHLTCOMPONENT_BASE_STOPWATCH();
1550 AliHLTComponentDataType dt;
1551 SetDataType(dt, dtID, dtOrigin);
1552 return CreateMemoryFile(capacity, dt, spec);
1553}
1554
1555AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1556 const AliHLTComponentDataType& dt,
1557 AliHLTUInt32_t spec)
1558{
1559 // see header file for function documentation
1560 ALIHLTCOMPONENT_BASE_STOPWATCH();
1561 AliHLTMemoryFile* pFile=NULL;
83fec083 1562 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1563 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1564 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1565 if (pFile) {
83fec083 1566 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1567 if (nofBlocks+1>fMemFiles.size()) {
1568 fMemFiles.resize(nofBlocks+1, NULL);
1569 }
1570 if (nofBlocks<fMemFiles.size()) {
1571 fMemFiles[nofBlocks]=pFile;
1572 AliHLTComponentBlockData bd;
1573 FillBlockData( bd );
1574 bd.fOffset = fOutputBufferFilled;
79c114b5 1575 bd.fSize = capacity;
1576 bd.fDataType = dt;
1577 bd.fSpecification = spec;
1578 fOutputBufferFilled+=bd.fSize;
1579 fOutputBlocks.push_back( bd );
1580 } else {
1581 HLTError("can not allocate/grow object array");
29312178 1582 pFile->CloseMemoryFile(0);
79c114b5 1583 delete pFile;
1584 pFile=NULL;
1585 }
1586 }
1587 } else {
1588 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1589 }
1590 return pFile;
1591}
1592
1593AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1594 const char* dtOrigin,
1595 AliHLTUInt32_t spec,
1596 float capacity)
1597{
1598 // see header file for function documentation
1599 ALIHLTCOMPONENT_BASE_STOPWATCH();
1600 AliHLTComponentDataType dt;
1601 SetDataType(dt, dtID, dtOrigin);
1602 int size=fOutputBufferSize-fOutputBufferFilled;
1603 if (capacity<0 || capacity>1.0) {
1604 HLTError("invalid parameter: capacity %f", capacity);
1605 return NULL;
1606 }
1607 size=(int)(size*capacity);
1608 return CreateMemoryFile(size, dt, spec);
1609}
1610
1611AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1612 AliHLTUInt32_t spec,
1613 float capacity)
1614{
1615 // see header file for function documentation
1616 ALIHLTCOMPONENT_BASE_STOPWATCH();
1617 int size=fOutputBufferSize-fOutputBufferFilled;
1618 if (capacity<0 || capacity>1.0) {
1619 HLTError("invalid parameter: capacity %f", capacity);
1620 return NULL;
1621 }
1622 size=(int)(size*capacity);
1623 return CreateMemoryFile(size, dt, spec);
1624}
1625
1626int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1627 const char* key, int option)
1628{
3a7c0444 1629 // see header file for function documentation
79c114b5 1630 int iResult=0;
1631 if (pFile && pObject) {
1632 pFile->cd();
1633 iResult=pObject->Write(key, option);
1634 if (iResult>0) {
1635 // success
1636 } else {
1637 iResult=-pFile->GetErrno();
1638 if (iResult==-ENOSPC) {
1639 HLTError("error writing memory file, buffer too small");
1640 }
1641 }
1642 } else {
1643 iResult=-EINVAL;
1644 }
1645 return iResult;
1646}
1647
1648int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1649{
3a7c0444 1650 // see header file for function documentation
79c114b5 1651 int iResult=0;
1652 if (pFile) {
2be3f004 1653 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1654 int i=0;
1655 while (element!=fMemFiles.end() && iResult>=0) {
1656 if (*element && *element==pFile) {
29312178 1657 iResult=pFile->CloseMemoryFile();
79c114b5 1658
1659 // sync memory files and descriptors
1660 if (iResult>=0) {
1661 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1662 }
1663 delete *element;
1664 *element=NULL;
1665 return iResult;
1666 }
1667 element++; i++;
1668 }
1669 HLTError("can not find memory file %p", pFile);
1670 iResult=-ENOENT;
1671 } else {
1672 iResult=-EINVAL;
1673 }
1674 return iResult;
1675}
1676
eafbc306 1677int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1678{
1679 // see header file for function documentation
eafbc306 1680 int iResult=0;
1681
1682 AliHLTComponentEventDoneData* newEDD = NULL;
1683
1684 unsigned long newSize=edd.fDataSize;
1685 if (fEventDoneData)
1686 newSize += fEventDoneData->fDataSize;
1687
1688 if (newSize>fEventDoneDataSize) {
1689 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1690 if (!newEDD)
1691 return -ENOMEM;
1692 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1693 newEDD->fDataSize = newSize;
1694 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1695 unsigned long long offset = 0;
1696 if (fEventDoneData) {
1697 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1698 offset += fEventDoneData->fDataSize;
1699 }
1700 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1701 if (fEventDoneData)
1702 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1703 fEventDoneData = newEDD;
1704 fEventDoneDataSize = newSize;
1705 }
bd2a51b0 1706 else if (fEventDoneData) {
eafbc306 1707 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1708 fEventDoneData->fDataSize += edd.fDataSize;
1709 }
bd2a51b0 1710 else {
1711 HLTError("internal mismatch, fEventDoneData=%d but buffer is NULL", fEventDoneDataSize);
1712 iResult=-EFAULT;
1713 }
a655eae3 1714 return iResult;
1715}
1716
0622a0f3 1717namespace
1718{
1719 // helper function for std:sort, implements an operator<
1720 bool SortComponentStatisticsById(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1721 {
1722 return a.fId<b.fId;
1723 }
1724
1725 // helper function for std:sort
1726 bool SortComponentStatisticsDescendingByLevel(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1727 {
1728 return a.fId>b.fId;
1729 }
1730
1731 // helper class to define operator== between AliHLTComponentStatistics and AliHLTComponentStatistics.fId
1732 class AliHLTComponentStatisticsId {
1733 public:
1734 AliHLTComponentStatisticsId(AliHLTUInt32_t id) : fId(id) {}
f308715b 1735 AliHLTComponentStatisticsId(const AliHLTComponentStatisticsId& src) : fId(src.fId) {}
0622a0f3 1736 bool operator==(const AliHLTComponentStatistics& a) const {return a.fId==fId;}
1737 private:
1738 AliHLTComponentStatisticsId();
0622a0f3 1739 AliHLTUInt32_t fId;
1740 };
1741
1742 // operator for std::find of AliHLTComponentStatistics by id
1743 bool operator==(const AliHLTComponentStatistics& a, const AliHLTComponentStatisticsId& b)
1744 {
1745 return b==a;
1746 }
1747
1748 bool AliHLTComponentStatisticsCompareIds(const AliHLTComponentStatistics& a, const AliHLTComponentStatistics& b)
1749 {
1750 return a.fId==b.fId;
1751 }
1752
1753 // helper class to define operator== between AliHLTComponentBlockData and AliHLTComponentBlockData.fSpecification
1754 class AliHLTComponentBlockDataSpecification {
1755 public:
1756 AliHLTComponentBlockDataSpecification(AliHLTUInt32_t specification) : fSpecification(specification) {}
f308715b 1757 AliHLTComponentBlockDataSpecification(const AliHLTComponentBlockDataSpecification& src) : fSpecification(src.fSpecification) {}
0622a0f3 1758 bool operator==(const AliHLTComponentBlockData& bd) const {return bd.fSpecification==fSpecification;}
1759 private:
1760 AliHLTComponentBlockDataSpecification();
0622a0f3 1761 AliHLTUInt32_t fSpecification;
1762 };
1763
1764 // operator for std::find of AliHLTComponentBlockData by specification
1765 bool operator==(const AliHLTComponentBlockData& bd, const AliHLTComponentBlockDataSpecification& spec)
1766 {
1767 return spec==bd;
1768 }
1769
1770 // operator for std::find
1771 bool operator==(const AliHLTComponentBlockData& a, const AliHLTComponentBlockData& b)
1772 {
1773 if (!MatchExactly(a.fDataType,b.fDataType)) return false;
1774 return a.fSpecification==b.fSpecification;
1775 }
1776
1777} // end of namespace
1778
3cde846d 1779int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1780 const AliHLTComponentBlockData* blocks,
1781 AliHLTComponentTriggerData& trigData,
1782 AliHLTUInt8_t* outputPtr,
1783 AliHLTUInt32_t& size,
1784 AliHLTUInt32_t& outputBlockCnt,
1785 AliHLTComponentBlockData*& outputBlocks,
1786 AliHLTComponentEventDoneData*& edd )
1787{
70ed7d01 1788 // see header file for function documentation
66108417 1789 HLTLogKeyword(fChainId.c_str());
90ebac25 1790 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1791 int iResult=0;
1792 fCurrentEvent=evtData.fEventID;
a655eae3 1793 fCurrentEventData=evtData;
1794 fpInputBlocks=blocks;
1795 fCurrentInputBlock=-1;
1796 fSearchDataType=kAliHLTAnyDataType;
1797 fpOutputBuffer=outputPtr;
1798 fOutputBufferSize=size;
1799 fOutputBufferFilled=0;
1800 fOutputBlocks.clear();
96f9673a 1801 outputBlockCnt=0;
1802 outputBlocks=NULL;
438635e3 1803
1804 AliHLTComponentBlockDataList forwardedBlocks;
1805
1806 // optional component statistics
a0aeb701 1807 AliHLTComponentStatisticsList compStats;
438635e3 1808 bool bAddComponentTableEntry=false;
abb52c8f 1809 vector<AliHLTUInt32_t> parentComponentTables;
0622a0f3 1810 int processingLevel=-1;
78d29060 1811#if defined(HLT_COMPONENT_STATISTICS)
1812 if ((fFlags&kDisableComponentStat)==0) {
1813 AliHLTComponentStatistics outputStat;
1814 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
1815 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
1816 outputStat.fId=fChainIdCrc;
1817 if (fpBenchmark) {
1818 fpBenchmark->Stop();
1819 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1820 fpBenchmark->Reset();
1821 fpBenchmark->Start();
1822 }
1823 compStats.push_back(outputStat);
a0aeb701 1824 }
78d29060 1825#endif // HLT_COMPONENT_STATISTICS
559631d5 1826
48abe484 1827 // data processing is skipped
1828 // - if there are only steering events in the block list.
1829 // For the sake of data source components data processing
1830 // is not skipped if there is no block list at all or if it
1831 // just contains the eventType block
1832 // - always skipped if the event is of type
1833 // - gkAliEventTypeConfiguration
1834 // - gkAliEventTypeReadPreprocessor
45c0a780 1835 const unsigned int skipModeDefault=0x1;
1836 const unsigned int skipModeForce=0x2;
1837 unsigned int bSkipDataProcessing=skipModeDefault;
1838
559631d5 1839 // find special events
45c0a780 1840 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1841 // first look for all special events and execute in the appropriate
1842 // sequence afterwords
1843 int indexComConfEvent=-1;
b543e186 1844 int indexUpdtDCSEvent=-1;
579d9eb7 1845 int indexSOREvent=-1;
1846 int indexEOREvent=-1;
cf9cf07e 1847 int indexECSParamBlock=-1;
83fec083 1848 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1849 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1850 indexSOREvent=i;
45c0a780 1851 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1852 bSkipDataProcessing&=~skipModeDefault;
1853 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1854 // run type string
1855 // handling is not clear yet
1856 if (fpInputBlocks[i].fPtr) {
1857 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1858 }
579d9eb7 1859 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1860 indexEOREvent=i;
45c0a780 1861 // the calibration processor relies on the SOR and EOR events
1862 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1863 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1864 // DDL list
1865 // this event is most likely deprecated
1866 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1867 indexComConfEvent=i;
b543e186 1868 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1869 indexUpdtDCSEvent=i;
1870 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1871 fEventType=fpInputBlocks[i].fSpecification;
9e14734f 1872 if (fEventType != gkAliEventTypeConfiguration and
1873 fEventType != gkAliEventTypeReadPreprocessor
1874 )
1875 {
1876 // We can actually get the event type from the CDH if it is valid.
1877 // Otherwise just use the specification of the input block.
1878 const AliRawDataHeader* cdh;
1879 if (ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) == 0)
1880 {
1881 fEventType = ExtractEventTypeFromCDH(cdh);
1882 }
1883 }
48abe484 1884
1885 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1886 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1887
1888 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1889 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1890
1891 // never skip if the event type block is the only block
1892 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1893
a0aeb701 1894 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1895 if (compStats.size()>0) {
1896 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1897 for (AliHLTUInt32_t offset=0;
1898 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1899 offset+=sizeof(AliHLTComponentStatistics)) {
1900 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1901 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1902 compStats[0].fLevel=pStat->fLevel+1;
1903 }
0622a0f3 1904 if (find(compStats.begin(), compStats.end(), AliHLTComponentStatisticsId(pStat->fId))==compStats.end()) {
1905 compStats.push_back(*pStat);
1906 }
a0aeb701 1907 }
1908 }
438635e3 1909 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
0622a0f3 1910 AliHLTComponentBlockDataList::iterator element=forwardedBlocks.begin();
1911 while ((element=find(element, forwardedBlocks.end(), AliHLTComponentBlockDataSpecification(fpInputBlocks[i].fSpecification)))!=forwardedBlocks.end()) {
1912 if (element->fDataType==fpInputBlocks[i].fDataType) break;
1913 // TODO: think about some more checks inclusing also the actual data buffers
1914 // this has to handle multiplicity>1 in the online system, where all components
1915 // send the information on SOR, because this event is broadcasted
1916 }
1917 if (element==forwardedBlocks.end()) {
1918 forwardedBlocks.push_back(fpInputBlocks[i]);
1919 }
abb52c8f 1920 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
0622a0f3 1921 if (fpInputBlocks[i].fSize>=sizeof(AliHLTComponentTableEntry)) {
1922 const AliHLTComponentTableEntry* entry=reinterpret_cast<AliHLTComponentTableEntry*>(fpInputBlocks[i].fPtr);
1923 if (entry->fStructSize==sizeof(AliHLTComponentTableEntry)) {
1924 if (processingLevel<0 || processingLevel<=(int)entry->fLevel)
1925 processingLevel=entry->fLevel+1;
1926 }
1927 }
cf9cf07e 1928 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeECSParam) {
1929 indexECSParamBlock=i;
45c0a780 1930 } else {
1931 // the processing function is called if there is at least one
1932 // non-steering data block. Steering blocks are not filtered out
1933 // for sake of performance
1934 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1935 if (compStats.size()>0) {
1936 compStats[0].fInputBlockCount++;
1937 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1938 }
579d9eb7 1939 }
1940 }
45c0a780 1941
579d9eb7 1942 if (indexSOREvent>=0) {
1943 // start of run
438635e3 1944 bAddComponentTableEntry=true;
0622a0f3 1945 compStats.clear(); // no component statistics for SOR
579d9eb7 1946 if (fpRunDesc==NULL) {
1947 fpRunDesc=new AliHLTRunDesc;
48abe484 1948 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1949 }
1950 if (fpRunDesc) {
1951 AliHLTRunDesc rundesc;
1952 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1953 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1954 *fpRunDesc=rundesc;
579d9eb7 1955 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1956 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1957 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1958 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1959 }
559631d5 1960 }
579d9eb7 1961 } else {
45c0a780 1962 iResult=-ENOMEM;
579d9eb7 1963 }
cf9cf07e 1964
1965 if (indexECSParamBlock>=0) {
1966 if (fpInputBlocks[indexECSParamBlock].fSize>0) {
1967 const char* param=reinterpret_cast<const char*>(fpInputBlocks[indexECSParamBlock].fPtr);
1968 TString paramString;
1969 if (param[fpInputBlocks[indexECSParamBlock].fSize-1]!=0) {
1970 HLTWarning("ECS parameter string not terminated");
1971 paramString.Insert(0, param, fpInputBlocks[indexECSParamBlock].fSize);
1972 paramString+="";
1973 } else {
1974 paramString=param;
1975 }
1976 ScanECSParam(paramString.Data());
1977 } else {
1978 HLTWarning("empty ECS parameter received");
1979 }
1980 } else {
1981 // TODO: later on we might throw a warning here since the CTP trigger classes
1982 // should be mandatory
1983 }
579d9eb7 1984 }
1985 if (indexEOREvent>=0) {
9d4d4b02 1986 fLastPushBackTime=0; // always send at EOR
438635e3 1987 bAddComponentTableEntry=true;
0622a0f3 1988 compStats.clear(); // no component statistics for EOR
579d9eb7 1989 if (fpRunDesc!=NULL) {
1990 if (fpRunDesc) {
1991 AliHLTRunDesc rundesc;
1992 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1993 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1994 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1995 } else {
1996 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1997 }
559631d5 1998 }
bee8f777 1999 // we do not unload the fpRunDesc struct here in order to have the run information
2000 // available during the event processing
2001 // https://savannah.cern.ch/bugs/?39711
2002 // the info will be cleared in DeInit
559631d5 2003 }
579d9eb7 2004 } else {
2005 HLTWarning("did not receive SOR, ignoring EOR");
2006 }
2007 }
76390ea0 2008 if (fEventType==gkAliEventTypeConfiguration) {
2009 if (indexComConfEvent>=0) {
579d9eb7 2010 TString cdbEntry;
b543e186 2011 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 2012 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
2013 }
2014 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
2015 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
2016 if (tmpResult<0) {
2017 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 2018 }
76390ea0 2019 } else {
2020 ALIHLTERRORGUARD(1, "incomplete Configure event, missing parameter data block");
2021 }
559631d5 2022 }
76390ea0 2023 if (fEventType==gkAliEventTypeReadPreprocessor) {
2024 if (indexUpdtDCSEvent>=0) {
b543e186 2025 TString modules;
4b30799e 2026 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
b543e186 2027 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
2028 }
d6b69874 2029 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
2030 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 2031 if (tmpResult<0) {
2032 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
2033 }
76390ea0 2034 } else {
2035 ALIHLTERRORGUARD(1, "incomplete ReadPreprocessor event, missing parameter data block");
2036 }
b543e186 2037 }
45c0a780 2038 } else {
2039 // processing function needs to be called if there are no input data
2040 // blocks in order to make data source components working.
2041 bSkipDataProcessing&=~skipModeDefault;
559631d5 2042 }
a0aeb701 2043
2044 // data processing is not skipped if the component explicitly asks
2045 // for the private blocks
78d29060 2046 if ((fFlags&kRequireSteeringBlocks)!=0) bSkipDataProcessing=0;
a0aeb701 2047
0622a0f3 2048 // data processing is not skipped for data sources
2049 if (GetComponentType()==AliHLTComponent::kSource) bSkipDataProcessing=0;
2050
edd72347 2051 if (fpCTPData) {
2052 // set the active triggers for this event
2053 fpCTPData->SetTriggers(trigData);
2054 // increment CTP trigger counters if available
2055 if (IsDataEvent()) fpCTPData->Increment(trigData);
2056 }
adb91bc3 2057
2be3f004 2058 AliHLTComponentBlockDataList blockData;
45c0a780 2059 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 2060 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 2061 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
2062 // in order to avoid 'shadowed variable' warning
2063 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
d906c8d9 2064 AliHLTMisc::AliOnlineGuard onlineGuard;
90ebac25 2065 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
2066 } // end of the scope of the stopwatch guard
b543e186 2067 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 2068 if (fOutputBlocks.size()>0) {
df61f928 2069 // High Level interface
2070
2071 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 2072 // sync memory files and descriptors
2be3f004 2073 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 2074 int i=0;
2075 while (element!=fMemFiles.end() && iResult>=0) {
2076 if (*element) {
2077 if ((*element)->IsClosed()==0) {
2078 HLTWarning("memory file has not been closed, force flush");
2079 iResult=CloseMemoryFile(*element);
2080 }
2081 }
2082 element++; i++;
2083 }
2084
2085 if (iResult>=0) {
2086 // create the descriptor list
2087 if (blockData.size()>0) {
2088 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
2089 iResult=-EFAULT;
2090 } else {
abb52c8f 2091 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 2092 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
2093 if (offset>0) fOutputBufferFilled+=offset;
2094 }
438635e3 2095 if (bAddComponentTableEntry) {
0622a0f3 2096 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables, processingLevel);
438635e3 2097 if (offset>0) size+=offset;
2098 }
2099 if (forwardedBlocks.size()>0) {
2100 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2101 }
79c114b5 2102 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
2103 size=fOutputBufferFilled;
2104 }
a655eae3 2105 }
2106 } else {
df61f928 2107 // Low Level interface
0622a0f3 2108 if (blockData.empty() && size!=0) {
2109 // set the size to zero because there is no announced data
2110 //HLTWarning("no output blocks added by component but output buffer filled %d of %d", size, fOutputBufferSize);
2111 size=0;
2112 }
2113
a0aeb701 2114 if (compStats.size()>0) {
2115 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
2116 if (offset>0) size+=offset;
2117 }
438635e3 2118 if (bAddComponentTableEntry) {
0622a0f3 2119 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables, processingLevel);
438635e3 2120 if (offset>0) size+=offset;
2121 }
2122 if (forwardedBlocks.size()>0) {
2123 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
2124 }
a655eae3 2125 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
2126 }
2127 if (iResult<0) {
2128 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
2129 }
2130 }
b543e186 2131 if (iResult<0 || bSkipDataProcessing) {
a655eae3 2132 outputBlockCnt=0;
2133 outputBlocks=NULL;
2134 }
8451168b 2135 CleanupInputObjects();
48abe484 2136 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 2137 IncrementEventCounter();
2138 }
96f9673a 2139 if (outputBlockCnt==0) {
2140 // no output blocks, set size to 0
2141 size=0;
2142 }
6f4231a1 2143
2144 // reset the internal EventData struct
4646c6e3 2145 FillEventData(fCurrentEventData);
edd72347 2146
2147 // reset the active triggers
2148 if (fpCTPData) fpCTPData->SetTriggers(0);
9d4d4b02 2149
2150 // set the time for the pushback period
2151 if (fPushbackPeriod>0) {
2152 // suppress the output
2153 TDatime time;
ebdd604d 2154 if (fLastPushBackTime<0) {
2155 // choose a random offset at beginning to equalize traffic for multiple instances
2156 // of the component
2157 gRandom->SetSeed(fChainIdCrc);
2158 fLastPushBackTime=time.Get();
2159 fLastPushBackTime-=gRandom->Integer(fPushbackPeriod);
2160 } else if ((int)time.Get()-fLastPushBackTime>=fPushbackPeriod) {
9d4d4b02 2161 fLastPushBackTime=time.Get();
2162 }
2163 }
2164
3cde846d 2165 return iResult;
2166}
a655eae3 2167
a0aeb701 2168int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
2169 AliHLTUInt8_t* buffer,
2170 AliHLTUInt32_t bufferSize,
2171 AliHLTUInt32_t offset,
2172 AliHLTComponentStatisticsList& stats) const
2173{
2174 // see header file for function documentation
2175 int iResult=0;
78d29060 2176 if ((fFlags&kDisableComponentStat)!=0) return 0;
2177#if defined(HLT_COMPONENT_STATISTICS)
a0aeb701 2178 if (stats.size()==0) return -ENOENT;
ae962989 2179 // check if there is space for at least one entry
2180 if (offset+sizeof(AliHLTComponentStatistics)>bufferSize) return 0;
a0aeb701 2181 stats[0].fTotalOutputSize=offset;
2182 stats[0].fOutputBlockCount=blocks.size();
2183 if (fpBenchmark) {
2e3fd14f 2184 fpBenchmark->Stop();
2185 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2186 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
2187 fpBenchmark->Continue();
a0aeb701 2188 }
0622a0f3 2189
2190 sort(stats.begin(), stats.end(), SortComponentStatisticsDescendingByLevel);
2191
2192 // shrink the number of entries if the buffer is too small
ae962989 2193 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize) {
0622a0f3 2194 unsigned originalSize=stats.size();
ae962989 2195 AliHLTUInt32_t removedLevel=0;
2196 do {
2197 // remove all entries of the level of the last entry
2198 removedLevel=stats.back().fLevel;
2199 AliHLTComponentStatisticsList::iterator element=stats.begin();
2200 element++;
2201 while (element!=stats.end()) {
2202 if (element->fLevel<=removedLevel) {
2203 element=stats.erase(element);
2204 } else {
2205 element++;
2206 }
2207 }
2208 } while (stats.size()>1 &&
2209 (offset+stats.size()*sizeof(AliHLTComponentStatistics)>bufferSize));
0622a0f3 2210 HLTWarning("too little space in output buffer to add block of %d statistics entries (size %d), available %d, removed %d entries",
2211 originalSize, sizeof(AliHLTComponentStatistics), bufferSize-offset, originalSize-stats.size());
2212 } else {
2213 HLTDebug("adding block of %d statistics entries", stats.size());
ae962989 2214 }
2215 assert(stats.size()>0);
2216 if (stats.size()==0) return 0;
2217
a0aeb701 2218 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
2219 AliHLTComponentBlockData bd;
2220 FillBlockData( bd );
2221 bd.fOffset = offset;
2222 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
2223 bd.fDataType = kAliHLTDataTypeComponentStatistics;
0622a0f3 2224 bd.fSpecification = fChainIdCrc;
a0aeb701 2225 memcpy(buffer+offset, &(stats[0]), bd.fSize);
2226 blocks.push_back(bd);
2227 iResult=bd.fSize;
2228 }
bd6cac58 2229#else
2230 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
2231 // get rid of warning
2232 }
78d29060 2233#endif // HLT_COMPONENT_STATISTICS
438635e3 2234 return iResult;
2235}
2236
2237int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
2238 AliHLTUInt8_t* buffer,
2239 AliHLTUInt32_t bufferSize,
abb52c8f 2240 AliHLTUInt32_t offset,
0622a0f3 2241 const vector<AliHLTUInt32_t>& parents,
2242 int processingLevel) const
438635e3 2243{
2244 // see header file for function documentation
2245 int iResult=0;
78d29060 2246 if ((fFlags&kDisableComponentStat)!=0) return 0;
2247#if defined(HLT_COMPONENT_STATISTICS)
abb52c8f 2248 // the payload consists of the AliHLTComponentTableEntry struct,
2249 // followed by a an array of 32bit crc chain ids and the component
2250 // description string
2251 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
2252 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
2253
2254 // the component description has the following format:
2255 // chain-id{component-id:arguments}
2256 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
2257 unsigned int descriptionSize=fChainId.size()+1;
2258 descriptionSize+=2; // the '{}' around the component id
2259 descriptionSize+=strlen(componentId);
2260 descriptionSize+=1; // the ':' between component id and arguments
2261 descriptionSize+=fComponentArgs.size();
2262
2263 payloadSize+=descriptionSize;
2264 if (buffer && (offset+payloadSize<=bufferSize)) {
2265 AliHLTUInt8_t* pTgt=buffer+offset;
2266 memset(pTgt, 0, payloadSize);
2267
2268 // write entry
2269 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
2270 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
0622a0f3 2271 pEntry->fLevel=processingLevel>=0?processingLevel:0;
abb52c8f 2272 pEntry->fNofParents=parents.size();
2273 pEntry->fSizeDescription=descriptionSize;
2274 pTgt=pEntry->fBuffer;
2275
2276 // write array of parents
2277 if (parents.size()>0) {
2278 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
2279 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
2280 pTgt+=copy;
2281 }
2282
2283 // write component description
2284 memcpy(pTgt, fChainId.c_str(), fChainId.size());
2285 pTgt+=fChainId.size();
2286 *pTgt++='{';
2287 memcpy(pTgt, componentId, strlen(componentId));
2288 pTgt+=strlen(componentId);
2289 *pTgt++=':';
2290 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
2291 pTgt+=fComponentArgs.size();
2292 *pTgt++='}';
2293 *pTgt++=0;
2294
438635e3 2295 AliHLTComponentBlockData bd;
2296 FillBlockData( bd );
2297 bd.fOffset = offset;
abb52c8f 2298 bd.fSize = payloadSize;
438635e3 2299 bd.fDataType = kAliHLTDataTypeComponentTable;
2300 bd.fSpecification = fChainIdCrc;
438635e3 2301 blocks.push_back(bd);
2302 iResult=bd.fSize;
2303 }
bd6cac58 2304#else
0622a0f3 2305 if (blocks.size() && buffer && bufferSize && offset && parents.size() && processingLevel) {
bd6cac58 2306 // get rid of warning
2307 }
78d29060 2308#endif // HLT_COMPONENT_STATISTICS
a0aeb701 2309 return iResult;
2310}
2311
90ebac25 2312AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
2313 :
2314 fpStopwatch(NULL),
2315 fpPrec(NULL)
2316{
2317 // standard constructor (not for use)
2318}
2319
2320AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
2321 :
2322 fpStopwatch(pStopwatch),
2323 fpPrec(NULL)
2324{
2325 // constructor
2326
2327 // check for already existing guard
2328 if (fgpCurrent) fpPrec=fgpCurrent;
2329 fgpCurrent=this;
2330
2331 // stop the preceeding guard if it controls a different stopwatch
2332 int bStart=1;
2333 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
2334
2335 // start the stopwatch if the current guard controls a different one
2336 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
2337}
2338
e419b223 2339AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 2340 :
2341 fpStopwatch(NULL),
2342 fpPrec(NULL)
2343{
e419b223 2344 //
2345 // copy constructor not for use
2346 //
2347}
2348
2349AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
2350{
2351 //
2352 // assignment operator not for use
2353 //
2354 fpStopwatch=NULL;
2355 fpPrec=NULL;
2356 return *this;
90ebac25 2357}
2358
2359AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
2360
2361AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
2362{
2363 // destructor
2364
2365 // resume the preceeding guard if it controls a different stopwatch
2366 int bStop=1;
2367 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
2368
2369 // stop the stopwatch if the current guard controls a different one
2370 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
2371
2372 // resume to the preceeding guard
2373 fgpCurrent=fpPrec;
2374}
2375
0007ed52 2376int AliHLTComponent::AliHLTStopwatchGuard::Hold(const TStopwatch* pSucc)
90ebac25 2377{
2378 // see header file for function documentation
2379 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
2380 return fpStopwatch!=pSucc?1:0;
2381}
2382
0007ed52 2383int AliHLTComponent::AliHLTStopwatchGuard::Resume(const TStopwatch* pSucc)
90ebac25 2384{
2385 // see header file for function documentation
2386 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
2387 return fpStopwatch!=pSucc?1:0;
2388}
2389
2390int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
2391{
2392 // see header file for function documentation
2393 int iResult=0;
2394 if (pSW!=NULL && type<kSWTypeCount) {
2395 if (fpStopwatches) {
2396 TObject* pObj=fpStopwatches->At((int)type);
2397 if (pSW==NULL // explicit reset
2398 || pObj==NULL) { // explicit set
2399 fpStopwatches->AddAt(pSW, (int)type);
2400 } else if (pObj!=pSW) {
2401 HLTWarning("stopwatch %d already set, reset first", (int)type);
2402 iResult=-EBUSY;
2403 }
2404 }
2405 } else {
2406 iResult=-EINVAL;
2407 }
2408 return iResult;
2409}
2410
2411int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
2412{
2413 // see header file for function documentation
2414 if (pStopwatches==NULL) return -EINVAL;
2415
2416 int iResult=0;
77fd699f 2417 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntriesFast(); i++)
90ebac25 2418 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
2419 return iResult;
2420}
559631d5 2421
2422AliHLTUInt32_t AliHLTComponent::GetRunNo() const
2423{
29312178 2424 // see header file for function documentation
6e289790 2425
2426 // 2010-02-11 OCDB is now the reliable source for the run number, it is
2427 // initialized either by aliroot or the external interface depending
2428 // on the environment. It turned out that the rundescriptor is not set
2429 // in the aliroot mode, resulting in an invalid run number. However this
2430 // did not cause problems until now. OCDB initialization has been revised
2431 // already in 10/2009. This was a remnant.
2432 // Have to check whether we get rid of the rundescriptor at some point.
2433 if (fpRunDesc==NULL) return AliHLTMisc::Instance().GetCDBRunNo();
2434 if (fpRunDesc->fRunNo!=(unsigned)AliHLTMisc::Instance().GetCDBRunNo()) {
2435 HLTWarning("run number mismatch: ocdb %d run descriptor %d", AliHLTMisc::Instance().GetCDBRunNo(), fpRunDesc->fRunNo);
2436 }
559631d5 2437 return fpRunDesc->fRunNo;
2438}
2439
2440AliHLTUInt32_t AliHLTComponent::GetRunType() const
2441{
29312178 2442 // see header file for function documentation
45c0a780 2443 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 2444 return fpRunDesc->fRunType;
2445}
2446
6700298e 2447AliHLTUInt32_t AliHLTComponent::GetTimeStamp() const
2448{
2449 // see header file for function documentation
bee8f777 2450 if (fCurrentEventData.fEventCreation_s) {
2451 return fCurrentEventData.fEventCreation_s;
2452 }
2453 // using the actual UTC if the time stamp was not set by the framework
2454 return static_cast<AliHLTUInt32_t>(time(NULL));
6700298e 2455}
2456
2457AliHLTUInt32_t AliHLTComponent::GetPeriodNumber() const
2458{
2459 // see header file for function documentation
2460 return (GetEventId()>>36)&0xfffffff;
2461}
2462
2463AliHLTUInt32_t AliHLTComponent::GetOrbitNumber() const
2464{
2465 // see header file for function documentation
2466 return (GetEventId()>>12)&0xffffff;
2467}
2468
2469AliHLTUInt16_t AliHLTComponent::GetBunchCrossNumber() const
2470{
2471 // see header file for function documentation
2472 return GetEventId()&0xfff;
2473}
2474
0007ed52 2475bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt) const
48abe484 2476{
2477 // see header file for function documentation
2478 if (pTgt) *pTgt=fEventType;
2479 return (fEventType==gkAliEventTypeData ||
9e14734f 2480 fEventType==gkAliEventTypeDataReplay);
48abe484 2481}
2482
83fec083 2483int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 2484 const char* structname, const char* eventname)
2485{
29312178 2486 // see header file for function documentation
559631d5 2487 int iResult=0;
2488 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
2489 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
2490 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
2491 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 2492 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 2493 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 2494 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 2495 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
2496 }
2497 if (copy!=iStructSize) {
c5123824 2498 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 2499 if (copy>iStructSize) {
2500 copy=iStructSize;
2501 } else {
2502 memset(pTgt, 0, iStructSize);
2503 }
2504 }
3294f81a 2505 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 2506 *pTgt=iStructSize;
2507 iResult=copy;
2508 } else {
2509 HLTWarning("%s event: missing data block", eventname);
2510 }
2511 } else {
2512 iResult=-ENODATA;
2513 }
2514 } else {
2515 HLTError("invalid struct");
2516 iResult=-EINVAL;
2517 }
2518 return iResult;
2519}
ed504011 2520
48abe484 2521AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2522{
2523 // see header file for function documentation
2524 AliHLTUInt32_t remainder = 0;
2525 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2526 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2527 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2528
2529 // code from
2530 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2531
2532 /*
2533 * Perform modulo-2 division, a byte at a time.
2534 */
2535 for (int byte = 0; byte < size; ++byte)
2536 {
2537 /*
2538 * Bring the next byte into the remainder.
2539 */
2540 remainder ^= (buffer[byte] << (crcwidth - 8));
2541
2542 /*
2543 * Perform modulo-2 division, a bit at a time.
2544 */
2545 for (uint8_t bit = 8; bit > 0; --bit)
2546 {
2547 /*
2548 * Try to divide the current data bit.
2549 */
2550 if (remainder & topbit)
2551 {
2552 remainder = (remainder << 1) ^ polynomial;
2553 }
2554 else
2555 {
2556 remainder = (remainder << 1);
2557 }
2558 }
2559 }
2560
2561 /*
2562 * The final remainder is the CRC result.
2563 */
2564 return (remainder);
2565}
abb52c8f 2566
2567int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2568 string& retChainId, string& retCompId, string& retCompArgs,
0622a0f3 2569 vector<AliHLTUInt32_t>& parents, int& level)
abb52c8f 2570{
2571 // see header file for function documentation
2572 retChainId.clear();
2573 retCompId.clear();
2574 retCompArgs.clear();
2575 parents.clear();
0622a0f3 2576 level=-1;
abb52c8f 2577 if (!pBuffer || size==0) return 0;
2578
2579 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2580 if (size<8/* the initial size of the structure*/ ||
2581 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
0622a0f3 2582
2583 if (pEntry->fStructSize!=sizeof(AliHLTComponentTableEntry)) return -EBADF;
2584 level=pEntry->fLevel;
abb52c8f 2585 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2586 const AliHLTUInt8_t* pEnd=pBuffer+size;
2587
2588 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2589 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2590 parents.push_back(*pParents);
2591 }
2592
2593 const char* pDescription=reinterpret_cast<const char*>(pParents);
2594 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2595 *(pDescription+pEntry->fSizeDescription)!=0) {
2596 return -EBADF;
2597 }
2598
2599 TString descriptor=reinterpret_cast<const char*>(pDescription);
2600 TString chainId;
2601 TString compId;
2602 TString compArgs;
2603 TObjArray* pTokens=descriptor.Tokenize("{");
2604 if (pTokens) {
2605 int n=0;
77fd699f 2606 if (pTokens->GetEntriesFast()>n) {
704972af 2607 retChainId=pTokens->At(n++)->GetName();
abb52c8f 2608 }
77fd699f 2609 if (pTokens->GetEntriesFast()>n) {
704972af 2610 compId=pTokens->At(n++)->GetName();
abb52c8f 2611 }
2612 delete pTokens;
2613 }
2614 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2615 int n=0;
77fd699f 2616 if (pTokens->GetEntriesFast()>n) {
704972af 2617 compId=pTokens->At(n++)->GetName();
abb52c8f 2618 }
77fd699f 2619 if (pTokens->GetEntriesFast()>n) {
704972af 2620 compArgs=pTokens->At(n++)->GetName();
abb52c8f 2621 }
2622 delete pTokens;
2623 }
2624 compId.ReplaceAll("}", "");
2625 compArgs.ReplaceAll("}", "");
2626
2627 retCompId=compId;
2628 retCompArgs=compArgs;
2629
2630 if (retChainId.size()==0) return -ENODATA;
2631
2632 return 1;
2633}
97d2b87a 2634
89413559 2635int AliHLTComponent::ExtractTriggerData(
2636 const AliHLTComponentTriggerData& trigData,
2637 const AliHLTUInt8_t (**attributes)[gkAliHLTBlockDAttributeCount],
2638 AliHLTUInt64_t* status,
2639 const AliRawDataHeader** cdh,
2640 AliHLTReadoutList* readoutlist,
2641 bool printErrors
2642 )
2643{
2644 // see header file for function documentation
2645
2646 // Check that the trigger data structure is the correct size.
2647 if (trigData.fStructSize != sizeof(AliHLTComponentTriggerData))
2648 {
2649 if (printErrors)
2650 {
2651 AliHLTLogging log;
2652 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2653 "Invalid trigger structure size: %d but expected %d.", trigData.fStructSize, sizeof(AliHLTComponentTriggerData)
2654 );
2655 }
2656 return -ENOENT;
2657 }
2658
e4d966f5 2659 // Get the size of the AliHLTEventTriggerData structure without the readout list part.
2660 // The way we do this here should also handle memory alignment correctly.
2661 AliHLTEventTriggerData* dummy = NULL;
2662 size_t sizeWithoutReadout = (char*)(&dummy->fReadoutList) - (char*)(dummy);
2663
89413559 2664 // Check that the trigger data pointer points to data of a size we can handle.
e4d966f5 2665 // Either it is the size of AliHLTEventTriggerData or the size of the old
2666 // version of AliHLTEventTriggerData using AliHLTEventDDLV0.
89413559 2667 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData) and
e4d966f5 2668 trigData.fDataSize != sizeWithoutReadout + sizeof(AliHLTEventDDLV0)
89413559 2669 )
2670 {
2671 if (printErrors)
2672 {
2673 AliHLTLogging log;
2674 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2675 "Invalid trigger data size: %d but expected %d.", trigData.fDataSize, sizeof(AliHLTEventTriggerData)
2676 );
2677 }
2678 return -EBADF;
2679 }
2680
2681 AliHLTEventTriggerData* evtData = reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
2682 assert(evtData != NULL);
2683
2684 // Check that the CDH has 8 words.
2685 if (cdh != NULL and evtData->fCommonHeaderWordCnt != 8)
2686 {
2687 if (printErrors)
2688 {
2689 AliHLTLogging log;
2690 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2691 "Common Data Header (CDH) has wrong number of data words: %d but expected %d",
2692 evtData->fCommonHeaderWordCnt, sizeof(AliRawDataHeader)/sizeof(AliHLTUInt32_t)
2693 );
2694 }
2695 return -EBADMSG;
2696 }
2697
2698 // Check that the readout list has the correct count of words. i.e. something we can handle,
2699 if (readoutlist != NULL and
2700 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV0 and
2701 evtData->fReadoutList.fCount != (unsigned)gkAliHLTDDLListSizeV1
2702 )
2703 {
2704 if (printErrors)
2705 {
2706 AliHLTLogging log;
2707 log.LoggingVarargs(kHLTLogError, Class_Name(), FUNCTIONNAME(), __FILE__, __LINE__,
2708 "Readout list structure has wrong number of data words: %d but expected %d",
2709 evtData->fReadoutList.fCount, gkAliHLTDDLListSize
2710 );
2711 }
2712 return -EPROTO;
2713 }
2714
2715 if (attributes != NULL)
2716 {
2717 *attributes = &evtData->fAttributes;
2718 }
2719 if (status != NULL)
2720 {
2721 *status = evtData->fHLTStatus;
2722 }
2723 if (cdh != NULL)
2724 {
24451d1f 2725 const AliRawDataHeader* cdhptr = reinterpret_cast<const AliRawDataHeader*>(&evtData->fCommonHeader[0]);
89413559 2726 *cdh = cdhptr;
2727 }
2728 if (readoutlist != NULL)
2729 {
2730 *readoutlist = AliHLTReadoutList(evtData->fReadoutList);
2731 }
2732 return 0;
2733}
2734
9e14734f 2735AliHLTUInt32_t AliHLTComponent::ExtractEventTypeFromCDH(const AliRawDataHeader* cdh)
2736{
2737 // see header file for function documentation
2738
2739 UChar_t l1msg = cdh->GetL1TriggerMessage();
2740 if ((l1msg & 0x1) == 0x0) return gkAliEventTypeData;
2741 // The L2SwC bit must be one if we got here, i.e. l1msg & 0x1 == 0x1.
2742 if (((l1msg >> 2) & 0xF) == 0xE) return gkAliEventTypeStartOfRun;
2743 if (((l1msg >> 2) & 0xF) == 0xF) return gkAliEventTypeEndOfRun;
2744 // Check the C1T bit to see if this is a calibration event,
2745 // if not then it must be some other software trigger event.
2746 if (((l1msg >> 6) & 0x1) == 0x1) return gkAliEventTypeCalibration;
2747 return gkAliEventTypeSoftware;
2748}
2749
97d2b87a 2750int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2751 const char* originClass, const char* originFunc,
2752 const char* file, int line, ... ) const
2753{
2754 // see header file for function documentation
2755 int iResult=0;
2756
2757 va_list args;
2758 va_start(args, line);
2759
2760 // logging function needs to be const in order to be called from const member functions
2761 // without problems. But at this point we face the problem with virtual members which
2762 // are not necessarily const.
2763 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
7efb6418 2764 AliHLTLogging::SetLogString(this, ", %p", "%s (%s_pfmt_): ",
97d2b87a 2765 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
7efb6418 2766 nonconst->GetComponentID());
97d2b87a 2767 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2768 va_end(args);
2769
2770 return iResult;
2771}
cf9cf07e 2772
cc095616 2773TUUID AliHLTComponent::GenerateGUID()
2774{
2775 // Generates a globally unique identifier.
2776
2777 // Start by creating a new UUID. We cannot use the one automatically generated
2778 // by ROOT because the algorithm used will not guarantee unique IDs when generating
2779 // these UUIDs at a high rate in parallel.
2780 TUUID uuid;
2781 // We then use the generated UUID to form part of the random number seeds which
2782 // will be used to generate a proper random UUID. For good measure we use a MD5
2783 // hash also. Note that we want to use the TUUID class because it will combine the
2784 // host address information into the UUID. Using gSystem->GetHostByName() apparently
2785 // can cause problems on Windows machines with a firewall, because it always tries
2786 // to contact a DNS. The TUUID class handles this case appropriately.
2787 union
2788 {
2789 UChar_t buf[16];
2790 UShort_t word[8];
2791 UInt_t dword[4];
2792 };
2793 uuid.GetUUID(buf);
2794 TMD5 md5;
2795 md5.Update(buf, sizeof(buf));
2796 TMD5 md52 = md5;
2797 md5.Final(buf);
2798 dword[0] += gSystem->GetUid();
2799 dword[1] += gSystem->GetGid();
2800 dword[2] += gSystem->GetPid();
2801 for (int i = 0; i < 4; ++i)
2802 {
2803 gRandom->SetSeed(dword[i]);
2804 dword[i] = gRandom->Integer(0xFFFFFFFF);
2805 }
2806 md52.Update(buf, sizeof(buf));
2807 md52.Final(buf);
2808 // To keep to the standard we need to set the version and reserved bits.
2809 word[3] = (word[3] & 0x0FFF) | 0x4000;
2810 buf[8] = (buf[8] & 0x3F) | 0x80;
2811
2812 // Create the name of the new class and file.
2813 char uuidstr[64];
2814 sprintf(uuidstr, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2815 dword[0], word[2], word[3], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]
2816 );
2817
2818 uuid.SetUUID(uuidstr);
2819 return uuid;
2820}
2821
cf9cf07e 2822int AliHLTComponent::ScanECSParam(const char* ecsParam)
2823{
2824 // see header file for function documentation
2825
2826 // format of the parameter string from ECS
2827 // <command>;<parameterkey>=<parametervalue>;<parameterkey>=<parametervalue>;...
2828 // search for a subset of the parameterkeys
c4ffab2c 2829 // RUN_TYPE=
2830 // RUN_NUMBER=
2831 // HLT_IN_DDL_LIST=
2832 // CTP_TRIGGER_CLASS=
2833 // DATA_FORMAT_VERSION=
2834 // BEAM_TYPE=
2835 // HLT_OUT_DDL_LIST=
2836 // HLT_TRIGGER_CODE=
2837 // DETECTOR_LIST=
2838 // HLT_MODE=
2839 // The command apears not to be sent by the online framework
cf9cf07e 2840 int iResult=0;
2841 TString string=ecsParam;
2842 TObjArray* parameter=string.Tokenize(";");
2843 if (parameter) {
77fd699f 2844 for (int i=0; i<parameter->GetEntriesFast(); i++) {
704972af 2845 TString entry=parameter->At(i)->GetName();
cf9cf07e 2846 HLTDebug("scanning ECS entry: %s", entry.Data());
2847 TObjArray* entryParams=entry.Tokenize("=");
2848 if (entryParams) {
77fd699f 2849 if (entryParams->GetEntriesFast()>1) {
cf9cf07e 2850 if ((((TObjString*)entryParams->At(0))->GetString()).CompareTo("CTP_TRIGGER_CLASS")==0) {
704972af 2851 int result=InitCTPTriggerClasses(entryParams->At(1)->GetName());
cf9cf07e 2852 if (iResult>=0 && result<0) iResult=result;
2853 } else {
2854 // TODO: scan the other parameters
2855 // e.g. consistency check of run number
2856 }
2857 }
2858 delete entryParams;
2859 }
2860 }
2861 delete parameter;
2862 }
2863
2864 return iResult;
2865}
2866
adb91bc3 2867int AliHLTComponent::SetupCTPData()
cf9cf07e 2868{
2869 // see header file for function documentation
adb91bc3 2870 if (fpCTPData) delete fpCTPData;
2871 fpCTPData=new AliHLTCTPData;
2872 if (!fpCTPData) return -ENOMEM;
cf9cf07e 2873 return 0;
2874}
2875
adb91bc3 2876int AliHLTComponent::InitCTPTriggerClasses(const char* ctpString)
cf9cf07e 2877{
2878 // see header file for function documentation
adb91bc3 2879 if (!fpCTPData) return 0; // silently accept as the component has to announce that it want's the CTP info
2880 return fpCTPData->InitCTPTriggerClasses(ctpString);
2881}
cf9cf07e 2882
adb91bc3 2883bool AliHLTComponent::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
2884{
2885 // see header file for function documentation
2886 if (!fpCTPData) {
2887 static bool bWarningThrown=false;
2888 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2889 bWarningThrown=true;
cf9cf07e 2890 return false;
2891 }
2892
adb91bc3 2893 return fpCTPData->EvaluateCTPTriggerClass(expression, trigData);
cf9cf07e 2894}
a5e775ec 2895
3fcb48b8 2896int AliHLTComponent::CheckCTPTrigger(const char* name) const
2897{
2898 // see header file for function documentation
2899 if (!fpCTPData) {
2900 static bool bWarningThrown=false;
2901 if (!bWarningThrown) HLTError("Trigger classes not initialized, use SetupCTPData from DoInit()");
2902 bWarningThrown=true;
2903 return false;
2904 }
2905
2906 return fpCTPData->CheckTrigger(name);
2907}
2908
a5e775ec 2909Double_t AliHLTComponent::GetBz()
2910{
2911 // Returns Bz.
2912 return AliHLTMisc::Instance().GetBz();
2913}
2914
2915Double_t AliHLTComponent::GetBz(const Double_t *r)
2916{
2917 // Returns Bz (kG) at the point "r" .
2918 return AliHLTMisc::Instance().GetBz(r);
2919}
2920
2921void AliHLTComponent::GetBxByBz(const Double_t r[3], Double_t b[3])
2922{
2923 // Returns Bx, By and Bz (kG) at the point "r" .
2924 AliHLTMisc::Instance().GetBxByBz(r, b);
2925}