]>
Commit | Line | Data |
---|---|---|
e546b023 | 1 | #include "AliPoolN.h" |
2 | #include "AliLog.h" | |
3 | #include <TMath.h> | |
4 | ||
5 | ||
6 | ClassImp(AliPoolN) | |
7 | ||
8 | //_______________________________________________ | |
9 | AliPoolN& AliPoolN::operator=(const AliPoolN& src) | |
10 | { | |
11 | // assign | |
12 | if (this!=&src) { | |
13 | if (fPool) delete[] fPool; | |
14 | fSize = src.fSize; | |
15 | fPool = new Int_t[fSize]; | |
16 | memcpy(fPool,src.fPool,sizeof(Int_t)*fSize); | |
17 | fPtrSlot = src.fPtrSlot; | |
18 | fFreeSlot = src.fFreeSlot; | |
19 | fNBooked = src.fNBooked; | |
20 | fNFreed = src.fNFreed; | |
21 | } | |
22 | return *this; | |
23 | } | |
24 | ||
25 | ||
26 | //_______________________________________________ | |
27 | void AliPoolN::Clear(Option_t*) | |
28 | { | |
29 | // reset | |
30 | fNBooked = fFreeSlot = fNFreed = 0; | |
31 | SetUniqueID(0); | |
32 | } | |
33 | ||
34 | //_______________________________________________ | |
35 | int* AliPoolN::BookSlots(void** addr, int n, int wsize) | |
36 | { | |
37 | // book n slots of size wsize (aligning to sizeof(int)) | |
38 | const int kIntW = sizeof(Int_t); | |
39 | const int kDivW = TMath::Log2(sizeof(Int_t)); | |
40 | const int kPtrW = sizeof(void*); | |
41 | const int kPtrIW = kPtrW/kIntW; // pointer length in int words | |
42 | static int eCounter = 0; | |
43 | // | |
44 | if (n<1) return 0; | |
45 | int nbtot = n*wsize; // total bytes to book (apart from addr) | |
46 | if (nbtot%kIntW) nbtot = (((nbtot>>kDivW)+1)<<kDivW); // make sure it is in Int words (normally 4 bites) | |
47 | int nw = kPtrIW + (nbtot>>kDivW); // number of int words to book (including space for pointer) | |
48 | UInt_t newFreeSlot = fFreeSlot+nw; | |
49 | // | |
50 | if (UInt_t(fPtrSlot.GetSize())<=fNBooked) fPtrSlot.Set( 2*(fNBooked+10) ); | |
51 | int* ptrS = fPtrSlot.GetArray(); | |
52 | if (fSize<=newFreeSlot) { // do we need to expand the array ? | |
53 | // | |
54 | int sizeN = int((newFreeSlot+10000)*1.5); | |
55 | Int_t* oldArr = fPool; | |
56 | fPool = new Int_t[sizeN]; | |
57 | if (fSize) memcpy(fPool,oldArr, fSize*sizeof(Int_t)); | |
58 | memset(&fPool[fSize],0,(sizeN-fSize)*sizeof(Int_t)); | |
59 | // | |
60 | for (UInt_t i=0;i<fNBooked;i++) { // fix old addresses | |
61 | void* oldP = (void*)&oldArr[ ptrS[i]+kPtrIW ]; | |
62 | void** slotP = (void**)&fPool[ ptrS[i] ]; | |
63 | void** ppp = (void**)slotP[0]; | |
64 | // printf("1>>%d %p %p old:%p\n",i,ppp, ppp ? *ppp : 0,oldP); | |
65 | if (!ppp || *ppp!=oldP) continue; // array was discarded | |
66 | *ppp = &fPool[ ptrS[i]+kPtrIW ]; | |
67 | } | |
68 | fSize = sizeN; | |
69 | delete[] oldArr; | |
70 | AliInfo(Form("Expansion %d: Size:%d, Object Booked:%d, Freed:%d, Next Free Slot:%d\n", | |
71 | ++eCounter,fSize,fNBooked,fNFreed,fFreeSlot)); | |
72 | } | |
73 | ptrS[fNBooked++] = fFreeSlot; | |
74 | void** slotP = (void**)&fPool[ fFreeSlot ]; | |
75 | slotP[0] = addr; | |
76 | SetUniqueID(fFreeSlot+kPtrIW); | |
77 | fFreeSlot = newFreeSlot; | |
78 | // | |
79 | return &fPool[GetUniqueID()]; | |
80 | } | |
81 | ||
82 | //_______________________________________________ | |
83 | void AliPoolN::PrintSummary(Option_t*) const | |
84 | { | |
85 | // print summary | |
86 | printf("Pool: Num.Arrays: Size:%d, Object Booked:%d, Freed:%d, Next Free Slot:%d\n", | |
87 | fSize,fNBooked,fNFreed,fFreeSlot); | |
88 | } | |
89 | ||
90 | ||
91 | //_______________________________________________ | |
92 | AliPoolN::AliPoolN(Int_t nini) : | |
93 | fSize(nini>100 ? nini:10000),fPool(new Int_t[fSize]),fPtrSlot(fSize/10),fNBooked(0), | |
94 | fNFreed(0),fFreeSlot(0) | |
95 | { | |
96 | // c-tor | |
97 | } | |
98 | ||
99 | //_______________________________________________ | |
100 | AliPoolN::AliPoolN(const AliPoolN& src) : | |
101 | TObject(src), fSize(src.fSize),fPool(new Int_t[fSize]),fPtrSlot(src.fPtrSlot), | |
102 | fNBooked(src.fNBooked), fNFreed(src.fNFreed),fFreeSlot(src.fFreeSlot) | |
103 | { | |
104 | // c-tor | |
105 | } | |
106 | ||
107 | //_______________________________________________ | |
108 | void AliPoolN::FreeSlot(void* adr) | |
109 | { | |
110 | char** adrc = (char**)adr; | |
111 | if (!(*adrc)) return; //{ printf("ATTENTION: 0 pointer is freed\n"); return; } | |
112 | *adrc = NULL; fNFreed++; | |
113 | } | |
114 | ||
115 | //_______________________________________________ | |
116 | Int_t AliPoolN::GetUsedSize() | |
117 | { | |
118 | // estimate which fraction of array is actually used | |
119 | const int kIntW = sizeof(Int_t); | |
120 | const int kPtrW = sizeof(void*); | |
121 | const int kPtrIW = kPtrW/kIntW; // pointer length in int words | |
122 | // | |
123 | if (fFreeSlot<1) return 0.; // empty | |
124 | int nFreeW=0, freeStart=-1,freeEnd=-1; | |
125 | int* ptrS = fPtrSlot.GetArray(); | |
126 | // | |
127 | for (UInt_t i=0;i<fNBooked;i++) { | |
128 | void* arrP = (void*)&fPool[ ptrS[i]+kPtrIW ]; // address of the booked array | |
129 | void** slotP = (void**)&fPool[ ptrS[i] ]; // address of the external pointer to which this array was attached | |
130 | void** ppp = (void**)slotP[0]; | |
131 | if (!ppp || *ppp!=arrP) { // the array was discarded | |
132 | if (freeStart<0) {freeStart = ptrS[i]; freeEnd = -1;} | |
133 | } | |
134 | else if (freeStart!=-1) { | |
135 | freeEnd = ptrS[i]; // end of free blocks | |
136 | nFreeW += freeEnd-freeStart; | |
137 | freeStart = -1; | |
138 | } | |
139 | } | |
140 | if (freeStart!=-1 && freeEnd<0) { // last blocks were freed | |
141 | freeEnd = fFreeSlot; | |
142 | nFreeW += freeEnd-freeStart; | |
143 | } | |
144 | return fFreeSlot - nFreeW; | |
145 | // | |
146 | } | |
147 | ||
148 | //_______________________________________________ | |
149 | void AliPoolN::Defragment() | |
150 | { | |
151 | // deframent the pool | |
152 | const int kIntW = sizeof(Int_t); | |
153 | const int kPtrW = sizeof(void*); | |
154 | const int kPtrIW = kPtrW/kIntW; // pointer length in int words | |
155 | // | |
156 | if (fFreeSlot<1) return; // empty | |
157 | int freeStart=-1,useStart=-1,useFirst=-1; | |
158 | int* ptrS = fPtrSlot.GetArray(); | |
159 | int cnt = 0, shift = 0; | |
160 | ||
161 | // | |
162 | for (UInt_t i=0;i<fNBooked;i++) { | |
163 | void* arrP = (void*)&fPool[ ptrS[i]+kPtrIW ]; // address of the booked array | |
164 | void** slotP = (void**)&fPool[ ptrS[i] ]; // address of the external pointer to which this array was attached | |
165 | void** ppp = (void**)slotP[0]; | |
166 | if (!ppp || *ppp!=arrP) { // the array was discarded | |
167 | if (useStart!=-1) { // and it is also the end of the used block | |
168 | if (freeStart!=-1) { // and there was a free block before | |
169 | int moved = ptrS[i]-useStart; | |
170 | shift = useStart-freeStart; | |
171 | memmove(&fPool[freeStart], &fPool[useStart], kIntW*moved); | |
172 | // update pointers for moved block | |
173 | for (UInt_t j=useFirst;j<i;j++) { // used block covered these arrays | |
174 | int slt = ptrS[cnt++] = ptrS[j]-shift; // updated index of the slot corresponding to array in the used block | |
175 | slotP = (void**)&fPool[ slt ]; | |
176 | ppp = (void**)slotP[0]; | |
177 | *ppp = &fPool[ slt+kPtrIW ]; // assign external array address the new pointer on the begginning of the array | |
178 | } | |
179 | freeStart = ptrS[i]-shift; // mark beginning of the new free block | |
180 | useStart = -1; // forget already treated used block | |
181 | } | |
182 | else { | |
183 | useStart = -1; // forget this used block, it is already in defragmented part | |
184 | freeStart = ptrS[i]; // no free block before, just mark beginning of new free block | |
185 | } | |
186 | } | |
187 | else if (freeStart==-1) freeStart = ptrS[i]; // previous slot was not used: mark beginning of new free block | |
188 | } | |
189 | else { // the array is used | |
190 | if (useStart==-1) { // and it is in the beginning of the used block | |
191 | useStart = ptrS[i]; | |
192 | useFirst = i; | |
193 | } | |
194 | if (freeStart==-1) cnt++; // no free block before, this array will not be moved | |
195 | } | |
196 | } | |
197 | // | |
198 | if (useStart!=-1 && freeStart!=-1) { // is there a last used block separated from defragmented part by empty block | |
199 | int moved = fFreeSlot-useStart; | |
200 | shift = useStart-freeStart; | |
201 | memmove(&fPool[freeStart], &fPool[useStart], kIntW*moved); | |
202 | // update pointers for moved block | |
203 | for (UInt_t j=useFirst;j<fNBooked;j++) { // used block covered these arrays | |
204 | int slt = ptrS[cnt++] = ptrS[j]-shift; // updated index of the slot corresponding to array in the used block | |
205 | void** slotP = (void**)&fPool[ slt ]; | |
206 | void** ppp = (void**)slotP[0]; // address of the pointer to which the array was assigned | |
207 | *ppp = &fPool[ slt+kPtrIW ]; // assign to it the new begginning of the array | |
208 | } | |
209 | } | |
210 | fFreeSlot -= shift; | |
211 | fNBooked = cnt; | |
212 | fNFreed = 0; | |
213 | AliInfo(Form("Freed %d words",shift)); | |
214 | // | |
215 | } |