1 #ifndef XRD_CLIIDXVEC_H
2 #define XRD_CLIIDXVEC_H
44 #include "XrdSys/XrdSysHeaders.hh"
46 #define IDXVEC_MINCAPACITY 128
49 class XrdClientVector {
68 long capacity, maxsize;
73 int BufRealloc(
int newsize);
75 inline void Init(
int cap = -1) {
76 if (rawdata) free(rawdata);
77 if (index) free(index);
79 mincap = (cap > 0) ? cap : IDXVEC_MINCAPACITY;
81 rawdata =
static_cast<char *
>(malloc(mincap * sizeof_t));
83 index =
static_cast<myindex *
>(malloc(mincap *
sizeof(myindex)));
85 if (!rawdata || !index) {
86 std::cerr <<
"XrdClientIdxVector::Init .... out of memory. sizeof_t=" << sizeof_t <<
87 " sizeof(myindex)=" <<
sizeof(myindex) <<
" capacity=" << mincap << std::endl;
92 memset(index, 0, mincap *
sizeof(myindex));
97 maxsize = capacity = mincap;
103 void DestroyElem(myindex *el) {
104 reinterpret_cast<T*
>(rawdata+el->offs)->~T();
108 void put(T& item,
long pos) {
112 if (size+holecount >= capacity) {
113 std::cerr <<
"XrdClientIdxVector::put .... internal error." << std::endl;
118 long offs = (size+holecount)*sizeof_t;
120 if (index[pos].notempty) {
121 offs = index[pos].offs;
127 p =
new(rawdata + offs) T(item);
130 index[pos].offs = offs;
131 index[pos].notempty =
true;
134 std::cerr <<
"XrdClientIdxVector::put .... out of memory." << std::endl;
142 inline int GetSize()
const {
return size; }
145 for (
long i = 0; i < size; i++)
146 if (index[i].notempty) DestroyElem(&index[i]);
151 XrdClientVector(
int cap = -1):
152 sizeof_t(0), rawdata(0), index(0)
155 sizeof_t = (
sizeof(T) + 3) >> 2 << 2;
159 XrdClientVector(XrdClientVector &v):
160 rawdata(0), index(0) {
162 sizeof_t = (
sizeof(T) + 3) >> 2 << 2;
167 for (
int i = 0; i < v.size; i++)
172 for (
long i = 0; i < size; i++)
173 if (index[i].notempty) DestroyElem(&index[i]);
175 if (rawdata) free(rawdata);
176 if (index) free(index);
179 void Resize(
int newsize) {
182 if (newsize > oldsize) {
186 for (
long i = oldsize; i < newsize; i++) {
192 for (
long i = oldsize; i > newsize; i--)
197 void Push_back(T& item) {
199 if ( BufRealloc(size+1) )
224 void Insert(T& item,
int pos) {
231 if ( BufRealloc(size+1) ) {
234 struct myindex tmpi = index[size];
235 memmove(&index[pos+1], &index[pos], (size-pos) *
sizeof(myindex));
238 memmove(&index[pos+1], &index[pos], (size-pos) *
sizeof(myindex));
239 index[pos].notempty =
false;
266 void Erase(
unsigned int pos,
bool dontrealloc=
true) {
268 DestroyElem(index + pos);
270 struct myindex tmpi = index[pos];
273 memmove(&index[pos], &index[pos+1], (size-pos-1) *
sizeof(myindex));
285 DestroyElem(index+size-1);
304 inline T &At(
int pos) {
305 if ((pos < 0) || (static_cast<unsigned long>(pos) >=
306 static_cast<unsigned long>(size))) abort();
308 return *(
reinterpret_cast<T*
>(rawdata + index[pos].offs));
311 inline T &operator[] (
int pos) {
321 int XrdClientVector<T>::BufRealloc(
int newsize) {
325 if ((size+holecount >= capacity-2) && (holecount > 4*size))
326 while (size+holecount >= capacity-2) {
327 long lastempty = size+holecount-1;
335 memmove(rawdata + index[lastempty].offs, rawdata + index[lastempty].offs + sizeof_t,
336 (size+holecount)*sizeof_t - index[lastempty].offs );
339 index[lastempty].notempty =
false;
343 for (
long i = 0; i < size+holecount; i++)
344 if (index[i].notempty && (index[i].offs > index[lastempty].offs))
345 index[i].offs -= sizeof_t;
349 if (newsize > maxsize) maxsize = newsize;
351 while (newsize+holecount > capacity*2/3) {
357 rawdata =
static_cast<char *
>(realloc(rawdata, capacity*sizeof_t));
359 std::cerr <<
"XrdClientIdxVector::BufRealloc .... out of memory." << std::endl;
363 index =
static_cast<myindex *
>(realloc(index, capacity*
sizeof(myindex)));
364 memset(index+capacity/2, 0, capacity*
sizeof(myindex)/2);
368 while ((newsize+holecount < capacity/3) && (capacity > 2*mincap)) {
375 rawdata =
static_cast<char *
>(realloc(rawdata, capacity*sizeof_t));
377 std::cerr <<
"XrdClientIdxVector::BufRealloc .... out of memory." << std::endl;
381 index =
static_cast<myindex *
>(realloc(index, capacity*
sizeof(myindex)));