ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.12
Committed: Tue Feb 17 14:22:57 2009 UTC (16 years, 2 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.11: +56 -8 lines
Log Message:
Optimize RefArray dereferencing based on object table cleaning, add optimized HasObject function

File Contents

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