8 //_______________________________________________
9 AliPoolN& AliPoolN::operator=(const AliPoolN& src)
13 if (fPool) delete[] fPool;
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;
26 //_______________________________________________
27 void AliPoolN::Clear(Option_t*)
30 fNBooked = fFreeSlot = fNFreed = 0;
34 //_______________________________________________
35 int* AliPoolN::BookSlots(void** addr, int n, int wsize)
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;
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;
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 ?
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));
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 ];
70 AliInfo(Form("Expansion %d: Size:%d, Object Booked:%d, Freed:%d, Next Free Slot:%d\n",
71 ++eCounter,fSize,fNBooked,fNFreed,fFreeSlot));
73 ptrS[fNBooked++] = fFreeSlot;
74 void** slotP = (void**)&fPool[ fFreeSlot ];
76 SetUniqueID(fFreeSlot+kPtrIW);
77 fFreeSlot = newFreeSlot;
79 return &fPool[GetUniqueID()];
82 //_______________________________________________
83 void AliPoolN::PrintSummary(Option_t*) const
86 printf("Pool: Num.Arrays: Size:%d, Object Booked:%d, Freed:%d, Next Free Slot:%d\n",
87 fSize,fNBooked,fNFreed,fFreeSlot);
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)
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)
107 //_______________________________________________
108 void AliPoolN::FreeSlot(void* adr)
110 char** adrc = (char**)adr;
111 if (!(*adrc)) return; //{ printf("ATTENTION: 0 pointer is freed\n"); return; }
112 *adrc = NULL; fNFreed++;
115 //_______________________________________________
116 Int_t AliPoolN::GetUsedSize()
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
123 if (fFreeSlot<1) return 0.; // empty
124 int nFreeW=0, freeStart=-1,freeEnd=-1;
125 int* ptrS = fPtrSlot.GetArray();
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;}
134 else if (freeStart!=-1) {
135 freeEnd = ptrS[i]; // end of free blocks
136 nFreeW += freeEnd-freeStart;
140 if (freeStart!=-1 && freeEnd<0) { // last blocks were freed
142 nFreeW += freeEnd-freeStart;
144 return fFreeSlot - nFreeW;
148 //_______________________________________________
149 void AliPoolN::Defragment()
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
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;
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
179 freeStart = ptrS[i]-shift; // mark beginning of the new free block
180 useStart = -1; // forget already treated used block
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
187 else if (freeStart==-1) freeStart = ptrS[i]; // previous slot was not used: mark beginning of new free block
189 else { // the array is used
190 if (useStart==-1) { // and it is in the beginning of the used block
194 if (freeStart==-1) cnt++; // no free block before, this array will not be moved
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
213 AliInfo(Form("Freed %d words",shift));