00001
00002
00003 #ifndef _OBSTACKREAP_H_
00004 #define _OBSTACKREAP_H_
00005
00006 #include <assert.h>
00007
00008
00009
00010
00011
00012
00013
00014 #if WIN32
00015 #include <windows.h>
00016 #endif
00017
00018 #include "dynarray.h"
00019
00020 namespace ObstackReapNS {
00021
00022 #if 0
00023 template <class ObjType>
00024 class DynamicArray {
00025 public:
00026 DynamicArray (void)
00027 : internalArray (0),
00028 internalArrayLength (0)
00029 {}
00030
00031 ~DynamicArray (void)
00032 {
00033 clear();
00034 }
00035
00036
00037
00038 inline void clear (void) {
00039 if (internalArray) {
00040 delete [] internalArray;
00041 internalArray = 0;
00042 internalArrayLength = 0;
00043
00044 }
00045 }
00046
00047
00048
00049
00050 inline const ObjType& operator[] (int index) const {
00051 assert (index < internalArrayLength);
00052 assert (index >= 0);
00053 return internalArray[index];
00054 }
00055
00056
00057
00058
00059 inline ObjType& operator[] (int index) {
00060 assert (index >= 0);
00061 if (index >= internalArrayLength) {
00062
00063
00064
00065
00066 const int newSize = index * 2 + 1;
00067 ObjType * arr = new ObjType[newSize];
00068
00069 #if MALLOC_TRACE
00070 printf ("m %x %d\n", arr, newSize * sizeof(ObjType));
00071 #endif
00072 if (internalArray) {
00073 memcpy (arr, internalArray, internalArrayLength * sizeof(ObjType));
00074 delete [] internalArray;
00075 #if MALLOC_TRACE
00076 printf ("f %x\n", internalArray);
00077 #endif
00078 }
00079 internalArray = arr;
00080 internalArrayLength = newSize;
00081
00082 }
00083 return internalArray[index];
00084 }
00085
00086
00087
00088
00089
00090 inline void trim (int nelts) {
00091
00092
00093
00094
00095 if (internalArray) {
00096 if (nelts * 4 < internalArrayLength) {
00097 const int newSize = nelts * 2;
00098 ObjType * arr = new ObjType[newSize];
00099
00100 #if MALLOC_TRACE
00101 printf ("m %x %d\n", arr, newSize * sizeof(ObjType));
00102 #endif
00103 memcpy (arr, internalArray, sizeof(ObjType) * nelts);
00104 delete [] internalArray;
00105 #if MALLOC_TRACE
00106 printf ("f %x\n", internalArray);
00107 #endif
00108 internalArray = arr;
00109 internalArrayLength = newSize;
00110 }
00111 assert (nelts <= internalArrayLength);
00112 }
00113 }
00114
00115
00116 private:
00117
00118
00119
00120 ObjType * internalArray;
00121
00122
00123
00124 int internalArrayLength;
00125 };
00126 #endif
00127
00128 template <class OBJTYPE>
00129 class DynStack {
00130 public:
00131 DynStack (void)
00132 : numItems (0)
00133 {
00134 items[0] = 0;
00135 }
00136
00137 int length (void) const { return numItems; }
00138
00139 inline void push (OBJTYPE * ptr) {
00140 numItems++;
00141 items[numItems] = ptr;
00142 }
00143
00144 inline OBJTYPE * pop (void) {
00145 OBJTYPE * ptr = 0;
00146 if (numItems > 0) {
00147 ptr = items[numItems];
00148 numItems--;
00149
00150 items.trim (numItems + 1);
00151 }
00152 return ptr;
00153 }
00154
00155 inline OBJTYPE * top (void) {
00156 OBJTYPE * ptr = NULL;
00157 if (numItems > 0) {
00158 ptr = items[numItems];
00159 }
00160 return ptr;
00161 }
00162
00163 inline void clear (void) {
00164 items.clear();
00165 }
00166
00167 private:
00168
00169
00170
00171
00172
00173
00174 int numItems;
00175
00176
00177
00178 DynamicArray<OBJTYPE *> items;
00179 };
00180
00181 };
00182
00183
00184
00185
00186 template <class ReapType>
00187 class ObstackReap {
00188 public:
00189
00190 ObstackReap (void)
00191 {
00192 currentReap = new ReapType;
00193 initCurrentObject();
00194 }
00195
00196 ~ObstackReap (void) {
00197 ReapType * r;
00198 while ((r = reapStack.pop())) {
00199 delete r;
00200 }
00201 delete currentReap;
00202 delete currentObject;
00203 }
00204
00205 inline void * malloc (size_t sz);
00206 inline void freeAfter (void * ptr);
00207 inline void freeAll (void);
00208 inline void * getObjectBase (void);
00209 inline void finalize (void);
00210 inline void * grow (size_t sz);
00211
00212 private:
00213
00214 inline void initCurrentObject (void);
00215
00216
00217 void free (void *);
00218
00219 enum { INITIAL_OBJECT_SIZE = 8 * sizeof(double) };
00220
00221 void * currentObject;
00222 char * currentObjectPosition;
00223 size_t currentObjectSize;
00224 size_t actualObjectSize;
00225 bool isCurrentObjectExposed;
00226 ReapType * currentReap;
00227 ObstackReapNS::DynStack<ReapType> reapStack;
00228 };
00229
00230
00231 template <class ReapType>
00232 void ObstackReap<ReapType>::initCurrentObject (void) {
00233 currentObject = currentReap->malloc (INITIAL_OBJECT_SIZE);
00234 currentObjectPosition = (char *) currentObject;
00235 currentObjectSize = 0;
00236 actualObjectSize = INITIAL_OBJECT_SIZE;
00237 isCurrentObjectExposed = false;
00238 }
00239
00240 template <class ReapType>
00241 void * ObstackReap<ReapType>::malloc (size_t sz) {
00242 if (!isCurrentObjectExposed) {
00243 return currentReap->malloc (sz);
00244 } else {
00245 void * ptr = currentReap->realloc (currentObject, sz);
00246 reapStack.push (currentReap);
00247 currentReap = new ReapType;
00248 initCurrentObject();
00249 return ptr;
00250 }
00251 }
00252
00253 template <class ReapType>
00254 void ObstackReap<ReapType>::freeAfter (void * ptr) {
00255 while (currentReap && (!currentReap->find(ptr))) {
00256 delete currentReap;
00257 currentReap = reapStack.pop();
00258 }
00259 }
00260
00261 template <class ReapType>
00262 void ObstackReap<ReapType>::freeAll (void) {
00263 while (currentReap) {
00264 delete currentReap;
00265 currentReap = reapStack.pop();
00266 }
00267 currentHeap = new ReapType;
00268 }
00269
00270
00271 template <class ReapType>
00272 inline void * ObstackReap<ReapType>::getObjectBase (void) {
00273 isCurrentObjectExposed = true;
00274 return currentObject;
00275 }
00276
00277 template <class ReapType>
00278 inline void ObstackReap<ReapType>::finalize (void) {
00279 if (isCurrentObjectExposed) {
00280 reapStack.push (currentReap);
00281 currentReap = new ReapType;
00282 }
00283 initCurrentObject();
00284 }
00285
00286 template <class ReapType>
00287 inline void * ObstackReap<ReapType>::grow (size_t sz) {
00288
00289 const int requestedObjectSize = currentObjectSize + sz;
00290
00291 if (requestedObjectSize > actualObjectSize) {
00292 cout << "resize!\n";
00293 void * ptr = currentReap->realloc (currentObject, sz);
00294 currentObjectPosition = (char *) ptr + (currentObjectPosition - (char *) currentObject);
00295 if (isCurrentObjectExposed) {
00296 reapStack.push (currentReap);
00297 currentReap = new ReapType;
00298 }
00299 currentObject = ptr;
00300 }
00301
00302
00303
00304
00305 isCurrentObjectExposed = false;
00306 currentObjectSize += sz;
00307 char * oldPosition = currentObjectPosition;
00308 currentObjectPosition += sz;
00309 return oldPosition;
00310 }
00311
00312 #endif