ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.23
Committed: Sun Sep 19 23:46:08 2010 UTC (14 years, 7 months ago) by bendavid
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_025c_branch2, Mit_025c_branch1, Mit_025c_branch0, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e
Branch point for: Mit_025c_branch
Changes since 1.22: +6 -2 lines
Log Message:
add hard protections for null pointers from refs

File Contents

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