ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.15
Committed: Thu Feb 26 17:05:18 2009 UTC (16 years, 2 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.14: +45 -51 lines
Log Message:
Add FastArray (optimized heap array) and switch RefArray to use FastArray

File Contents

# User Rev Content
1 loizides 1.1 //--------------------------------------------------------------------------------------------------
2 bendavid 1.15 // $Id: RefArray.h,v 1.14 2009/02/17 21:54:35 bendavid Exp $
3 loizides 1.1 //
4     // RefArray
5     //
6     // Implementation of a TRefArray using stack (and not heap) memory.
7 bendavid 1.7 // The maximum number of references is left as a template parameter.
8     // Since all of the stack allocation is handled by the StackArrays
9     // the RefArray itself can now actually be split.
10     //
11     // RefArray now supports objects from multiple PIDs, but only a single PID will be stored as long
12     // as only objects from a single PID are added.
13 loizides 1.1 //
14     // Authors: C.Loizides, J.Bendavid
15     //--------------------------------------------------------------------------------------------------
16    
17 loizides 1.2 #ifndef MITANA_DATACONT_REFARRAY
18     #define MITANA_DATACONT_REFARRAY
19 loizides 1.1
20     #include <TObject.h>
21     #include <TRefArray.h>
22     #include <TRefTable.h>
23     #include <TProcessID.h>
24     #include <TError.h>
25 bendavid 1.14 #include "MitAna/TAM/interface/TAMSelector.h"
26 loizides 1.1 #include "MitAna/DataCont/interface/Collection.h"
27 bendavid 1.15 #include "MitAna/DataCont/interface/FastArray.h"
28     #include "MitAna/DataCont/interface/FastArrayBasic.h"
29 bendavid 1.7 #include "MitAna/DataCont/interface/ProcIDRef.h"
30 loizides 1.1
31     namespace mithep
32     {
33 bendavid 1.15 template<class ArrayElement>
34 loizides 1.10 class RefArray /*: public Collection<ArrayElement> TODO to be enabled for Mit_008*/
35 loizides 1.1 {
36     public:
37     RefArray();
38 bendavid 1.7 virtual ~RefArray() {}
39 loizides 1.1
40 loizides 1.9 void Add(const ArrayElement *ae);
41 loizides 1.1 ArrayElement *At(UInt_t idx);
42 loizides 1.8 const ArrayElement *At(UInt_t idx) const;
43 bendavid 1.15 void Clear(Option_t */*opt*/="") { fPIDs.Clear(); fUIDs.Clear(); }
44 loizides 1.8 UInt_t Entries() const { return GetEntries(); }
45     UInt_t GetEntries() const { return fUIDs.GetEntries(); }
46 bendavid 1.15 UInt_t GetSize() const { return fUIDs.GetSize(); }
47 bendavid 1.12 Bool_t HasObject(const ArrayElement *obj) const;
48 loizides 1.8 Bool_t IsOwner() const { return kTRUE; }
49 loizides 1.10 TObject *ObjAt(UInt_t idx);
50     const TObject *ObjAt(UInt_t idx) const;
51 bendavid 1.7 void Reset();
52 bendavid 1.15 void Trim() { fPIDs.Trim(); fUIDs.Trim(); }
53 loizides 1.1 ArrayElement *UncheckedAt(UInt_t idx);
54 loizides 1.8 const ArrayElement *UncheckedAt(UInt_t idx) const;
55 loizides 1.1 ArrayElement *operator[](UInt_t idx);
56 loizides 1.8 const ArrayElement *operator[](UInt_t idx) const;
57 loizides 1.1
58     protected:
59 loizides 1.8 TObject *GetObject(UInt_t idx) const;
60 bendavid 1.12 TProcessID *GetPID(UInt_t idx) const;
61 loizides 1.8 UInt_t GetUID(UInt_t idx) const;
62 loizides 1.1
63 bendavid 1.15 FastArray<ProcIDRef> fPIDs;//|| process ids of referenced objects
64     FastArrayBasic<UInt_t> fUIDs;//|| unique ids of referenced objects
65 loizides 1.1
66 loizides 1.10 ClassDef(RefArray, 2) // Implementation of our own TRefArray
67 loizides 1.1 };
68     }
69    
70     //--------------------------------------------------------------------------------------------------
71 bendavid 1.15 template<class ArrayElement>
72     inline mithep::RefArray<ArrayElement>::RefArray()
73 loizides 1.1 {
74 loizides 1.8 // Default constructor.
75 loizides 1.1 }
76    
77     //--------------------------------------------------------------------------------------------------
78 bendavid 1.15 template<class ArrayElement>
79     void mithep::RefArray<ArrayElement>::Add(const ArrayElement *ae)
80 loizides 1.1 {
81     // Add new reference to object.
82    
83     // check if the object can belong here and assign or get its uid
84     if (ae->TestBit(kHasUUID)) {
85 loizides 1.8 Fatal("Add", "Object can not be added as it has not UUID!");
86 loizides 1.1 return;
87     }
88    
89 bendavid 1.7 UInt_t uid = 0;
90     TProcessID *pid = 0;
91 loizides 1.1 if (ae->TestBit(kIsReferenced)) {
92     uid = ae->GetUniqueID();
93 loizides 1.9 pid = TProcessID::GetProcessWithUID(uid, const_cast<ArrayElement*>(ae));
94 loizides 1.1 } else {
95 bendavid 1.7 pid = TProcessID::GetSessionProcessID();
96 loizides 1.9 uid = TProcessID::AssignID(const_cast<ArrayElement*>(ae));
97 loizides 1.1 }
98    
99 loizides 1.8 // If RefArray contains one and only one PID reference, then only add another if the added object
100     // has a different PID. When this occurs all of the extra spaces which had been left empty get
101     // filled in with the original PID
102 bendavid 1.7 if (fPIDs.GetEntries()==1) {
103     if (pid != fPIDs.At(0)->Pid() ) {
104     while (fPIDs.GetEntries()<GetEntries())
105 bendavid 1.15 fPIDs.GetNew()->SetPid(fPIDs.At(0)->Pid());
106 bendavid 1.7
107 bendavid 1.15 fPIDs.GetNew()->SetPid(pid);
108 bendavid 1.7 }
109     }
110     else
111 bendavid 1.15 fPIDs.GetNew()->SetPid(pid);
112 bendavid 1.7
113     fUIDs.Add(uid);
114 loizides 1.1 }
115    
116     //--------------------------------------------------------------------------------------------------
117 bendavid 1.15 template<class ArrayElement>
118     inline ArrayElement *mithep::RefArray<ArrayElement>::At(UInt_t idx)
119 loizides 1.1 {
120     // Return entry at given index.
121    
122 loizides 1.10 if (idx<GetEntries())
123 loizides 1.1 return static_cast<ArrayElement*>(GetObject(idx));
124    
125 loizides 1.11 Fatal("At", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
126 loizides 1.1 return 0;
127     }
128    
129     //--------------------------------------------------------------------------------------------------
130 bendavid 1.15 template<class ArrayElement>
131     inline const ArrayElement *mithep::RefArray<ArrayElement>::At(UInt_t idx) const
132 loizides 1.1 {
133     // Return entry at given index.
134    
135 loizides 1.10 if (idx<GetEntries())
136 loizides 1.1 return static_cast<const ArrayElement*>(GetObject(idx));
137    
138 loizides 1.11 Fatal("At", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
139 loizides 1.1 return 0;
140     }
141    
142     //--------------------------------------------------------------------------------------------------
143 bendavid 1.15 template<class ArrayElement>
144     TObject *mithep::RefArray<ArrayElement>::GetObject(UInt_t idx) const
145 loizides 1.1 {
146     // Return entry at given index. Code adapted from TRef::GetObject().
147 loizides 1.8
148 bendavid 1.12 TProcessID *pid = GetPID(idx);
149 loizides 1.1
150 bendavid 1.7 if (!pid) {
151 loizides 1.8 Fatal("GetObject","Process id pointer is null!");
152 loizides 1.1 return 0;
153     }
154    
155 bendavid 1.7 if (!TProcessID::IsValid(pid)) {
156 loizides 1.8 Fatal("GetObject","Process id is invalid!");
157 loizides 1.1 return 0;
158     }
159 loizides 1.8
160 loizides 1.1 UInt_t uid = GetUID(idx);
161    
162 bendavid 1.14 //try to autoload from TAM
163     TAMSelector *tSel = TAMSelector::GetEvtSelector();
164     if (tSel) {
165     return tSel->GetObjectWithID(uid,pid);
166     }
167    
168     //no TAM proxy present, fall back to standard Root calls
169    
170 loizides 1.1 //the reference may be in the TRefTable
171     TRefTable *table = TRefTable::GetRefTable();
172     if (table) {
173 bendavid 1.7 table->SetUID(uid, pid);
174 loizides 1.1 table->Notify();
175     }
176    
177 bendavid 1.14 return pid->GetObjectWithID(uid);
178    
179 loizides 1.1 }
180    
181     //--------------------------------------------------------------------------------------------------
182 bendavid 1.15 template<class ArrayElement>
183     inline TProcessID *mithep::RefArray<ArrayElement>::GetPID(UInt_t idx) const
184 bendavid 1.12 {
185     // Return pid corresponding to idx.
186    
187     TProcessID *pid = 0;
188     if (fPIDs.GetEntries()>1)
189 bendavid 1.15 pid = fPIDs.UncheckedAt(idx)->Pid();
190 bendavid 1.12 else
191 bendavid 1.15 pid = fPIDs.UncheckedAt(0)->Pid();
192 bendavid 1.12
193     return pid;
194     }
195    
196     //--------------------------------------------------------------------------------------------------
197 bendavid 1.15 template<class ArrayElement>
198     inline UInt_t mithep::RefArray<ArrayElement>::GetUID(UInt_t idx) const
199 loizides 1.1 {
200     // Return uid corresponding to idx.
201    
202 bendavid 1.15 return fUIDs.UncheckedAt(idx);
203 loizides 1.1 }
204    
205     //--------------------------------------------------------------------------------------------------
206 bendavid 1.15 template<class ArrayElement>
207     Bool_t mithep::RefArray<ArrayElement>::HasObject(const ArrayElement *obj) const
208 bendavid 1.12 {
209     // check whether RefArray contains a given object
210    
211     if (!obj->TestBit(kIsReferenced))
212     return kFALSE;
213    
214     UInt_t oUid = obj->GetUniqueID();
215     TProcessID *oPid = TProcessID::GetProcessWithUID(oUid, const_cast<ArrayElement*>(obj));
216    
217     for (UInt_t i=0; i<GetEntries(); ++i) {
218     if ( (GetUID(i)&0xffffff)==(oUid&0xffffff) && GetPID(i)->GetUniqueID()==oPid->GetUniqueID())
219     return kTRUE;
220     }
221    
222     return kFALSE;
223    
224     }
225    
226     //--------------------------------------------------------------------------------------------------
227 bendavid 1.15 template<class ArrayElement>
228     TObject *mithep::RefArray<ArrayElement>::ObjAt(UInt_t idx)
229 loizides 1.10 {
230     // Return object at given index.
231    
232     if (idx<GetEntries())
233     return GetObject(idx);
234    
235 loizides 1.11 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
236 loizides 1.10 return 0;
237     }
238    
239     //--------------------------------------------------------------------------------------------------
240 bendavid 1.15 template<class ArrayElement>
241     const TObject *mithep::RefArray<ArrayElement>::ObjAt(UInt_t idx) const
242 loizides 1.10 {
243     // Return object at given index.
244    
245     if (idx<GetEntries())
246     return static_cast<const TObject*>(GetObject(idx));
247    
248 loizides 1.11 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
249 loizides 1.10 return 0;
250     }
251    
252     //--------------------------------------------------------------------------------------------------
253 bendavid 1.15 template<class ArrayElement>
254     inline void mithep::RefArray<ArrayElement>::Reset()
255 loizides 1.1 {
256 loizides 1.8 fUIDs.Reset();
257     fPIDs.Reset();
258 loizides 1.1 }
259    
260     //--------------------------------------------------------------------------------------------------
261 bendavid 1.15 template<class ArrayElement>
262     inline ArrayElement *mithep::RefArray<ArrayElement>::UncheckedAt(UInt_t idx)
263 loizides 1.1 {
264     // Return entry at given index.
265    
266 loizides 1.8 return static_cast<ArrayElement*>(GetObject(idx));
267 loizides 1.1 }
268    
269 bendavid 1.7 //--------------------------------------------------------------------------------------------------
270 bendavid 1.15 template<class ArrayElement>
271     inline const ArrayElement *mithep::RefArray<ArrayElement>::UncheckedAt(UInt_t idx) const
272 bendavid 1.7 {
273 loizides 1.8 // Return entry at given index.
274    
275     return static_cast<const ArrayElement*>(GetObject(idx));
276 loizides 1.1 }
277    
278     //--------------------------------------------------------------------------------------------------
279 bendavid 1.15 template<class ArrayElement>
280     inline const ArrayElement *mithep::RefArray<ArrayElement>::operator[](UInt_t idx) const
281 loizides 1.1 {
282     // Return entry at given index.
283    
284 loizides 1.8 return At(idx);
285 loizides 1.1 }
286    
287     //--------------------------------------------------------------------------------------------------
288 bendavid 1.15 template<class ArrayElement>
289     inline ArrayElement *mithep::RefArray<ArrayElement>::operator[](UInt_t idx)
290 loizides 1.1 {
291     // Return entry at given index.
292    
293 loizides 1.8 return At(idx);
294 loizides 1.1 }
295     #endif