00001
00002
00003 #ifndef _BATCHHEAP_H_
00004 #define _BATCHHEAP_H_
00005
00006 #include <assert.h>
00007
00008
00009 template <class SuperHeap>
00010 class MultiMalloc : public SuperHeap {
00011 public:
00012
00013
00014 int multimalloc (int num, size_t sz, void *& ptr)
00015 {
00016 int i = 0;
00017 ptr = (freeObject *) SuperHeap::malloc (sz);
00018 freeObject * p = (freeObject *) ptr;
00019 if (ptr != NULL) {
00020 for (i = 1; i < num; i++) {
00021 p->next = (freeObject *) SuperHeap::malloc (sz);
00022 if (p->next == NULL)
00023 break;
00024 p = p->next;
00025 }
00026 p->next = NULL;
00027 }
00028 return i;
00029 }
00030
00031
00032
00033 void multifree (int num, void *& ptr)
00034 {
00035 freeObject * p;
00036 freeObject * prev = (freeObject *) ptr;
00037 for (int i = 0; i < num; i++) {
00038 p = prev->next;
00039 SuperHeap::free (prev);
00040 prev = p;
00041 }
00042 ptr = NULL;
00043 }
00044
00045 private:
00046
00047 class freeObject {
00048 public:
00049 freeObject * next;
00050 };
00051
00052
00053 };
00054
00055
00056 template <int BatchNumber, class SuperHeap>
00057 class BatchHeap : public SuperHeap {
00058 public:
00059
00060 BatchHeap (void)
00061 : nObjects (0)
00062 {
00063 freeList[0] = NULL;
00064 freeList[1] = NULL;
00065 }
00066
00067
00068 ~BatchHeap (void) {
00069 if (nObjects <= BatchNumber) {
00070 SuperHeap::multifree (nObjects, (void *&) freeList[0]);
00071 } else {
00072 SuperHeap::multifree (BatchNumber, (void *&) freeList[0]);
00073 SuperHeap::multifree (nObjects - BatchNumber, (void *&) freeList[1]);
00074 }
00075 }
00076
00077 inline void * malloc (size_t sz) {
00078 if (nObjects == 0) {
00079
00080 nObjects = SuperHeap::multimalloc (BatchNumber, sz, (void *&) freeList[0]);
00081 }
00082 assert (nObjects >= 1);
00083 freeObject * ptr;
00084 if (nObjects > BatchNumber) {
00085 freeObject *& head = freeList[1];
00086 ptr = head;
00087 nObjects--;
00088 head = head->next;
00089 return (void *) ptr;
00090 } else {
00091 freeObject *& head = freeList[0];
00092 ptr = head;
00093 nObjects--;
00094 head = head->next;
00095 return (void *) ptr;
00096 }
00097 }
00098
00099 inline void free (void * ptr) {
00100 if (nObjects <= BatchNumber) {
00101 freeObject *& head = freeList[0];
00102 ((freeObject *) ptr)->next = head;
00103 head = (freeObject *) ptr;
00104 } else {
00105 freeObject *& head = freeList[1];
00106 ((freeObject *) ptr)->next = head;
00107 head = (freeObject *) ptr;
00108 }
00109 nObjects++;
00110 if (nObjects == 2 * BatchNumber) {
00111
00112 assert (freeList[1] != NULL);
00113 SuperHeap::multifree (BatchNumber, (void *&) freeList[1]);
00114 }
00115 }
00116
00117 private:
00118
00119 class freeObject {
00120 public:
00121 freeObject * next;
00122 };
00123
00124 int nObjects;
00125
00126
00127
00128 freeObject * freeList[2];
00129 };
00130
00131 #endif