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