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

# User Rev Content
1 bendavid 1.1 //--------------------------------------------------------------------------------------------------
2 loizides 1.9 // $Id: FastArray.h,v 1.8 2009/03/23 14:14:27 loizides Exp $
3 bendavid 1.1 //
4     // FastArray
5     //
6 loizides 1.3 // Implementation of a "fast" array on the heap: Memory is dynamically allocated,
7 bendavid 1.1 // but there is an optimization in the read streamer similar to the TClonesArray
8 loizides 1.3 // 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 loizides 1.9 // For various reasons, the array cannot be written in split mode.
13 loizides 1.3 // Array is meant to store classes as opposed to FastArrayBasic which should be
14     // used to hold basic types.
15 bendavid 1.1 //
16     // Authors: J.Bendavid
17     //--------------------------------------------------------------------------------------------------
18    
19 loizides 1.4 #ifndef MITANA_DATACONT_FASTARRAY_H
20     #define MITANA_DATACONT_FASTARRAY_H
21 bendavid 1.1
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 loizides 1.3 void Clear(Option_t */*opt*/="") { fSize=0; Init(0); }
43     UInt_t Entries() const { return fSize; }
44 loizides 1.5 UInt_t GetEntries() const { return fSize; }
45 bendavid 1.1 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 loizides 1.6 void Reset();
52 bendavid 1.1 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 loizides 1.3 const TClass *fClass; //!pointer to TClass object used by streamer
65 bendavid 1.1 UShort_t fCapacity; //!size of heap allocated
66     UShort_t fNObjects; //!number of allocated objects
67 loizides 1.3 ArrayElement *fArray; //!the array on the heap
68 bendavid 1.1
69 loizides 1.3 ClassDef(FastArray,1) // Array on heap for arbitrary classes
70 bendavid 1.1 };
71     }
72    
73     //--------------------------------------------------------------------------------------------------
74     template<class ArrayElement>
75     inline mithep::FastArray<ArrayElement>::FastArray() :
76 loizides 1.3 fSize(0),
77 bendavid 1.1 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 loizides 1.3 fSize(0),
89 bendavid 1.1 fClass(a.fClass),
90     fCapacity(0),
91     fNObjects(0),
92     fArray(0)
93     {
94     // Copy constructor. Copy only elements which are used.
95 loizides 1.3
96 bendavid 1.2 Init(a.fSize);
97 bendavid 1.1 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 loizides 1.3 // Construct additional blank objects for read streamer.
106 bendavid 1.1
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 loizides 1.7 BaseCollection::Clear();
124 bendavid 1.1 }
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 loizides 1.7 BaseCollection::Clear();
149 bendavid 1.1 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 loizides 1.3 // Expand or shrink the array to the given number of elements.
189 bendavid 1.1
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 loizides 1.8 fCapacity * sizeof(ArrayElement)));
205 bendavid 1.1 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 loizides 1.8 if (fSize < fNObjects)
216 bendavid 1.1 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 loizides 1.8 // Initialize heap array.
240 bendavid 1.1
241     if (fArray && fCapacity != s) {
242     for (UInt_t i=0; i<fNObjects; ++i)
243     fArray[i].~ArrayElement();
244     TStorage::Dealloc(fArray);
245 loizides 1.8 fArray = 0;
246 bendavid 1.1 fNObjects = 0;
247     }
248    
249     fCapacity = s;
250    
251     if ( !fArray && fCapacity > 0 )
252 loizides 1.3 fArray = static_cast<ArrayElement*>(TStorage::Alloc(fCapacity*sizeof(ArrayElement)));
253 bendavid 1.1 }
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 loizides 1.6 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 bendavid 1.1 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