Adding a new common utility class to hold a list of named scalars.
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTScalars.cxx
1 // $Id: $
2 /**************************************************************************
3  * This file is property of and copyright by the ALICE HLT Project        *
4  * All rights reserved.                                                   *
5  *                                                                        *
6  * Primary Authors:                                                       *
7  *   Artur Szostak <artursz@iafrica.com>                                  *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 ///  @file   AliHLTScalars.cxx
19 ///  @author Artur Szostak <artursz@iafrica.com>
20 ///  @date   28 Sep 2010
21 ///  @brief  Implementation of the HLT scalars class.
22 ///
23 /// This implements the scalars class for the HLT, which is a collection of
24 /// named scalar values. Searching for a named scalar is optimised by using
25 /// using a hash map.
26
27 #include "AliHLTScalars.h"
28 #include "TString.h"
29 #include "AliLog.h"
30 #include "TIterator.h"
31 #include "Riostream.h"
32 #include <cassert>
33
34 ClassImp(AliHLTScalars);
35 ClassImp(AliHLTScalars::AliScalar);
36
37
38 AliHLTScalars::AliHLTScalars() :
39         TObject(),
40         fScalars(AliHLTScalars::AliScalar::Class(), 128),
41         fMap(TCollection::kInitHashTableCapacity, 2)
42 {
43         // Default constructor.
44         
45         fMap.SetOwner(kFALSE);
46 }
47
48
49 AliHLTScalars::AliHLTScalars(const AliHLTScalars& obj) :
50         TObject(obj),
51         fScalars(obj.fScalars),
52         fMap(obj.fMap.GetSize(), obj.fMap.GetRehashLevel())
53 {
54         // Copy constructor performs a deep copy.
55
56         fMap.SetOwner(kFALSE);
57         fMap.AddAll(&fScalars);
58 }
59
60
61 AliHLTScalars::AliHLTScalars(const TClass* cl, Int_t initSize) :
62         TObject(),
63         fScalars(cl, initSize),
64         fMap(TCollection::kInitHashTableCapacity, 2)
65 {
66         // Constructor to be able to specify a custom class for the fScalars TClonesArray object.
67
68         fMap.SetOwner(kFALSE);
69 }
70
71
72 AliHLTScalars::~AliHLTScalars()
73 {
74         // Default destructor.
75         
76         Clear();
77 }
78
79
80 bool AliHLTScalars::Add(const char* name, const char* description, Double_t value)
81 {
82         // Adds a new scalar.
83
84         AliScalar* scalar = static_cast<AliScalar*>( fMap.FindObject(name) );
85         bool exists = scalar != NULL;
86         if (not exists)
87         {
88                 scalar = new (fScalars[fScalars.GetEntriesFast()]) AliScalar(name, description, value);
89                 fMap.Add(scalar);
90         }
91         else
92         {
93                 scalar->Value(value);
94         }
95         return exists;
96 }
97
98
99 bool AliHLTScalars::Remove(const char* name)
100 {
101         // Removes a scalar from the list.
102
103         TNamed x(name, "");
104         TObject* scalar = fMap.Remove(&x);
105         bool existed = scalar != NULL;
106         if (existed)
107         {
108                 fScalars.Remove(scalar);
109                 fScalars.Compress();
110         }
111         return existed;
112 }
113
114
115 const AliHLTScalars::AliScalar& AliHLTScalars::GetScalar(const char* name) const
116 {
117         // Fetch the named scalar object.
118
119         const TObject* scalar = fMap.FindObject(name);
120         if (scalar != NULL)
121         {
122                 return *static_cast<const AliScalar*>(scalar);
123         }
124         else
125         {
126                 static AliHLTScalars::AliScalar sentinel;
127                 return sentinel;
128         }
129 }
130
131
132 AliHLTScalars::AliScalar& AliHLTScalars::GetScalar(const char* name)
133 {
134         // Fetch the named scalar object for editing.
135
136         TObject* scalar = fMap.FindObject(name);
137         if (scalar == NULL)
138         {
139                 scalar = new (fScalars[fScalars.GetEntriesFast()]) AliScalar(name, "", 0);
140                 fMap.Add(scalar);
141         }
142         return *static_cast<AliScalar*>(scalar);
143 }
144
145
146 const AliHLTScalars::AliScalar& AliHLTScalars::GetScalarN(UInt_t n) const
147 {
148         // Fetch the n'th scalar object.
149
150         if (n < NumberOfScalars())
151         {
152                 const TObject* scalar = fScalars.UncheckedAt(Int_t(n));
153                 return *static_cast<const AliScalar*>(scalar);
154         }
155         else
156         {
157                 static AliHLTScalars::AliScalar sentinel;
158                 return sentinel;
159         }
160 }
161
162
163 AliHLTScalars::AliScalar& AliHLTScalars::GetScalarN(UInt_t n)
164 {
165         // Fetch the n'th scalar object for editing.
166
167         TObject* scalar = NULL;
168         if (n < NumberOfScalars())
169         {
170                 scalar = fScalars.UncheckedAt(Int_t(n));
171         }
172         else
173         {
174                 // We have to create all missing scalars since there cannot
175                 // be gaps in the TClonesArray. This can cause segfaults during
176                 // ROOT I/O of the class otherwise.
177                 for (UInt_t i = NumberOfScalars(); i <= n; ++i)
178                 {
179                         // Make sure the the name of the scalar is not taken.
180                         // If it is then find an unused name.
181                         TString nameToUse = Form("Scalar%d", i);
182                         if (FindObject(nameToUse.Data()) != NULL)
183                         {
184                                 UInt_t m = 0;
185                                 do
186                                 {
187                                         nameToUse = Form("Scalar%d_%d", i, m++);
188                                 }
189                                 while (FindObject(nameToUse.Data()) != NULL);
190                         }
191                         scalar = new (fScalars[i]) AliScalar(nameToUse.Data(), "", 0);
192                         fMap.Add(scalar);
193                 }
194         }
195         return *static_cast<AliScalar*>(scalar);
196 }
197
198
199 void AliHLTScalars::Reset()
200 {
201         // Sets all the scalar values and rates to zero.
202         
203         for (Int_t i = 0; i < fScalars.GetEntriesFast(); ++i)
204         {
205                 AliScalar* scalar = static_cast<AliScalar*>( fScalars.UncheckedAt(i) );
206                 scalar->Value(0);
207         }
208 }
209
210
211 void AliHLTScalars::Clear(Option_t* option)
212 {
213         // Clears the array of scalars.
214
215         fMap.Clear();
216         fScalars.Delete(option);
217 }
218
219
220 void AliHLTScalars::Copy(TObject& object) const
221 {
222         // Performs a deep copy.
223         
224         if (object.IsA() != AliHLTScalars::Class())
225         {
226                 AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
227                 return;
228         }
229         AliHLTScalars* obj = static_cast<AliHLTScalars*>(&object);
230         obj->operator = (*this);
231 }
232
233
234 void AliHLTScalars::Print(Option_t* option) const
235 {
236         // Prints the HLT trigger scalars.
237
238         TIter next(&fScalars);
239         const AliScalar* scalar = NULL;
240
241         TString opt = option;
242         if (opt == "compact")
243         {
244                 scalar = static_cast<const AliScalar*>(next());
245                 if (scalar != NULL) cout << scalar->Value();
246                 while ((scalar = static_cast<const AliScalar*>(next())) != NULL)
247                 {
248                         cout << ", " << scalar->Value();
249                 }
250                 cout << endl;
251                 return;
252         }
253         
254         // Calculate the maximum field width required to keep things aligned.
255         int fieldwidth = 0;
256         while ((scalar = static_cast<const AliScalar*>(next())) != NULL)
257         {
258                 int length = strlen(scalar->Name()) + strlen(scalar->Description()) + 3;
259                 if (length > fieldwidth) fieldwidth = length;
260         }
261         if (fieldwidth > 80) fieldwidth = 80;
262         
263         cout << "HLT scalars:" << endl;
264         next.Reset();
265         while ((scalar = static_cast<const AliScalar*>(next())) != NULL)
266         {
267                 TString str = scalar->Description();
268                 str += " (";
269                 str += scalar->Name();
270                 str += ")";
271                 cout << setw(fieldwidth) << str.Data() << setw(0)
272                      << " = " << scalar->Value() << setw(0)
273                      << endl;
274         }
275         if (fScalars.GetSize() == 0) cout << "(none)" << endl;
276 }
277
278
279 AliHLTScalars& AliHLTScalars::operator = (const AliHLTScalars& obj)
280 {
281         // Performs a deep copy.
282         
283         if (this == &obj) return *this;
284         Clear();  // Remove existing scalars.
285         TObject::operator = (obj);
286         for (Int_t i = 0; i < obj.fScalars.GetEntriesFast(); ++i)
287         {
288                 const AliScalar* x = static_cast<const AliScalar*>(obj.fScalars.UncheckedAt(i));
289                 new (fScalars[i]) AliScalar(*x);
290         }
291         fMap.AddAll(&fScalars);
292         return *this;
293 }
294
295
296 Bool_t AliHLTScalars::IsEqual(const TObject *obj) const
297 {
298         // Checks if two sets of scalar lists have the same scalars.
299
300         assert(obj != NULL);
301         if (obj->IsA()->GetBaseClass(AliHLTScalars::Class()) == NULL)
302         {
303                 AliError(Form("Cannot compare object of type '%s'' with an object of type '%s'.",
304                               this->ClassName(), obj->ClassName()
305                         ));
306                 return kFALSE;
307         }
308         const AliHLTScalars* rhs = static_cast<const AliHLTScalars*>(obj);
309         if (fScalars.GetEntriesFast() != rhs->fScalars.GetEntriesFast()) return kFALSE;
310         TIter next(&fScalars);
311         const AliScalar* scalar = NULL;
312         while ((scalar = static_cast<const AliScalar*>(next())) != NULL)
313         {
314                 if (rhs->fScalars.FindObject(scalar->Name()) == NULL) return kFALSE;
315         }
316         return kTRUE;
317 }
318
319
320 bool AliHLTScalars::operator == (const AliHLTScalars& obj) const
321 {
322         // Compares two scalar lists to see that they have the same scalar values.
323
324         if (fScalars.GetEntriesFast() != obj.fScalars.GetEntriesFast()) return false;
325         TIter next(&fScalars);
326         const AliScalar* a = NULL;
327         while ((a = static_cast<const AliScalar*>(next())) != NULL)
328         {
329                 const AliScalar* b = static_cast<const AliScalar*>(
330                                 obj.fScalars.FindObject(a->Name())
331                         );
332                 if (b == NULL) return false;
333                 if (a->Value() != b->Value()) return false;
334         }
335         return true;
336 }
337
338
339 void AliHLTScalars::AliScalar::Copy(TObject& object) const
340 {
341         // Performs a deep copy.
342         
343         if (object.IsA() != AliHLTScalars::AliScalar::Class())
344         {
345                 AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
346                 return;
347         }
348         AliHLTScalars::AliScalar* obj = static_cast<AliHLTScalars::AliScalar*>(&object);
349         *obj = *this;
350 }