]> git.uio.no Git - u/mrichter/AliRoot.git/blob - CONTAINERS/AliMemArray.cxx
Removing PYTHIA
[u/mrichter/AliRoot.git] / CONTAINERS / AliMemArray.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Log$
18 Revision 1.2  2001/01/10 09:33:56  kowal2
19 Clear method modified to fix the problem with reading Tree.
20
21 Revision 1.1  2000/11/01 16:01:26  kowal2
22 Classes for handling the new hits structures
23
24 */
25 ///////////////////////////////////////////////////////////////////////////////
26 //                                                                           //
27 //  AliMemArray                                                              //                      
28 //  (Pseudo)Container optimised for fast  random access operator[ ]. 
29 //  Operator []  time doesn\92t depend on the number of elements in container O(1) - 
30 //    like in standard array or like in STL vector
31 //   To achieve maximally-fast indexing and iteration in one buffer mode  
32 //   the vector maintains its storage as a single contiguous array of objects (one buffer mode)
33
34 //   When a vector runs out of pre-allocated storage, in order to maintain it 
35 //   contiguous array it must allocate a whole new (larger) chunk of storage  
36 //   elsewhere and copy the objects to the new storage.
37 //       void *  AliMemArray::Unchecked1DAt(UInt_t i) const                    
38 //             return  &(((char*)fCont)[fObjectSize*i]);
39
40 //   In multi buffer mode (like two dimensional array) when a vector runs out of 
41 //   pre-allocated storage we don\92t need to copy whole array only small buffer but operator [] is slower
42 //       void *  AliMemArray::Unchecked2DAt(UInt_t i, UInt_t j) const                    
43 //       return &(  ((char**)fCont)[i] [j*fObjectSize]); 
44 //       void  *  AliMemArray::Unchecked2DAt(UInt_t i) const 
45 //       return &(  ((char**)fCont)[i/fBufferSize] [(i%fBufferSize)*fObjectSize])  ;
46
47
48 //Begin_Html
49 //<img src="../gif/AliMemArray.gif">
50 //End_Html
51
52    
53 //  Streamer CTORBuffer and DTORBuffer are  virtual - should be implemented in derived
54 //  classes. For example AliObjectArray derived from AliMemArray is general array 
55 //  for objects with defined AliClassInfo information. 
56 //                                                                           //
57 //                                                                          //
58 //  Origin:  Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk // 
59 ///////////////////////////////////////////////////////////////////////////////
60
61
62
63 #include "AliMemArray.h"
64 #include "Riostream.h"
65 #include "TMath.h"
66 #include "TError.h"
67
68
69 ClassImp(AliMemArray)
70  
71
72 AliMemArray::AliMemArray()
73
74   //
75   //default constructor
76   //
77   fCont = 0;
78   fSize = 0;
79   fCapacity=0;
80   fObjectSize = 0;
81   fBufferSize = 0;
82 }
83
84 AliMemArray::AliMemArray(Int_t objectSize, Int_t buffersize)
85 {
86   //
87   // AliMemArray constructor 
88   fCont = 0;
89   fSize = 0;
90   fCapacity=0;
91   fObjectSize =objectSize;
92   fBufferSize  =buffersize;
93 }
94
95 AliMemArray::AliMemArray(const AliMemArray & arr) 
96 {
97   //
98   //copy constructor
99   fCont = arr.fCont;
100   fSize = arr.fSize;
101   fCapacity = arr.fCapacity;
102   fObjectSize = arr.fObjectSize;
103   fBufferSize =arr.fBufferSize;
104   
105   if (arr.fBufferSize==0) {
106     fCont = new char[fCapacity*fObjectSize];
107     CopyBuffer(fCont, arr.fCont, fSize);
108   }
109   else{ 
110     Int_t buffers = fCapacity/fBufferSize;
111     if (fCapacity%fBufferSize) buffers++;     
112     void ** table  = (void**) new char*[buffers];   
113     for (Int_t i=0; i<buffers;i++){
114       table[i] = new char[fBufferSize*fObjectSize];
115       Int_t size = fSize - i*fBufferSize;
116       if (size > (Int_t)fBufferSize) size = fBufferSize;
117       if (size >0) CopyBuffer(table[i], ((void**)arr.fCont)[i],size);
118     }
119     fCont = (void*)table;
120   }
121 }
122     
123
124 void AliMemArray::Swap(  AliMemArray &arr)
125 {
126   //swap contents of array
127   UInt_t size = arr.fSize;
128   arr.fSize = fSize;
129   fSize = size;
130   UInt_t capacity = arr.fCapacity;
131   arr.fCapacity = fCapacity;
132   fCapacity = capacity;
133   UInt_t objectSize = arr.fObjectSize;
134   arr.fObjectSize = fObjectSize;
135   fObjectSize = objectSize;
136   UInt_t bufferSize = arr.fBufferSize;
137   arr.fBufferSize = fBufferSize;
138   fBufferSize = bufferSize;
139   void * cont = arr.fCont;
140   arr.fCont = fCont;
141   fCont = cont;
142 }
143
144 void     AliMemArray::CopyBuffer(void *dest, void *src,  UInt_t size)
145 {
146   //
147   //array placement copy constructor
148   memcpy(dest, src,size*fObjectSize);
149 }
150
151 AliMemArray::~AliMemArray()  
152 {
153   //
154   //default destructor
155   Delete();
156 }
157
158
159 void   AliMemArray::SetObjectSize(UInt_t  bufsize)
160 {
161   //
162   //set memory size for one object - it can be changed only when the array is empty 
163   if (fCont){
164     ::Error("AliMemArray::SetObjectSize", "forbidden to resize just allocated objects");
165     return;
166   };
167   fBufferSize=bufsize;
168 }
169
170 AliMemArray & AliMemArray::operator = (const AliMemArray &arr)
171 {
172   //
173   //
174   AliMemArray  tmparr(arr);
175   Swap(tmparr);
176   return *this;
177 }
178
179 void   AliMemArray::SetBufferSize(UInt_t  bufsize)
180 {
181   //
182   //set buffer size - it can be changed only when the array is empty 
183   if (fCont==0) {
184     fBufferSize = bufsize;
185     return;
186   }
187   if (fBufferSize == bufsize) return;
188   
189   if (bufsize==0){
190     char *table = new char[fObjectSize*fCapacity];
191     char * p = table;
192     for (UInt_t i=0; i<fSize; i++,p+=fObjectSize) 
193       memcpy(p, At(i), fObjectSize);
194     //delete [](char*)fCont;
195     Delete();
196     fCont = table;
197     fBufferSize = bufsize;
198   }
199   else{
200     Int_t buffers = fCapacity/bufsize;
201     if (fCapacity%bufsize) buffers++;     
202     char ** table  =  new char*[buffers];   
203     for (Int_t ibuf=0; ibuf<buffers;ibuf++){
204       table[ibuf] = new char[bufsize*fObjectSize];
205       Int_t size = fSize - ibuf*bufsize;
206       if (size > (Int_t)bufsize) size = bufsize;      
207       if (size >0) for ( Int_t ip=0;ip<size;ip++)
208         memcpy(&table[ibuf][ip*fObjectSize], At(ibuf*bufsize+ip), fObjectSize);
209     }
210     //    delete [](char**)fCont;
211     Delete();
212     fCont = (void*)table;
213     fBufferSize = bufsize;
214   }
215
216 }
217
218
219
220 void AliMemArray::Delete(Option_t *)
221 {
222   //
223   //delete memory space occupied by the array  - 
224   //Use this routine when your objects allocate
225   //memory (e.g. objects inheriting from TNamed or containing TStrings
226   //allocate memory). If not you better use Clear() since if is faster.  
227   if (fCont){
228     if (fBufferSize) {
229       Delete2D();
230       fSize = 0;
231       fCapacity = 0;
232       return;
233     }
234     DTORBuffer(Unchecked1DAt(0),fSize);
235     delete [] (char*)fCont;
236     fCont = 0;
237     fSize = 0;
238     fCapacity = 0;
239   }
240 }
241
242 void AliMemArray::Clear(Option_t *)
243 {
244   //
245   //clear array   - 
246   // Only use this routine when your objects don't
247   // allocate memory since it will not call the object dtors.
248   if (fBufferSize){
249     Clear2D();
250     return;
251   }
252   if (fCont){
253     //    memset(fCont, 0, fSize*fObjectSize);
254     //MI change - to have the same as in TClonesArray
255     fSize = 0;
256   }
257 }
258
259 void AliMemArray::Reserve(UInt_t  n)
260 {
261   //
262   //reserve arrays space
263   //  
264   if (fObjectSize<=0) {
265     cout<<"Object length not defined\n";
266     return;
267   }
268   if (n==fCapacity) return;
269   
270   if (fBufferSize>0) {
271     Reserve2D(n); //if 2D buffer
272     return;
273   }
274   //
275   if (fCapacity){
276     if (fSize>n) {
277       DTORBuffer(Unchecked1DAt(n),fSize-n);
278       memset(&((char*)fCont)[n*fObjectSize], 0, (fSize-n)*fObjectSize); 
279       fSize =n;
280     }
281     fCont = (char*)TStorage::ReAlloc(fCont, n*fObjectSize,fCapacity*fObjectSize); 
282   }
283   else  fCont = new char[n*fObjectSize];
284
285   if (!fCont) fCapacity = 0;
286   else fCapacity = n;
287 }
288
289
290 void AliMemArray::Resize(UInt_t  n)
291 {
292   //
293   //resize buffer
294   //   
295   if (fObjectSize<=0) {
296     cout<<"Object length not defined\n";
297     return;
298   }
299   if (fBufferSize>0) {
300      Resize2D(n); //if 2D buffer
301      return;
302   }
303   //
304   if (n>fCapacity) Reserve(n);   //reserve automaticaly space if sie >capacity
305   if (fSize>n){ 
306     DTORBuffer(Unchecked1DAt(n),fSize-n);
307     //memset(&((char*)fCont)[n*fObjectSize], 0, (fSize-n)*fObjectSize);
308     //MI change - to have the same as in TClonesArray
309   }
310   if (fSize<n)    CTORBuffer(Unchecked1DAt(fSize),n-fSize);     
311   fSize = n;
312   return; 
313 }
314
315 void AliMemArray::Delete2D()
316 {
317   //
318   //delete memory space occupied by the array 
319   if (!fBufferSize) return;
320
321   Int_t  nbuff = (fCapacity/fBufferSize);
322   if ( (fCapacity%fBufferSize)!=0) nbuff++;
323   for (Int_t  i=0;i<nbuff;i++) {    
324     Int_t size = fSize-i*fBufferSize;
325     if  (size>0)
326       DTORBuffer(GetRow(i),UInt_t(size)<fBufferSize? size:fBufferSize);    
327     delete [] (char*)GetRow(i);
328   }
329   delete [] (void**)fCont;
330   fCont =0;
331   fSize = 0;  
332   fCapacity = 0;
333 }
334
335 void AliMemArray::Clear2D()
336 {
337   //
338   //clear memory space occupied by the array  - doesn't call DTOR
339   Int_t  nbuff = (fCapacity/fBufferSize);
340   if ( (fCapacity%fBufferSize)!=0) nbuff++;
341   // for (Int_t  i=0;i<nbuff;i++) memset(GetRow(i), 0, fSize*fObjectSize);
342   //MI change - to have the same as in TClonesArray
343   fSize = 0;  
344 }
345
346
347
348
349 void AliMemArray::Reserve2D(UInt_t  n) 
350 {
351   //
352   // 
353   Int_t buffers = n/fBufferSize;
354   if (n%fBufferSize) buffers++;
355   UInt_t  nobjects=buffers*fBufferSize;
356   Int_t oldbuffers = GetNBuffers() ;
357   if (buffers==oldbuffers) return;
358   //
359   void ** table  = (void**) new char*[buffers];
360
361   Int_t max = buffers>oldbuffers ? buffers: oldbuffers;
362   for (Int_t i = 0;i<max;i++) {
363     if ( (i<oldbuffers) && (i<buffers))  table[i] = GetRow(i);
364     if ( (i<oldbuffers)&&(i>=buffers) ){
365       Int_t dsize = TMath::Min(Int_t(fSize) - i*Int_t(fBufferSize),Int_t(fBufferSize));
366       if (dsize>0) DTORBuffer(GetRow(i),dsize);
367       delete [] (char*)GetRow(i);
368     }
369     if (i>=oldbuffers)
370       table[i] = new char[fBufferSize*fObjectSize];
371   }
372   if (fSize>nobjects) fSize=nobjects;
373
374   fCapacity = nobjects ;    
375   delete [] (void**)fCont;
376   fCont = (void*)table;
377 }
378
379
380
381 void AliMemArray::Resize2D(UInt_t  n) 
382 {
383   //
384   //  
385   if (n>fCapacity) Reserve2D(n);   //reserve automaticaly space 
386   Int_t buffers = n/fBufferSize;
387   if (n%fBufferSize) buffers++;
388
389   if (fSize>n){   //call destructor if we decrease the size of array
390     Int_t oldbuffer = fSize/fBufferSize;
391     
392     for (Int_t i=buffers;i<oldbuffer; i++){
393       Int_t iold= fSize-i*fBufferSize;
394       if (iold>(Int_t)fBufferSize) iold= fBufferSize; 
395       Int_t inew= n -i*fBufferSize;
396       if (inew<0) inew =0;
397       DTORBuffer(Unchecked2DAt(i,inew),iold-inew);
398     }
399   }
400   if (fSize<n){   //call constructor if we increase the size of array
401     Int_t oldbuffer = fSize/fBufferSize;
402     for (Int_t i=oldbuffer;i<buffers; i++){
403       Int_t iold = fSize-i*fBufferSize;
404       if (iold<0) iold = 0;
405       Int_t inew =  n -i*fBufferSize;
406       if (inew>(Int_t)fBufferSize) inew = fBufferSize;
407       CTORBuffer(Unchecked2DAt(i,iold),inew-iold);
408     }
409   }
410   fSize = n;  
411 }
412
413
414
415
416
417