- Main Page
- Classes
- Files
- Directories

- File List
- File Members

# fbxcontainerallocators.h

Go to the documentation of this file.

    00001 /****************************************************************************************
    00002
    00003    Copyright (C) 2013 Autodesk, Inc.
    00004    All rights reserved.
    00005
    00006    Use of this software is subject to the terms of the Autodesk license agreement
    00007    provided at the time of installation or download, or which otherwise accompanies
    00008    this software in either electronic or hard copy form.
    00009
    00010 ****************************************************************************************/
    00011
    00013 #ifndef _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
    00014 #define _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
    00015
    00016 #include <fbxsdk/fbxsdk_def.h>
    00017
    00018 #include <fbxsdk/fbxsdk_nsbegin.h>
    00019
    00023 class FBXSDK_DLL FbxBaseAllocator
    00024 {
    00025 public:
    00032     FbxBaseAllocator(const size_t pRecordSize) :
    00033         mRecordSize(pRecordSize)
    00034     {
    00035     }
    00036
    00044     void Reserve(const size_t /*pRecordCount*/)
    00045     {
    00046         // By default, ignore all preallocating requests.
    00047     }
    00048
    00054     void* AllocateRecords(const size_t pRecordCount=1)
    00055     {
    00056         return FbxMalloc(pRecordCount * mRecordSize);
    00057     }
    00058
    00062     void FreeMemory(void* pRecord)
    00063     {
    00064         FbxFree(pRecord);
    00065     }
    00066
    00069     size_t GetRecordSize() const
    00070     {
    00071         return mRecordSize;
    00072     }
    00073
    00074 private:
    00075     size_t mRecordSize;
    00076 };
    00077
    00082 class FbxHungryAllocator
    00083 {
    00084 public:
    00085     FbxHungryAllocator(size_t pRecordSize) :
    00086         mRecordSize(pRecordSize),
    00087         mRecordPoolSize(0),
    00088         mData(NULL)
    00089     {
    00090     }
    00091
    00092     FbxHungryAllocator(const FbxHungryAllocator& pOther) :
    00093         mRecordSize(pOther.mRecordSize),
    00094         mRecordPoolSize(pOther.mRecordPoolSize),
    00095         mData(NULL)
    00096     {
    00097     }
    00098
    00099     ~FbxHungryAllocator()
    00100     {
    00101         MemoryBlock* lCurrent = mData;
    00102         MemoryBlock* lNext = lCurrent ? lCurrent->mNextBlock : 0;
    00103         while (lCurrent)
    00104         {
    00105             FbxDelete(lCurrent);
    00106             lCurrent = lNext;
    00107             lNext = lCurrent ? lCurrent->mNextBlock : 0;
    00108         }
    00109     }
    00110
    00111     void Reserve(const size_t pRecordCount)
    00112     {
    00113         MemoryBlock* lMem = FbxNew< MemoryBlock >(pRecordCount* mRecordSize);
    00114         lMem->mNextBlock = mData;
    00115         mData = lMem;
    00116         mRecordPoolSize += pRecordCount;
    00117     }
    00118
    00119     void* AllocateRecords(const size_t pRecordCount = 1)
    00120     {
    00121         MemoryBlock* lBlock = mData;
    00122         void* lRecord = NULL;
    00123
    00124         while( (lBlock != NULL) && ((lRecord = lBlock->GetChunk(pRecordCount * mRecordSize)) == NULL) )
    00125         {
    00126             lBlock = lBlock->mNextBlock;
    00127         }
    00128
    00129         if( lRecord == NULL )
    00130         {
    00131             size_t lNumRecordToAllocate = mRecordPoolSize / 8 == 0 ? 2 : mRecordPoolSize / 8;
    00132             if( lNumRecordToAllocate < pRecordCount )
    00133             {
    00134                 lNumRecordToAllocate = pRecordCount;
    00135             }
    00136             Reserve(lNumRecordToAllocate);
    00137             lRecord = AllocateRecords(pRecordCount);
    00138         }
    00139         return lRecord;
    00140     }
    00141
    00142     void FreeMemory(void* /*pRecord*/)
    00143     {
    00144         // "Hungry": release memory only when the allocator is destroyed.
    00145     }
    00146
    00147     size_t GetRecordSize() const
    00148     {
    00149         return mRecordSize;
    00150     }
    00151
    00152     FbxHungryAllocator& operator=(const FbxHungryAllocator& pOther)
    00153     {
    00154         if( this != &pOther )
    00155         {
    00156             // The next call to AllocateRecords() may skip over currently reserved
    00157             // records if the size changes drastically, but otherwise GetChunk()
    00158             // is size-oblivious.
    00159             if( mRecordSize < pOther.mRecordSize )
    00160             {
    00161                 mRecordPoolSize = 0;
    00162             }
    00163
    00164             mRecordSize = pOther.mRecordSize;
    00165         }
    00166         return(*this);
    00167     }
    00168
    00169 private:
    00170     class MemoryBlock
    00171     {
    00172     public:
    00173         MemoryBlock(size_t pSize) :
    00174             mNextBlock(NULL),
    00175             mData(NULL),
    00176             mFreeData(NULL),
    00177             mEnd(NULL)
    00178         {
    00179             mData = FbxMalloc(pSize);
    00180             mFreeData = mData;
    00181             mEnd = reinterpret_cast<char*>(mData) + pSize;
    00182         }
    00183
    00184         ~MemoryBlock()
    00185         {
    00186             FbxFree(mData);
    00187         }
    00188
    00189         void* GetChunk(const size_t pSize)
    00190         {
    00191             if( reinterpret_cast<char*>(mFreeData) + pSize < mEnd )
    00192             {
    00193                 void* lChunk = mFreeData;
    00194                 mFreeData = reinterpret_cast<char*>(mFreeData) + pSize;
    00195                 return lChunk;
    00196             }
    00197             return NULL;
    00198         }
    00199
    00200         MemoryBlock*    mNextBlock;
    00201         void*           mData;
    00202         void*           mFreeData;
    00203         void*           mEnd;
    00204     };
    00205
    00206     size_t          mRecordSize;
    00207     size_t          mRecordPoolSize;
    00208     MemoryBlock*    mData;
    00209 };
    00210
    00211 #include <fbxsdk/fbxsdk_nsend.h>
    00212
    00213 #endif /* _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_ */