1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.2 2001/01/10 09:33:56 kowal2
19 Clear method modified to fix the problem with reading Tree.
21 Revision 1.1 2000/11/01 16:01:26 kowal2
22 Classes for handling the new hits structures
25 ///////////////////////////////////////////////////////////////////////////////
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)
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]);
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]) ;
49 //<img src="../gif/AliMemArray.gif">
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.
58 // Origin: Marian Ivanov, Uni. of Bratislava, ivanov@fmph.uniba.sk //
59 ///////////////////////////////////////////////////////////////////////////////
63 #include "AliMemArray.h"
64 #include "Riostream.h"
72 AliMemArray::AliMemArray()
84 AliMemArray::AliMemArray(Int_t objectSize, Int_t buffersize)
87 // AliMemArray constructor
91 fObjectSize =objectSize;
92 fBufferSize =buffersize;
95 AliMemArray::AliMemArray(const AliMemArray & arr)
101 fCapacity = arr.fCapacity;
102 fObjectSize = arr.fObjectSize;
103 fBufferSize =arr.fBufferSize;
105 if (arr.fBufferSize==0) {
106 fCont = new char[fCapacity*fObjectSize];
107 CopyBuffer(fCont, arr.fCont, fSize);
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);
119 fCont = (void*)table;
124 void AliMemArray::Swap( AliMemArray &arr)
126 //swap contents of array
127 UInt_t size = arr.fSize;
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;
144 void AliMemArray::CopyBuffer(void *dest, void *src, UInt_t size)
147 //array placement copy constructor
148 memcpy(dest, src,size*fObjectSize);
151 AliMemArray::~AliMemArray()
159 void AliMemArray::SetObjectSize(UInt_t bufsize)
162 //set memory size for one object - it can be changed only when the array is empty
164 ::Error("AliMemArray::SetObjectSize", "forbidden to resize just allocated objects");
170 AliMemArray & AliMemArray::operator = (const AliMemArray &arr)
174 AliMemArray tmparr(arr);
179 void AliMemArray::SetBufferSize(UInt_t bufsize)
182 //set buffer size - it can be changed only when the array is empty
184 fBufferSize = bufsize;
187 if (fBufferSize == bufsize) return;
190 char *table = new char[fObjectSize*fCapacity];
192 for (UInt_t i=0; i<fSize; i++,p+=fObjectSize)
193 memcpy(p, At(i), fObjectSize);
194 //delete [](char*)fCont;
197 fBufferSize = bufsize;
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);
210 // delete [](char**)fCont;
212 fCont = (void*)table;
213 fBufferSize = bufsize;
220 void AliMemArray::Delete(Option_t *)
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.
234 DTORBuffer(Unchecked1DAt(0),fSize);
235 delete [] (char*)fCont;
242 void AliMemArray::Clear(Option_t *)
246 // Only use this routine when your objects don't
247 // allocate memory since it will not call the object dtors.
253 // memset(fCont, 0, fSize*fObjectSize);
254 //MI change - to have the same as in TClonesArray
259 void AliMemArray::Reserve(UInt_t n)
262 //reserve arrays space
264 if (fObjectSize<=0) {
265 cout<<"Object length not defined\n";
268 if (n==fCapacity) return;
271 Reserve2D(n); //if 2D buffer
277 DTORBuffer(Unchecked1DAt(n),fSize-n);
278 memset(&((char*)fCont)[n*fObjectSize], 0, (fSize-n)*fObjectSize);
281 fCont = (char*)TStorage::ReAlloc(fCont, n*fObjectSize,fCapacity*fObjectSize);
283 else fCont = new char[n*fObjectSize];
285 if (!fCont) fCapacity = 0;
290 void AliMemArray::Resize(UInt_t n)
295 if (fObjectSize<=0) {
296 cout<<"Object length not defined\n";
300 Resize2D(n); //if 2D buffer
304 if (n>fCapacity) Reserve(n); //reserve automaticaly space if sie >capacity
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
310 if (fSize<n) CTORBuffer(Unchecked1DAt(fSize),n-fSize);
315 void AliMemArray::Delete2D()
318 //delete memory space occupied by the array
319 if (!fBufferSize) return;
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;
326 DTORBuffer(GetRow(i),UInt_t(size)<fBufferSize? size:fBufferSize);
327 delete [] (char*)GetRow(i);
329 delete [] (void**)fCont;
335 void AliMemArray::Clear2D()
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
349 void AliMemArray::Reserve2D(UInt_t n)
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;
359 void ** table = (void**) new char*[buffers];
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);
370 table[i] = new char[fBufferSize*fObjectSize];
372 if (fSize>nobjects) fSize=nobjects;
374 fCapacity = nobjects ;
375 delete [] (void**)fCont;
376 fCont = (void*)table;
381 void AliMemArray::Resize2D(UInt_t n)
385 if (n>fCapacity) Reserve2D(n); //reserve automaticaly space
386 Int_t buffers = n/fBufferSize;
387 if (n%fBufferSize) buffers++;
389 if (fSize>n){ //call destructor if we decrease the size of array
390 Int_t oldbuffer = fSize/fBufferSize;
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;
397 DTORBuffer(Unchecked2DAt(i,inew),iold-inew);
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);