Coding conventions fixed
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliRefArray.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 #include "AliRefArray.h"
17 #include <string.h>
18
19 ClassImp(AliRefArray)
20
21 //____________________________________________________________________
22 AliRefArray::AliRefArray() : fNElems(0),fRefSize(0),fElems(0),fRefInd(0),fRefBuff(0)
23 {
24   // default constructor
25 }
26  
27 //____________________________________________________________________
28 AliRefArray::AliRefArray(UInt_t nelem,UInt_t depth) : 
29   TObject(),fNElems(nelem),fRefSize(depth),fElems(0),fRefInd(0),fRefBuff(0)
30 {
31   // constructor
32   fNElems = nelem;
33   // create array with nelem initial referres
34   if (fNElems<1) fNElems = 1;
35   fElems   = new Int_t[fNElems];   
36   if (fRefSize>0) {
37     fRefInd  = new UInt_t[fRefSize];  
38     fRefBuff = new UInt_t[fRefSize];  
39   }
40   Reset();
41   //
42 }
43  
44 //____________________________________________________________________
45 AliRefArray::AliRefArray(const AliRefArray& src) :
46   TObject(src),
47   fNElems(src.fNElems),
48   fRefSize(src.fRefSize),
49   fElems(new Int_t[fNElems]),
50   fRefInd(new UInt_t[fRefSize]),
51   fRefBuff(new UInt_t[fRefSize])
52 {
53   //
54   // create a copy 
55   //
56   memcpy(fElems,src.fElems,fNElems*sizeof(Int_t));
57   memcpy(fRefInd,src.fRefInd,fRefSize*sizeof(UInt_t));
58   memcpy(fRefBuff,src.fRefBuff,fRefSize*sizeof(UInt_t));
59 }
60  
61 //____________________________________________________________________
62 AliRefArray& AliRefArray::operator=(const AliRefArray& src)
63 {
64   // create a copy with useful info (skip unused slots)
65   if(&src != this) {
66     TObject::operator=(src);
67     fNElems = src.fNElems;
68     fRefSize=0;
69     if (fElems) delete[] fElems;
70     if (fRefInd) delete[] fRefInd;
71     if (fRefBuff) delete[] fRefBuff;
72     fElems = 0;
73     fRefInd = 0;
74     fRefBuff = 0;
75     if (src.fRefInd) {
76       fRefSize = src.fRefInd[0];
77       fRefInd  = new UInt_t[fRefSize];
78       fRefBuff = new UInt_t[fRefSize];
79       memcpy(fRefInd, src.fRefInd, fRefSize*sizeof(UInt_t));
80       memcpy(fRefBuff,src.fRefBuff,fRefSize*sizeof(UInt_t));
81     }
82     if (fNElems) {
83       fElems   = new Int_t[fNElems];   
84       memcpy(fElems,src.fElems,fNElems*sizeof(Int_t));
85     }
86   }
87   return *this;
88   //
89 }
90
91 //____________________________________________________________________
92 AliRefArray::~AliRefArray() 
93 {
94   // destructor
95   delete[] fElems;
96   delete[] fRefBuff;
97   delete[] fRefInd;
98 }
99
100 //____________________________________________________________________
101 void AliRefArray::Expand(UInt_t size)
102 {
103   // expand the size
104   if (size<fNElems) {
105     if (size>0) {printf("The size can be only increased\n");return;}
106     else size = (fNElems<<2) + 1;
107   }
108   else if (size==fNElems) return;
109   Int_t *tmpArr = new Int_t[size];
110   memcpy(tmpArr,fElems,fNElems*sizeof(Int_t));
111   memset(tmpArr+fNElems,0,(size-fNElems)*sizeof(UInt_t));
112   delete[] fElems;
113   fElems  = tmpArr;
114   fNElems = size;
115 }
116
117 //____________________________________________________________________
118 void AliRefArray::Reset()
119 {
120   // reset references
121   if (fNElems) memset(fElems,0,fNElems*sizeof(Int_t));
122   if (fRefSize) {
123     memset(fRefInd,0,fRefSize*sizeof(UInt_t));
124     memset(fRefBuff,0,fRefSize*sizeof(UInt_t));
125     fRefInd[0] = 1;
126   }
127 }
128
129 //____________________________________________________________________
130 void AliRefArray::ExpandReferences(Int_t addSize)
131 {
132   // add extra slots
133   if (addSize<3) addSize = 3;
134   UInt_t oldSize = fRefSize;
135   fRefSize += addSize;
136   UInt_t*   buff = new UInt_t[fRefSize];
137   UInt_t*   ind  = new UInt_t[fRefSize];
138   if (fRefBuff) memcpy(buff, fRefBuff, oldSize*sizeof(UInt_t)); // copy current content
139   if (fRefInd)  memcpy(ind,  fRefInd,  oldSize*sizeof(UInt_t));
140   memset(buff+oldSize,0,addSize*sizeof(UInt_t));
141   memset(ind +oldSize,0,addSize*sizeof(UInt_t));
142   delete[] fRefBuff; fRefBuff = buff;
143   delete[] fRefInd;  fRefInd  = ind;
144   if (!oldSize) fRefInd[0] = 1;
145 }
146
147 //____________________________________________________________________
148 void AliRefArray::Print(Option_t*) const
149 {
150   // reset references
151   for (UInt_t i=0;i<fNElems;i++) {
152     printf("Entry%4d: ",i);
153     Int_t ref;
154     if (!(ref=fElems[i])) {printf("None\n"); continue;}
155     if (fElems[i]<0)      {printf("%d\n",-(1+ref));   continue;}
156     do { printf("%d ",fRefBuff[ref]-1); }    while((ref=fRefInd[ref])); printf("\n");
157   }
158 }
159
160 //____________________________________________________________________
161 void AliRefArray::AddReferences(UInt_t from, UInt_t *refs, UInt_t nref)
162 {
163   // add nodes to the references of "from"
164   if (nref==1) {AddReference(from, refs[0]); return;}
165   if (!nref) return;
166   //
167   if (from>=fNElems) Expand(from+1);
168   UInt_t chk = nref + (fElems[from]<0); // if <0, need to transfer to indices the only existing reference
169   if      (!fRefInd) ExpandReferences(chk+1);
170   else if ( fRefInd[0]+chk >= fRefSize ) ExpandReferences(chk);
171   UInt_t &freeSlot = fRefInd[0];
172   // if there is already single ref, transfer it to indices
173   Int_t ref = fElems[from];
174   if (ref<0) { fRefInd[freeSlot]=0; fRefBuff[freeSlot] = -ref; ref = fElems[from] = freeSlot++; }
175   //
176   while(fRefInd[ref]) ref=fRefInd[ref]; // find last index of last entry for cluster from
177   if (fElems[from]) fRefInd[ref] = freeSlot;           // not a first entry, register it in the indices
178   else              fElems[from] = freeSlot;           // first entry, register it in the refs
179   for (UInt_t ir=0;ir<nref;ir++) {
180     if (!ir && !fElems[from]) fElems[from] = freeSlot;
181     else ref = fRefInd[ref] = freeSlot;
182     fRefBuff[freeSlot++] = refs[ir]+1;
183   }
184 }