00001 #ifndef FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KCONTAINERALLOCATORS_H
00002 #define FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KCONTAINERALLOCATORS_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <fbxfilesdk/components/kbaselib/kbaselib_h.h>
00040
00041 #include <fbxfilesdk/components/kbaselib/klib/kdebug.h>
00042
00043 #include <stdlib.h>
00044
00045 #include <fbxfilesdk/fbxfilesdk_nsbegin.h>
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 class KFBX_DLL KBaseAllocator
00084 {
00085 public:
00086 KBaseAllocator(size_t const pRecordSize)
00087 : mRecordSize(pRecordSize)
00088 {
00089 }
00090
00091 void Reserve(size_t const pRecordCount)
00092 {
00093 }
00094
00095 void* AllocateRecords(size_t const pRecordCount = 1)
00096 {
00097 return malloc(pRecordCount * mRecordSize);
00098 }
00099
00100 void FreeMemory(void* pRecord)
00101 {
00102 free(pRecord);
00103 }
00104
00105 size_t GetRecordSize() const
00106 {
00107 return mRecordSize;
00108 }
00109
00110
00111
00112 private:
00113 size_t mRecordSize;
00114 };
00115
00116
00117
00118
00119
00120
00121 class KHungryAllocator
00122 {
00123 public:
00124 KHungryAllocator(size_t pRecordSize)
00125 : mRecordSize(pRecordSize)
00126 , mData(NULL)
00127 , mRecordPoolSize(0)
00128 {
00129 }
00130
00131 KHungryAllocator(const KHungryAllocator& pOther)
00132 : mRecordSize(pOther.mRecordSize)
00133 , mData(0)
00134 , mRecordPoolSize(pOther.mRecordPoolSize)
00135 {
00136 }
00137
00138 ~KHungryAllocator()
00139 {
00140 MemoryBlock* lCurrent = mData;
00141 MemoryBlock* lNext = lCurrent ? lCurrent->mNextBlock : 0;
00142 while (lCurrent)
00143 {
00144 delete lCurrent;
00145 lCurrent = lNext;
00146 lNext = lCurrent ? lCurrent->mNextBlock : 0;
00147 }
00148 }
00149
00150 void Reserve(size_t const pRecordCount)
00151 {
00152 MemoryBlock* lMem = new MemoryBlock(pRecordCount * mRecordSize);
00153 lMem->mNextBlock = mData;
00154 mData = lMem;
00155 mRecordPoolSize += pRecordCount;
00156 }
00157
00158 void* AllocateRecords(size_t const pRecordCount = 1)
00159 {
00160 MemoryBlock* lBlock = mData;
00161 void* lRecord = NULL;
00162
00163 while ((lBlock != NULL) &&
00164 ((lRecord = lBlock->GetChunk(pRecordCount * mRecordSize)) == NULL))
00165 {
00166 lBlock = lBlock->mNextBlock;
00167 }
00168
00169 if (lRecord == NULL)
00170 {
00171 size_t lNumRecordToAllocate = mRecordPoolSize / 8 == 0 ? 2 : mRecordPoolSize / 8;
00172 if (lNumRecordToAllocate < pRecordCount)
00173 {
00174 lNumRecordToAllocate = pRecordCount;
00175 }
00176 Reserve(lNumRecordToAllocate);
00177 lRecord = AllocateRecords(pRecordCount);
00178 }
00179
00180 return lRecord;
00181 }
00182
00183 void FreeMemory(void* pRecord)
00184 {
00185 }
00186
00187 size_t GetRecordSize() const
00188 {
00189 return mRecordSize;
00190 }
00191
00192 KHungryAllocator& operator=(const KHungryAllocator& pOther)
00193 {
00194 if( this != &pOther )
00195 {
00196
00197
00198
00199 if( mRecordSize < pOther.mRecordSize )
00200 {
00201 mRecordPoolSize = 0;
00202 }
00203
00204 mRecordSize = pOther.mRecordSize;
00205 }
00206
00207 return(*this);
00208 }
00209
00210 private:
00211 class MemoryBlock
00212 {
00213 public:
00214 MemoryBlock(size_t pSize)
00215 : mNextBlock(NULL)
00216 , mData(NULL)
00217 , mFreeData(NULL)
00218 , mEnd(NULL)
00219 {
00220 mData = malloc(pSize);
00221 mFreeData = mData;
00222 mEnd = reinterpret_cast<char*>(mData) + pSize;
00223 };
00224
00225 ~MemoryBlock()
00226 {
00227 free(mData);
00228 }
00229
00230 void* GetChunk(size_t const pSize)
00231 {
00232 if (reinterpret_cast<char*>(mFreeData) + pSize < mEnd)
00233 {
00234 void* lChunk = mFreeData;
00235 mFreeData = reinterpret_cast<char*>(mFreeData) + pSize;
00236 return lChunk;
00237 }
00238
00239 return NULL;
00240 }
00241
00242 MemoryBlock* mNextBlock;
00243 void* mData;
00244 void* mFreeData;
00245 void* mEnd;
00246 };
00247
00248 size_t mRecordSize;
00249 MemoryBlock* mData;
00250 size_t mRecordPoolSize;
00251 };
00252
00253
00254
00255 #include <fbxfilesdk/fbxfilesdk_nsend.h>
00256
00257 #endif // FBXFILESDK_COMPONENTS_KBASELIB_KLIB_KCONTAINERALLOCATORS_H
00258