ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/FastArray.h
Revision: 1.9
Committed: Mon Mar 23 22:15:09 2009 UTC (16 years, 1 month ago) by loizides
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_029b, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, 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, Mit_014d, Mit_014c, Mit_014b, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, Mit_012i, Mit_012h, Mit_012g, Mit_012f, Mit_012e, Mit_012d, Mit_012c, Mit_012b, Mit_012a, Mit_012, Mit_011a, Mit_011, Mit_010a, Mit_010, Mit_009c, Mit_009b, Mit_009a, Mit_009, Mit_008, HEAD
Branch point for: Mit_025c_branch
Changes since 1.8: +2 -2 lines
Log Message:
Cosmetics

File Contents

# Content
1 //--------------------------------------------------------------------------------------------------
2 // $Id: FastArray.h,v 1.8 2009/03/23 14:14:27 loizides Exp $
3 //
4 // FastArray
5 //
6 // Implementation of a "fast" array on the heap: Memory is dynamically allocated,
7 // but there is an optimization in the read streamer similar to the TClonesArray
8 // where the heap memory of an existing object is reused.
9 // This class is meant to be used as a datamember for objects which are contained
10 // inside a TClonesArray. It is assumed that those classed do not use heap memory
11 // themselves.
12 // For various reasons, the array cannot be written in split mode.
13 // Array is meant to store classes as opposed to FastArrayBasic which should be
14 // used to hold basic types.
15 //
16 // Authors: J.Bendavid
17 //--------------------------------------------------------------------------------------------------
18
19 #ifndef MITANA_DATACONT_FASTARRAY_H
20 #define MITANA_DATACONT_FASTARRAY_H
21
22 #include <TObject.h>
23 #include <TClass.h>
24 #include <TStorage.h>
25 #include "MitAna/DataCont/interface/Collection.h"
26
27 namespace mithep
28 {
29 template<class ArrayElement>
30 class FastArray : public Collection<ArrayElement>
31 {
32 public:
33 FastArray();
34 FastArray(const FastArray &a);
35 ~FastArray() { Init(0); }
36
37 void AddCopy(const ArrayElement &ae);
38 ArrayElement *AddNew();
39 ArrayElement *Allocate();
40 ArrayElement *At(UInt_t idx);
41 const ArrayElement *At(UInt_t idx) const;
42 void Clear(Option_t */*opt*/="") { fSize=0; Init(0); }
43 UInt_t Entries() const { return fSize; }
44 UInt_t GetEntries() const { return fSize; }
45 ArrayElement *GetNew();
46 UInt_t GetSize() const { return fCapacity; }
47 Bool_t HasObject(const ArrayElement *obj) const;
48 Bool_t IsOwner() const { return kTRUE; }
49 TObject *ObjAt(UInt_t idx);
50 const TObject *ObjAt(UInt_t idx) const;
51 void Reset();
52 void Trim() { Expand(fSize); }
53 ArrayElement *UncheckedAt(UInt_t idx);
54 const ArrayElement *UncheckedAt(UInt_t idx) const;
55 ArrayElement *operator[](UInt_t idx);
56 const ArrayElement *operator[](UInt_t idx) const;
57
58 protected:
59 ArrayElement *AddBlank();
60 void Init(UShort_t s);
61 void Expand(UShort_t s);
62
63 UShort_t fSize; //size of array
64 const TClass *fClass; //!pointer to TClass object used by streamer
65 UShort_t fCapacity; //!size of heap allocated
66 UShort_t fNObjects; //!number of allocated objects
67 ArrayElement *fArray; //!the array on the heap
68
69 ClassDef(FastArray,1) // Array on heap for arbitrary classes
70 };
71 }
72
73 //--------------------------------------------------------------------------------------------------
74 template<class ArrayElement>
75 inline mithep::FastArray<ArrayElement>::FastArray() :
76 fSize(0),
77 fClass(TClass::GetClass(typeid(ArrayElement))),
78 fCapacity(0),
79 fNObjects(0),
80 fArray(0)
81 {
82 // Default constructor.
83 }
84
85 //--------------------------------------------------------------------------------------------------
86 template<class ArrayElement>
87 inline mithep::FastArray<ArrayElement>::FastArray(const FastArray &a) :
88 fSize(0),
89 fClass(a.fClass),
90 fCapacity(0),
91 fNObjects(0),
92 fArray(0)
93 {
94 // Copy constructor. Copy only elements which are used.
95
96 Init(a.fSize);
97 for (UInt_t i=0; i<a.fSize; ++i)
98 new(Allocate()) ArrayElement(a.fArray[i]);
99 }
100
101 //--------------------------------------------------------------------------------------------------
102 template<class ArrayElement>
103 ArrayElement* mithep::FastArray<ArrayElement>::AddBlank()
104 {
105 // Construct additional blank objects for read streamer.
106
107 if (fNObjects >= fCapacity)
108 Expand(TMath::Max(16,2*fCapacity));
109
110 ++fNObjects;
111 return new(&fArray[fNObjects-1]) ArrayElement();
112 }
113
114 //--------------------------------------------------------------------------------------------------
115 template<class ArrayElement>
116 void mithep::FastArray<ArrayElement>::AddCopy(const ArrayElement &ae)
117 {
118 // Add a copy of an existing object.
119
120 if (fSize<fNObjects) {
121 fArray[fSize] = ae;
122 ++fSize;
123 BaseCollection::Clear();
124 }
125 else
126 new(Allocate()) ArrayElement(ae);
127 }
128
129 //--------------------------------------------------------------------------------------------------
130 template<class ArrayElement>
131 ArrayElement* mithep::FastArray<ArrayElement>::AddNew()
132 {
133 // Add new object.
134
135 return new(Allocate()) ArrayElement();
136 }
137
138 //--------------------------------------------------------------------------------------------------
139 template<class ArrayElement>
140 ArrayElement* mithep::FastArray<ArrayElement>::Allocate()
141 {
142 // Return next slot in the array, *only* to be used in placement new operator.
143
144 if (fSize >= fCapacity)
145 Expand(TMath::Max(16,2*fCapacity));
146
147 ++fSize;
148 BaseCollection::Clear();
149 fNObjects = TMath::Max(fNObjects,fSize);
150 return &fArray[fSize-1];
151 }
152
153 //--------------------------------------------------------------------------------------------------
154 template<class ArrayElement>
155 inline ArrayElement *mithep::FastArray<ArrayElement>::At(UInt_t idx)
156 {
157 // Return entry at given index.
158
159 if (idx<fSize)
160 return static_cast<ArrayElement*>(&fArray[idx]);
161
162 ArrayElement tmp;
163 TObject::Fatal("At","Index too large: (%u < %u violated) for %s containing %s",
164 idx, fSize, this->GetName(), typeid(tmp).name());
165 return 0;
166 }
167
168 //--------------------------------------------------------------------------------------------------
169 template<class ArrayElement>
170 inline const ArrayElement *mithep::FastArray<ArrayElement>::At(UInt_t idx) const
171 {
172 // Return entry at given index.
173
174 if (idx<fSize)
175 return static_cast<const ArrayElement*>(&fArray[idx]);
176
177 ArrayElement tmp;
178 TObject::Fatal("At","Index too large: (%u < %u violated) for %s containing %s",
179 idx, fSize, this->GetName(), typeid(tmp).name());
180 return 0;
181 }
182
183 //--------------------------------------------------------------------------------------------------
184 template<class ArrayElement>
185 inline void mithep::FastArray<ArrayElement>::Expand(UShort_t s)
186 {
187
188 // Expand or shrink the array to the given number of elements.
189
190 if (s < fSize) {
191 TObject::Fatal("Expand", "Cannot shrink FastArray to less than fSize");
192 return;
193 }
194
195 if (!fArray || s==0) {
196 Init(s);
197 return;
198 }
199
200 if (fCapacity == s)
201 return;
202
203 fArray = static_cast<ArrayElement*>(TStorage::ReAlloc(fArray, s * sizeof(ArrayElement),
204 fCapacity * sizeof(ArrayElement)));
205 fCapacity = s;
206 fNObjects = TMath::Min(fCapacity,fNObjects);
207 }
208
209 //--------------------------------------------------------------------------------------------------
210 template<class ArrayElement>
211 ArrayElement* mithep::FastArray<ArrayElement>::GetNew()
212 {
213 // Return next slot in the array, *only* to be used in placement new operator.
214
215 if (fSize < fNObjects)
216 return Allocate();
217 else
218 return AddNew();
219 }
220
221 //--------------------------------------------------------------------------------------------------
222 template<class ArrayElement>
223 inline Bool_t mithep::FastArray<ArrayElement>::HasObject(const ArrayElement *obj) const
224 {
225 // Check whether object is in array.
226
227 for (UInt_t i=0; i<fSize; ++i) {
228 if ( fArray[i].IsEqual(obj) )
229 return true;
230 }
231
232 return false;
233 }
234
235 //--------------------------------------------------------------------------------------------------
236 template<class ArrayElement>
237 inline void mithep::FastArray<ArrayElement>::Init(UShort_t s)
238 {
239 // Initialize heap array.
240
241 if (fArray && fCapacity != s) {
242 for (UInt_t i=0; i<fNObjects; ++i)
243 fArray[i].~ArrayElement();
244 TStorage::Dealloc(fArray);
245 fArray = 0;
246 fNObjects = 0;
247 }
248
249 fCapacity = s;
250
251 if ( !fArray && fCapacity > 0 )
252 fArray = static_cast<ArrayElement*>(TStorage::Alloc(fCapacity*sizeof(ArrayElement)));
253 }
254
255 //--------------------------------------------------------------------------------------------------
256 template<class ArrayElement>
257 inline TObject *mithep::FastArray<ArrayElement>::ObjAt(UInt_t idx)
258 {
259 // Return object at given index.
260
261 return static_cast<TObject*>(At(idx));
262 }
263
264 //--------------------------------------------------------------------------------------------------
265 template<class ArrayElement>
266 inline const TObject *mithep::FastArray<ArrayElement>::ObjAt(UInt_t idx) const
267 {
268 // Return object at given index.
269
270 return static_cast<const TObject*>(At(idx));
271 }
272
273 //-------------------------------------------------------------------------------------------------
274 template<class ArrayElement>
275 void mithep::FastArray<ArrayElement>::Reset()
276 {
277 // Reset this array.
278
279 fSize = 0;
280 BaseCollection::Clear();
281 }
282
283 //-------------------------------------------------------------------------------------------------
284 template<class ArrayElement>
285 void mithep::FastArray<ArrayElement>::Streamer(TBuffer &b)
286 {
287 // Stream all objects in the array to or from the I/O buffer.
288
289 if (b.IsReading()) {
290 b >> fSize;
291 if (fSize) {
292 if (fSize > fCapacity)
293 Expand(TMath::Max(static_cast<Int_t>(fSize),2*fCapacity));
294
295 while (fNObjects < fSize)
296 AddBlank();
297
298 b.ReadFastArray(fArray,fClass,fSize);
299 }
300 } else { /*writing*/
301 b << fSize;
302 if (fSize) {
303 b.WriteFastArray(fArray,fClass,fSize);
304 }
305 }
306 }
307
308 //--------------------------------------------------------------------------------------------------
309 template<class ArrayElement>
310 inline ArrayElement *mithep::FastArray<ArrayElement>::UncheckedAt(UInt_t idx)
311 {
312 // Return entry at given index.
313
314 return static_cast<ArrayElement*>(&fArray[idx]);
315 }
316
317 //--------------------------------------------------------------------------------------------------
318 template<class ArrayElement>
319 inline const ArrayElement *mithep::FastArray<ArrayElement>::UncheckedAt(UInt_t idx) const
320 {
321 // Return entry at given index.
322
323 return static_cast<const ArrayElement*>(&fArray[idx]);
324 }
325
326 //--------------------------------------------------------------------------------------------------
327 template<class ArrayElement>
328 inline const ArrayElement *mithep::FastArray<ArrayElement>::operator[](UInt_t idx) const
329 {
330 // Return entry at given index.
331
332 return At(idx);
333 }
334
335 //--------------------------------------------------------------------------------------------------
336 template<class ArrayElement>
337 inline ArrayElement *mithep::FastArray<ArrayElement>::operator[](UInt_t idx)
338 {
339 // Return entry at given index.
340
341 return At(idx);
342 }
343 #endif