]>
Commit | Line | Data |
---|---|---|
b765ad15 | 1 | // $Id$ |
2 | ||
3 | //************************************************************************** | |
4 | //* This file is property of and copyright by the ALICE HLT Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | //* for The ALICE HLT Project. * | |
9 | //* * | |
10 | //* Permission to use, copy, modify and distribute this software and its * | |
11 | //* documentation strictly for non-commercial purposes is hereby granted * | |
12 | //* without fee, provided that the above copyright notice appears in all * | |
13 | //* copies and that both the copyright notice and this permission notice * | |
14 | //* appear in the supporting documentation. The authors make no claims * | |
15 | //* about the suitability of this software for any purpose. It is * | |
16 | //* provided "as is" without express or implied warranty. * | |
17 | //************************************************************************** | |
18 | ||
19 | /** @file AliHLTCompStatCollector.cxx | |
20 | @author Matthias Richter | |
21 | @date | |
22 | @brief Collector component for the component statistics information. | |
23 | */ | |
24 | ||
25 | #include "AliHLTCompStatCollector.h" | |
26 | #include "TStopwatch.h" | |
27 | #include "TH1F.h" | |
28 | #include "TH2F.h" | |
29 | #include "TH2C.h" | |
30 | #include "TTree.h" | |
abb52c8f | 31 | #include "TFolder.h" |
32 | #include "TNamed.h" | |
b765ad15 | 33 | #include "TString.h" |
abb52c8f | 34 | #include <cassert> |
35 | ||
36 | #define HLTSTAT_FOLDER_NAME "HLTstat" | |
37 | #define HLTSTAT_FOLDER_DESC "ALICE HLT component statistics" | |
38 | #define HLTSTAT_ENTRY_PARENT_FOLDER_NAME "parents" | |
39 | #define HLTSTAT_ENTRY_PARENT_FOLDER_DESC "parent components" | |
40 | #define HLTSTAT_ENTRY_PROPS_FOLDER_NAME "props" | |
41 | #define HLTSTAT_ENTRY_PROPS_FOLDER_DESC "component properties" | |
42 | #define HLTSTAT_ENTRY_PROPS_IDOBJ_NAME "id" | |
43 | #define HLTSTAT_ENTRY_PROPS_IDOBJ_DESC "numerical id calculated from chain id" | |
b765ad15 | 44 | |
45 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
46 | ClassImp(AliHLTCompStatCollector) | |
47 | ||
48 | AliHLTCompStatCollector::AliHLTCompStatCollector() | |
49 | : | |
50 | AliHLTProcessor(), | |
51 | fpTimer(NULL), | |
abb52c8f | 52 | fpFolder(NULL), |
b765ad15 | 53 | fpStatTree(NULL), |
54 | fCycleTime(0), | |
55 | fNofSets(0), | |
56 | fArraySize(1000), | |
57 | fPosition(0), | |
58 | fpLevelArray(NULL), | |
59 | fpSpecArray(NULL), | |
60 | fpBlockNoArray(NULL), | |
61 | fpIdArray(NULL), | |
62 | fpTimeArray(NULL), | |
63 | fpCTimeArray(NULL), | |
64 | fpInputBlockCountArray(NULL), | |
65 | fpTotalInputSizeArray(NULL), | |
66 | fpOutputBlockCountArray(NULL), | |
67 | fpTotalOutputSizeArray(NULL) | |
63410eb4 | 68 | , fSizeEstimator(1000) |
b765ad15 | 69 | { |
70 | // see header file for class documentation | |
71 | // or | |
72 | // refer to README to build package | |
73 | // or | |
74 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
75 | } | |
76 | ||
77 | AliHLTCompStatCollector::~AliHLTCompStatCollector() | |
78 | { | |
79 | // see header file for class documentation | |
80 | ClearAll(); | |
81 | } | |
82 | ||
83 | void AliHLTCompStatCollector::GetInputDataTypes( vector<AliHLTComponentDataType>& list) | |
84 | { | |
85 | // see header file for class documentation | |
86 | list.push_back(kAliHLTDataTypeComponentStatistics); | |
87 | } | |
88 | ||
89 | AliHLTComponentDataType AliHLTCompStatCollector::GetOutputDataType() | |
90 | { | |
91 | // see header file for class documentation | |
92 | return kAliHLTMultipleDataType; | |
93 | } | |
94 | ||
95 | int AliHLTCompStatCollector::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) | |
96 | { | |
97 | // see header file for class documentation | |
98 | tgtList.clear(); | |
99 | tgtList.push_back(kAliHLTDataTypeHistogram); | |
100 | tgtList.push_back(kAliHLTDataTypeTTree); | |
101 | return tgtList.size(); | |
102 | } | |
103 | ||
104 | void AliHLTCompStatCollector::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
105 | { | |
106 | // see header file for class documentation | |
63410eb4 | 107 | constBase=fSizeEstimator; |
b765ad15 | 108 | inputMultiplier=100.0; |
109 | } | |
110 | ||
111 | int AliHLTCompStatCollector::DoInit( int argc, const char** argv ) | |
112 | { | |
113 | // see header file for class documentation | |
114 | int iResult=0; | |
115 | TString argument=""; | |
116 | int bMissingParam=0; | |
117 | for (int i=0; i<argc && iResult>=0; i++) { | |
118 | argument=argv[i]; | |
119 | if (argument.IsNull()) continue; | |
120 | ||
121 | // -array-size | |
122 | if (argument.CompareTo("-array-size")==0) { | |
123 | if ((bMissingParam=(++i>=argc))) break; | |
124 | TString param=argv[argc]; | |
125 | if (param.IsDigit()) { | |
126 | fArraySize=param.Atoi(); | |
127 | } else { | |
128 | HLTError("expecting number as parameter for option '-array-size'"); | |
129 | iResult=-EINVAL; | |
130 | } | |
131 | ||
132 | } else { | |
133 | iResult=-EINVAL; | |
134 | } | |
135 | } | |
136 | if (bMissingParam) { | |
137 | HLTError("missing parameter for argument %s", argument.Data()); | |
138 | iResult=-EINVAL; | |
139 | } | |
140 | ||
141 | if (iResult>=0) { | |
142 | fpLevelArray=new UInt_t[fArraySize]; | |
143 | fpSpecArray=new UInt_t[fArraySize]; | |
144 | fpBlockNoArray=new UInt_t[fArraySize]; | |
145 | fpIdArray=new UInt_t[fArraySize]; | |
146 | fpTimeArray=new UInt_t[fArraySize]; | |
147 | fpCTimeArray=new UInt_t[fArraySize]; | |
148 | fpInputBlockCountArray=new UInt_t[fArraySize]; | |
149 | fpTotalInputSizeArray=new UInt_t[fArraySize]; | |
150 | fpOutputBlockCountArray=new UInt_t[fArraySize]; | |
151 | fpTotalOutputSizeArray=new UInt_t[fArraySize]; | |
152 | ||
153 | fpStatTree=new TTree("CompStat", "HLT component statistics"); | |
154 | if (fpStatTree) { | |
155 | fpStatTree->SetDirectory(0); | |
156 | fpStatTree->Branch("cycleTime", &fCycleTime, "cycleTime/F"); | |
157 | fpStatTree->Branch("nofSets", &fNofSets, "nofSets/I"); | |
158 | fpStatTree->Branch("Level", fpLevelArray, "Level[nofSets]/i"); | |
159 | fpStatTree->Branch("Specification", fpSpecArray, "Specification[nofSets]/i"); | |
160 | fpStatTree->Branch("BlockNo", fpBlockNoArray, "BlockNo[nofSets]/i"); | |
161 | fpStatTree->Branch("Id", fpIdArray, "Id[nofSets]/i"); | |
162 | fpStatTree->Branch("Time", fpTimeArray, "Time[nofSets]/i"); | |
163 | fpStatTree->Branch("CTime", fpCTimeArray, "CTime[nofSets]/i"); | |
164 | fpStatTree->Branch("InputBlockCount", fpInputBlockCountArray, "InputBlockCount[nofSets]/i"); | |
165 | fpStatTree->Branch("TotalInputSize", fpTotalInputSizeArray, "TotalInputSize[nofSets]/i"); | |
166 | fpStatTree->Branch("OutputBlockCount", fpOutputBlockCountArray, "OutputBlockCount[nofSets]/i"); | |
167 | fpStatTree->Branch("TotalOutputSize", fpTotalOutputSizeArray, "TotalOutputSize[nofSets]/i"); | |
168 | } | |
169 | } | |
170 | return iResult; | |
171 | } | |
172 | ||
173 | int AliHLTCompStatCollector::DoDeinit( ) | |
174 | { | |
175 | // see header file for class documentation | |
176 | ClearAll(); | |
177 | ||
178 | return 0; | |
179 | } | |
180 | ||
181 | int AliHLTCompStatCollector::DoEvent( const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/) | |
182 | { | |
183 | // see header file for class documentation | |
184 | int iResult=0; | |
185 | ||
abb52c8f | 186 | AliHLTUInt32_t eventType=gkAliEventTypeUnknown; |
187 | IsDataEvent(&eventType); | |
188 | ||
b765ad15 | 189 | ResetFillingVariables(); |
190 | if (fpTimer) { | |
191 | fCycleTime=fpTimer->RealTime()*1000000; | |
192 | } | |
193 | ||
abb52c8f | 194 | bool bEmbeddedTree=false; |
195 | bool bFolderCreated=false; | |
9d5f00ad | 196 | if ((bFolderCreated=(fpFolder==NULL))) { |
abb52c8f | 197 | fpFolder=new TFolder(HLTSTAT_FOLDER_NAME, HLTSTAT_FOLDER_DESC); |
198 | if (bEmbeddedTree) fpFolder->Add(fpStatTree); | |
199 | } | |
200 | if (!fpFolder) return -ENOMEM; | |
201 | vector<TFolder*> newFolders; | |
202 | ||
203 | for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentTable); | |
204 | pBlock && iResult>=0; | |
205 | pBlock=GetNextInputBlock()) { | |
206 | string chainId, compId, compArgs; | |
207 | vector<AliHLTUInt32_t> parents; | |
208 | iResult=ExtractComponentTableEntry((const AliHLTUInt8_t*)pBlock->fPtr, pBlock->fSize, | |
209 | chainId, compId, compArgs, | |
210 | parents); | |
211 | if (iResult>0) { | |
212 | HLTDebug("%s(%s) 0x%08x", chainId.c_str(), compId.c_str(), pBlock->fSpecification); | |
213 | TObject* pObj=NULL; | |
214 | TFolder* pEntry=NULL; | |
215 | if ((pObj=fpFolder->FindObjectAny(chainId.c_str()))!=NULL && | |
216 | (pEntry=dynamic_cast<TFolder*>(pObj))!=NULL ) { | |
217 | ||
218 | } else if (pObj) { | |
219 | HLTError("entry %s exists in folder, but is not a sub-folder", chainId.c_str()); | |
220 | } else if (chainId.size()>0) { | |
221 | pEntry=new TFolder(chainId.c_str(), chainId.c_str()); | |
222 | if (pEntry) { | |
223 | pEntry->SetOwner(); | |
224 | TFolder* pProps=pEntry->AddFolder(HLTSTAT_ENTRY_PROPS_FOLDER_NAME, HLTSTAT_ENTRY_PROPS_FOLDER_DESC); | |
225 | if (pProps) { | |
226 | pProps->Add(new TObjString(compId.c_str())); | |
227 | if (!compArgs.empty()) | |
228 | pProps->Add(new TObjString(compArgs.c_str())); | |
229 | TNamed* pCRC=new TNamed(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME, HLTSTAT_ENTRY_PROPS_IDOBJ_DESC); | |
230 | if (pCRC) { | |
231 | pCRC->SetUniqueID(pBlock->fSpecification); | |
232 | pProps->Add(pCRC); | |
233 | } | |
234 | } | |
235 | TFolder* pParents=pEntry->AddFolder(HLTSTAT_ENTRY_PARENT_FOLDER_NAME, HLTSTAT_ENTRY_PARENT_FOLDER_DESC); | |
236 | if (pParents) { | |
237 | for (vector<AliHLTUInt32_t>::iterator parent=parents.begin(); | |
238 | parent!=parents.end(); parent++) { | |
239 | TString name; name.Form("0x%08x", *parent); | |
240 | pParents->Add(new TObjString(name)); | |
241 | } | |
242 | } | |
243 | if (parents.size()==0) { | |
244 | newFolders.push_back(pEntry); | |
245 | } else { | |
246 | vector<TFolder*>::iterator iter=newFolders.begin(); | |
247 | vector<AliHLTUInt32_t>::iterator parent=parents.begin(); | |
248 | while (iter!=newFolders.end() && parent!=parents.end()) { | |
249 | TObject* idobj=(*iter)->FindObjectAny(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME); | |
250 | AliHLTUInt32_t crcid=0; | |
251 | if (idobj) crcid=idobj->GetUniqueID(); | |
252 | HLTDebug("check: %s 0x%08x", (*iter)->GetName(), crcid); | |
253 | if (idobj && crcid==*parent) break; | |
254 | if ((++parent!=parents.end())) continue; | |
255 | parent=parents.begin(); | |
256 | iter++; | |
257 | } | |
258 | newFolders.insert(iter,pEntry); | |
259 | } | |
260 | } | |
261 | } else { | |
262 | HLTError("missing chain id for table entry 0x%08x (%p %d), skipping ...", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize); | |
263 | } | |
264 | } else if (iResult!=0) { | |
265 | HLTError("extraction of table entry 0x%08x (%p %d) failed with %d", pBlock->fSpecification, pBlock->fPtr, pBlock->fSize, iResult); | |
266 | } | |
267 | iResult=0; | |
268 | } | |
269 | ||
270 | if (newFolders.size()>0) { | |
271 | vector<TFolder*> revert; | |
272 | vector<TFolder*>::iterator iter=newFolders.begin(); | |
273 | while (iter!=newFolders.end()) { | |
274 | revert.insert(revert.begin(), *iter); | |
275 | HLTDebug("%s", (*iter)->GetName()); | |
276 | iter++; | |
277 | } | |
278 | newFolders.empty(); | |
279 | newFolders.assign(revert.begin(), revert.end()); | |
280 | ||
281 | vector<TFolder*>::iterator publisher=newFolders.begin(); | |
282 | while (publisher!=newFolders.end()) { | |
283 | bool bRemove=false; | |
284 | HLTDebug("checking %s for parents", (*publisher)->GetName()); | |
285 | TFolder* propsFolder=dynamic_cast<TFolder*>((*publisher)->FindObject(HLTSTAT_ENTRY_PROPS_FOLDER_NAME)); | |
286 | assert(propsFolder); | |
287 | TObject* idobj=NULL; | |
288 | if (propsFolder) idobj=propsFolder->FindObject(HLTSTAT_ENTRY_PROPS_IDOBJ_NAME); | |
289 | assert(idobj); | |
290 | AliHLTUInt32_t crcid=idobj->GetUniqueID(); | |
291 | TString idstr; idstr.Form("0x%08x", crcid); | |
292 | if (idobj) { | |
293 | for (vector<TFolder*>::iterator consumer=publisher+1; | |
294 | consumer!=newFolders.end(); consumer++) { | |
295 | HLTDebug(" checking %s", (*consumer)->GetName()); | |
296 | TFolder* parentFolder=dynamic_cast<TFolder*>((*consumer)->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME)); | |
297 | assert(parentFolder); | |
298 | if (parentFolder) { | |
299 | TIter entries(parentFolder->GetListOfFolders()); | |
300 | while (TObject* entry=entries.Next()) | |
460c4045 | 301 | if (entry) { |
302 | Bool_t foo; foo=kTRUE;// only to avoid warning in non-debug compile | |
303 | HLTDebug(" searching %s in %s: %s", idstr.Data(), (*consumer)->GetName(), entry->GetName()); | |
304 | } | |
abb52c8f | 305 | TObject* parent=parentFolder->FindObjectAny(idstr); |
306 | if (parent) { | |
307 | parentFolder->Add(*publisher); | |
308 | parentFolder->Remove(parent); | |
309 | bRemove=true; | |
310 | } | |
311 | } | |
312 | } | |
313 | } | |
314 | if (bRemove) publisher=newFolders.erase(publisher); | |
315 | else publisher++; | |
316 | } | |
317 | ||
318 | for (publisher=newFolders.begin(); | |
319 | publisher!=newFolders.end(); publisher++) { | |
320 | RemoveRecurrence(*publisher); | |
321 | fpFolder->Add(*publisher); | |
322 | } | |
323 | } | |
324 | ||
b765ad15 | 325 | int blockNo=0; |
326 | for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock(kAliHLTDataTypeComponentStatistics); | |
327 | pBlock && iResult>=0; | |
328 | pBlock=GetNextInputBlock(), blockNo++) { | |
329 | unsigned int current=fPosition; | |
330 | iResult=FillVariablesSorted(pBlock->fPtr, pBlock->fSize); | |
331 | for (; current<fPosition; current++) { | |
332 | fpSpecArray[current]=pBlock->fSpecification; | |
333 | fpBlockNoArray[current]=blockNo; | |
334 | } | |
587c9cf9 | 335 | // indicate availability of component statistic block |
336 | iResult=1; | |
b765ad15 | 337 | } |
338 | ||
587c9cf9 | 339 | if (iResult>0) { |
b765ad15 | 340 | fNofSets=fPosition; |
341 | fpStatTree->Fill(); | |
63410eb4 | 342 | if (!bEmbeddedTree && ((iResult=PushBack(fpStatTree, kAliHLTDataTypeTTree|kAliHLTDataOriginOut))==-ENOSPC)) { |
343 | fSizeEstimator+=GetLastObjectSize(); | |
344 | } | |
b765ad15 | 345 | |
587c9cf9 | 346 | // init the timer for the next cycle |
347 | if (!fpTimer) fpTimer=new TStopwatch; | |
348 | if (fpTimer) { | |
349 | fpTimer->Reset(); | |
350 | fpTimer->Start(); | |
351 | } | |
b765ad15 | 352 | } |
353 | ||
abb52c8f | 354 | if (iResult>=0 /*&& eventType==gkAliEventTypeEndOfRun*/) { |
63410eb4 | 355 | if ((iResult=PushBack(fpFolder, kAliHLTDataTypeTObject|kAliHLTDataOriginOut))==-ENOSPC) { |
356 | fSizeEstimator+=GetLastObjectSize(); | |
357 | } | |
abb52c8f | 358 | } |
359 | ||
360 | if (iResult>0) iResult=0; | |
b765ad15 | 361 | return iResult; |
362 | } | |
363 | ||
364 | void AliHLTCompStatCollector::ResetFillingVariables() | |
365 | { | |
366 | // see header file for class documentation | |
367 | fCycleTime=0; | |
368 | fNofSets=0; | |
369 | fPosition=0; | |
370 | memset(fpLevelArray, 0, sizeof(UInt_t)*fArraySize); | |
371 | memset(fpSpecArray, 0, sizeof(UInt_t)*fArraySize); | |
372 | memset(fpBlockNoArray, 0, sizeof(UInt_t)*fArraySize); | |
373 | memset(fpIdArray, 0, sizeof(UInt_t)*fArraySize); | |
374 | memset(fpTimeArray, 0, sizeof(UInt_t)*fArraySize); | |
375 | memset(fpCTimeArray, 0, sizeof(UInt_t)*fArraySize); | |
376 | memset(fpInputBlockCountArray, 0, sizeof(UInt_t)*fArraySize); | |
377 | memset(fpTotalInputSizeArray, 0, sizeof(UInt_t)*fArraySize); | |
378 | memset(fpOutputBlockCountArray, 0, sizeof(UInt_t)*fArraySize); | |
379 | memset(fpTotalOutputSizeArray, 0, sizeof(UInt_t)*fArraySize); | |
380 | } | |
381 | ||
382 | int AliHLTCompStatCollector::FillVariablesSorted(void* ptr, int size) | |
383 | { | |
384 | // see header file for class documentation | |
385 | int iResult=0; | |
386 | if (size%sizeof(AliHLTComponentStatistics)) { | |
387 | HLTError("data block is not aligned to the size of the AliHLTComponentStatistics struct"); | |
388 | return -EINVAL; | |
389 | } | |
390 | AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(ptr); | |
391 | UInt_t nofStats=size/sizeof(AliHLTComponentStatistics); | |
392 | vector<int> indexList; | |
393 | UInt_t i=0; | |
394 | for (i=0; i<nofStats; i++) { | |
395 | vector<int>::iterator element=indexList.begin(); | |
396 | for (; element!=indexList.end(); element++) { | |
397 | if (pStat[i].fLevel>pStat[*element].fLevel) { | |
398 | break; | |
399 | } | |
400 | } | |
401 | indexList.insert(element, i); | |
402 | } | |
403 | ||
404 | i=fPosition; | |
405 | for (vector<int>::iterator element=indexList.begin(); | |
406 | element!=indexList.end(); | |
407 | element++, i++) { | |
408 | if (i<fArraySize) { | |
409 | fpLevelArray[i]=pStat[*element].fLevel; | |
410 | fpIdArray[i]=pStat[*element].fId; | |
411 | fpTimeArray[i]=pStat[*element].fTime; | |
412 | fpCTimeArray[i]=pStat[*element].fCTime; | |
413 | fpInputBlockCountArray[i]=pStat[*element].fInputBlockCount; | |
414 | fpTotalInputSizeArray[i]=pStat[*element].fTotalInputSize; | |
415 | fpOutputBlockCountArray[i]=pStat[*element].fOutputBlockCount; | |
416 | fpTotalOutputSizeArray[i]=pStat[*element].fTotalOutputSize; | |
417 | } | |
418 | } | |
419 | ||
420 | if (i>=fArraySize) { | |
421 | HLTWarning("too little space in branch variables to fill %d statistics blocks, available %d at position %d", i, fArraySize, fPosition); | |
422 | fPosition=fArraySize; | |
423 | } else { | |
424 | fPosition=i; | |
425 | } | |
426 | ||
427 | return iResult; | |
428 | } | |
429 | ||
430 | void AliHLTCompStatCollector::ClearAll() | |
431 | { | |
abb52c8f | 432 | // see header file for class documentation |
b765ad15 | 433 | if (fpTimer) delete fpTimer; fpTimer=NULL; |
abb52c8f | 434 | if (fpFolder) delete fpFolder; fpFolder=NULL; |
b765ad15 | 435 | if (fpStatTree) delete fpStatTree; fpStatTree=NULL; |
436 | if (fpLevelArray) delete fpLevelArray; fpLevelArray=NULL; | |
437 | if (fpSpecArray) delete fpSpecArray; fpSpecArray=NULL; | |
438 | if (fpBlockNoArray) delete fpBlockNoArray; fpBlockNoArray=NULL; | |
439 | if (fpIdArray) delete fpIdArray; fpIdArray=NULL; | |
440 | if (fpTimeArray) delete fpTimeArray; fpTimeArray=NULL; | |
441 | if (fpCTimeArray) delete fpCTimeArray; fpCTimeArray=NULL; | |
442 | if (fpInputBlockCountArray) delete fpInputBlockCountArray; fpInputBlockCountArray=NULL; | |
443 | if (fpTotalInputSizeArray) delete fpTotalInputSizeArray; fpTotalInputSizeArray=NULL; | |
444 | if (fpOutputBlockCountArray) delete fpOutputBlockCountArray; fpOutputBlockCountArray=NULL; | |
445 | if (fpTotalOutputSizeArray) delete fpTotalOutputSizeArray; fpTotalOutputSizeArray=NULL; | |
446 | } | |
abb52c8f | 447 | |
448 | int AliHLTCompStatCollector::RemoveRecurrence(TFolder* pRoot) const | |
449 | { | |
450 | // see header file for class documentation | |
451 | int iResult=0; | |
452 | if (!pRoot) return -EINVAL; | |
453 | TFolder* parentFolder=dynamic_cast<TFolder*>(pRoot->FindObject(HLTSTAT_ENTRY_PARENT_FOLDER_NAME)); | |
454 | assert(parentFolder); | |
455 | vector<TFolder*> listRemove; | |
456 | if (parentFolder) { | |
457 | TIter entries(parentFolder->GetListOfFolders()); | |
458 | TFolder* entry=NULL; | |
459 | TObject* obj=NULL; | |
460 | while ((obj=entries.Next())!=NULL && (entry=dynamic_cast<TFolder*>(obj))!=NULL) { | |
461 | TString name=entry->GetName(); | |
462 | HLTDebug("checking %s for recurrence", name.Data()); | |
463 | TIter tokens(parentFolder->GetListOfFolders()); | |
464 | TFolder* token=NULL; | |
465 | while ((obj=tokens.Next())!=NULL && (token=dynamic_cast<TFolder*>(obj))!=NULL) { | |
466 | if (name.CompareTo(token->GetName())==0) continue; | |
467 | if ((obj=token->FindObjectAny(name))!=NULL) { | |
468 | listRemove.push_back(entry); | |
469 | HLTDebug("found recurrence in %s", token->GetName()); | |
470 | break; | |
471 | } else { | |
472 | HLTDebug("no recurrence found in %s", token->GetName()); | |
473 | } | |
474 | } | |
475 | RemoveRecurrence(entry); | |
476 | } | |
477 | for (vector<TFolder*>::iterator removeElement=listRemove.begin(); | |
478 | removeElement!=listRemove.end(); removeElement++) { | |
479 | parentFolder->Remove(*removeElement); | |
480 | } | |
481 | } | |
482 | ||
483 | return iResult; | |
484 | } |