ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.14
Committed: Tue Feb 17 21:54:35 2009 UTC (16 years, 2 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.13: +12 -13 lines
Log Message:
Implemented much cleaner optimized auto loading of branches from refs

File Contents

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