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