ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/FastArray.h
Revision: 1.3
Committed: Mon Mar 2 12:34:00 2009 UTC (16 years, 2 months ago) by loizides
Content type: text/plain
Branch: MAIN
Changes since 1.2: +21 -24 lines
Log Message:
Documentation, cleanup and object id removal.

File Contents

# User Rev Content
1 bendavid 1.1 //--------------------------------------------------------------------------------------------------
2 loizides 1.3 // $Id: FastArray.h,v 1.2 2009/02/27 09:16:30 bendavid 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     // For various reasons, the array can not 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 bendavid 1.1 //
16     // Authors: J.Bendavid
17     //--------------------------------------------------------------------------------------------------
18    
19     #ifndef MITANA_DATACONT_FASTARRAY
20     #define MITANA_DATACONT_FASTARRAY
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 loizides 1.3 void Clear(Option_t */*opt*/="") { fSize=0; Init(0); }
43     UInt_t Entries() const { return fSize; }
44     UInt_t GetEntries() const { return Entries(); }
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     void Reset() { fSize = 0; }
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 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     }
124     else
125     new(Allocate()) ArrayElement(ae);
126     }
127    
128     //--------------------------------------------------------------------------------------------------
129     template<class ArrayElement>
130     ArrayElement* mithep::FastArray<ArrayElement>::AddNew()
131     {
132     // Add new object.
133    
134     return new(Allocate()) ArrayElement();
135     }
136    
137     //--------------------------------------------------------------------------------------------------
138     template<class ArrayElement>
139     ArrayElement* mithep::FastArray<ArrayElement>::Allocate()
140     {
141     // Return next slot in the array, *only* to be used in placement new operator.
142    
143     if (fSize >= fCapacity)
144     Expand(TMath::Max(16,2*fCapacity));
145    
146     ++fSize;
147     fNObjects = TMath::Max(fNObjects,fSize);
148     return &fArray[fSize-1];
149     }
150    
151     //--------------------------------------------------------------------------------------------------
152     template<class ArrayElement>
153     inline ArrayElement *mithep::FastArray<ArrayElement>::At(UInt_t idx)
154     {
155     // Return entry at given index.
156    
157     if (idx<fSize)
158     return static_cast<ArrayElement*>(&fArray[idx]);
159    
160     ArrayElement tmp;
161     TObject::Fatal("At","Index too large: (%u < %u violated) for %s containing %s",
162     idx, fSize, this->GetName(), typeid(tmp).name());
163     return 0;
164     }
165    
166     //--------------------------------------------------------------------------------------------------
167     template<class ArrayElement>
168     inline const ArrayElement *mithep::FastArray<ArrayElement>::At(UInt_t idx) const
169     {
170     // Return entry at given index.
171    
172     if (idx<fSize)
173     return static_cast<const ArrayElement*>(&fArray[idx]);
174    
175     ArrayElement tmp;
176     TObject::Fatal("At","Index too large: (%u < %u violated) for %s containing %s",
177     idx, fSize, this->GetName(), typeid(tmp).name());
178     return 0;
179     }
180    
181     //--------------------------------------------------------------------------------------------------
182     template<class ArrayElement>
183     inline void mithep::FastArray<ArrayElement>::Expand(UShort_t s)
184     {
185    
186 loizides 1.3 // Expand or shrink the array to the given number of elements.
187 bendavid 1.1
188     if (s < fSize) {
189     TObject::Fatal("Expand", "Cannot shrink FastArray to less than fSize");
190     return;
191     }
192    
193     if (!fArray || s==0) {
194     Init(s);
195     return;
196     }
197    
198     if (fCapacity == s)
199     return;
200    
201     fArray = static_cast<ArrayElement*>(TStorage::ReAlloc(fArray, s * sizeof(ArrayElement),
202     fCapacity * sizeof(ArrayElement)));
203     fCapacity = s;
204     fNObjects = TMath::Min(fCapacity,fNObjects);
205     }
206    
207     //--------------------------------------------------------------------------------------------------
208     template<class ArrayElement>
209     ArrayElement* mithep::FastArray<ArrayElement>::GetNew()
210     {
211     // Return next slot in the array, *only* to be used in placement new operator.
212    
213     if (fSize < fCapacity)
214     return Allocate();
215     else
216     return AddNew();
217     }
218    
219     //--------------------------------------------------------------------------------------------------
220     template<class ArrayElement>
221     inline Bool_t mithep::FastArray<ArrayElement>::HasObject(const ArrayElement *obj) const
222     {
223     // Check whether object is in array.
224    
225     for (UInt_t i=0; i<fSize; ++i) {
226     if ( fArray[i].IsEqual(obj) )
227     return true;
228     }
229    
230     return false;
231     }
232    
233     //--------------------------------------------------------------------------------------------------
234     template<class ArrayElement>
235     inline void mithep::FastArray<ArrayElement>::Init(UShort_t s)
236     {
237    
238     // Initialize heap array
239    
240     if (fArray && fCapacity != s) {
241     for (UInt_t i=0; i<fNObjects; ++i)
242     fArray[i].~ArrayElement();
243     TStorage::Dealloc(fArray);
244     fArray = 0;
245     fNObjects = 0;
246     }
247    
248     fCapacity = s;
249    
250     if ( !fArray && fCapacity > 0 )
251 loizides 1.3 fArray = static_cast<ArrayElement*>(TStorage::Alloc(fCapacity*sizeof(ArrayElement)));
252 bendavid 1.1 }
253    
254     //--------------------------------------------------------------------------------------------------
255     template<class ArrayElement>
256     inline TObject *mithep::FastArray<ArrayElement>::ObjAt(UInt_t idx)
257     {
258     // Return object at given index.
259    
260     return static_cast<TObject*>(At(idx));
261     }
262    
263     //--------------------------------------------------------------------------------------------------
264     template<class ArrayElement>
265     inline const TObject *mithep::FastArray<ArrayElement>::ObjAt(UInt_t idx) const
266     {
267     // Return object at given index.
268    
269     return static_cast<const TObject*>(At(idx));
270     }
271    
272     //-------------------------------------------------------------------------------------------------
273     template<class ArrayElement>
274     void mithep::FastArray<ArrayElement>::Streamer(TBuffer &b)
275     {
276     // Stream all objects in the array to or from the I/O buffer.
277    
278     if (b.IsReading()) {
279     b >> fSize;
280     if (fSize) {
281     if (fSize > fCapacity)
282     Expand(TMath::Max(static_cast<Int_t>(fSize),2*fCapacity));
283    
284     while (fNObjects < fSize)
285     AddBlank();
286    
287     b.ReadFastArray(fArray,fClass,fSize);
288     }
289     } else { /*writing*/
290     b << fSize;
291     if (fSize) {
292     b.WriteFastArray(fArray,fClass,fSize);
293     }
294     }
295     }
296    
297     //--------------------------------------------------------------------------------------------------
298     template<class ArrayElement>
299     inline ArrayElement *mithep::FastArray<ArrayElement>::UncheckedAt(UInt_t idx)
300     {
301     // Return entry at given index.
302    
303     return static_cast<ArrayElement*>(&fArray[idx]);
304     }
305    
306     //--------------------------------------------------------------------------------------------------
307     template<class ArrayElement>
308     inline const ArrayElement *mithep::FastArray<ArrayElement>::UncheckedAt(UInt_t idx) const
309     {
310     // Return entry at given index.
311    
312     return static_cast<const ArrayElement*>(&fArray[idx]);
313     }
314    
315     //--------------------------------------------------------------------------------------------------
316     template<class ArrayElement>
317     inline const ArrayElement *mithep::FastArray<ArrayElement>::operator[](UInt_t idx) const
318     {
319     // Return entry at given index.
320    
321     return At(idx);
322     }
323    
324     //--------------------------------------------------------------------------------------------------
325     template<class ArrayElement>
326     inline ArrayElement *mithep::FastArray<ArrayElement>::operator[](UInt_t idx)
327     {
328     // Return entry at given index.
329    
330     return At(idx);
331     }
332     #endif