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