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