ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.13
Committed: Tue Feb 17 14:37:30 2009 UTC (16 years, 2 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.12: +6 -11 lines
Log Message:
Cleanup and add comments

File Contents

# User Rev Content
1 loizides 1.1 //--------------------------------------------------------------------------------------------------
2 bendavid 1.13 // $Id: RefArray.h,v 1.12 2009/02/17 14:22:57 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     #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 bendavid 1.13
170     //We are now assuming that the object table is cleaned so that all unloaded objects have null
171     //pointers in the object table
172     //This guarantees that the check below is valid for determining whether we need to go to the
173     //TRefTable
174 bendavid 1.12 if (obj)
175     return obj;
176    
177 loizides 1.1 //the reference may be in the TRefTable
178     TRefTable *table = TRefTable::GetRefTable();
179     if (table) {
180 bendavid 1.7 table->SetUID(uid, pid);
181 loizides 1.1 table->Notify();
182 bendavid 1.12 obj = pid->GetObjectWithID(uid);
183 loizides 1.1 }
184    
185     return obj;
186     }
187    
188     //--------------------------------------------------------------------------------------------------
189 bendavid 1.7 template<class ArrayElement, UInt_t N>
190 bendavid 1.12 inline TProcessID *mithep::RefArray<ArrayElement,N>::GetPID(UInt_t idx) const
191     {
192     // Return pid corresponding to idx.
193    
194     TProcessID *pid = 0;
195     if (fPIDs.GetEntries()>1)
196     pid = fPIDs.At(idx)->Pid();
197     else
198     pid = fPIDs.At(0)->Pid();
199    
200     return pid;
201     }
202    
203     //--------------------------------------------------------------------------------------------------
204     template<class ArrayElement, UInt_t N>
205 bendavid 1.7 inline UInt_t mithep::RefArray<ArrayElement,N>::GetUID(UInt_t idx) const
206 loizides 1.1 {
207     // Return uid corresponding to idx.
208    
209 bendavid 1.7 return fUIDs.At(idx);
210 loizides 1.1 }
211    
212     //--------------------------------------------------------------------------------------------------
213 bendavid 1.7 template<class ArrayElement, UInt_t N>
214 bendavid 1.12 Bool_t mithep::RefArray<ArrayElement,N>::HasObject(const ArrayElement *obj) const
215     {
216     // check whether RefArray contains a given object
217    
218     if (!obj->TestBit(kIsReferenced))
219     return kFALSE;
220    
221     UInt_t oUid = obj->GetUniqueID();
222     TProcessID *oPid = TProcessID::GetProcessWithUID(oUid, const_cast<ArrayElement*>(obj));
223    
224     for (UInt_t i=0; i<GetEntries(); ++i) {
225     if ( (GetUID(i)&0xffffff)==(oUid&0xffffff) && GetPID(i)->GetUniqueID()==oPid->GetUniqueID())
226     return kTRUE;
227     }
228    
229     return kFALSE;
230    
231     }
232    
233     //--------------------------------------------------------------------------------------------------
234     template<class ArrayElement, UInt_t N>
235 loizides 1.10 TObject *mithep::RefArray<ArrayElement,N>::ObjAt(UInt_t idx)
236     {
237     // Return object at given index.
238    
239     if (idx<GetEntries())
240     return GetObject(idx);
241    
242 loizides 1.11 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
243 loizides 1.10 return 0;
244     }
245    
246     //--------------------------------------------------------------------------------------------------
247     template<class ArrayElement,UInt_t N>
248     const TObject *mithep::RefArray<ArrayElement,N>::ObjAt(UInt_t idx) const
249     {
250     // Return object at given index.
251    
252     if (idx<GetEntries())
253     return static_cast<const TObject*>(GetObject(idx));
254    
255 loizides 1.11 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, GetEntries());
256 loizides 1.10 return 0;
257     }
258    
259     //--------------------------------------------------------------------------------------------------
260     template<class ArrayElement, UInt_t N>
261 loizides 1.8 inline void mithep::RefArray<ArrayElement,N>::Reset()
262 loizides 1.1 {
263 loizides 1.8 fUIDs.Reset();
264     fPIDs.Reset();
265 loizides 1.1 }
266    
267     //--------------------------------------------------------------------------------------------------
268 bendavid 1.7 template<class ArrayElement, UInt_t N>
269 loizides 1.8 inline ArrayElement *mithep::RefArray<ArrayElement,N>::UncheckedAt(UInt_t idx)
270 loizides 1.1 {
271     // Return entry at given index.
272    
273 loizides 1.8 return static_cast<ArrayElement*>(GetObject(idx));
274 loizides 1.1 }
275    
276 bendavid 1.7 //--------------------------------------------------------------------------------------------------
277     template<class ArrayElement, UInt_t N>
278 loizides 1.8 inline const ArrayElement *mithep::RefArray<ArrayElement,N>::UncheckedAt(UInt_t idx) const
279 bendavid 1.7 {
280 loizides 1.8 // Return entry at given index.
281    
282     return static_cast<const ArrayElement*>(GetObject(idx));
283 loizides 1.1 }
284    
285     //--------------------------------------------------------------------------------------------------
286 bendavid 1.7 template<class ArrayElement, UInt_t N>
287 loizides 1.8 inline const ArrayElement *mithep::RefArray<ArrayElement,N>::operator[](UInt_t idx) const
288 loizides 1.1 {
289     // Return entry at given index.
290    
291 loizides 1.8 return At(idx);
292 loizides 1.1 }
293    
294     //--------------------------------------------------------------------------------------------------
295 bendavid 1.7 template<class ArrayElement, UInt_t N>
296 loizides 1.8 inline ArrayElement *mithep::RefArray<ArrayElement,N>::operator[](UInt_t idx)
297 loizides 1.1 {
298     // Return entry at given index.
299    
300 loizides 1.8 return At(idx);
301 loizides 1.1 }
302     #endif