fbxsdk/core/base/fbxcontainerallocators.h Source File

fbxcontainerallocators.h
Go to the documentation of this file.
1 /****************************************************************************************
2 
3  Copyright (C) 2015 Autodesk, Inc.
4  All rights reserved.
5 
6  Use of this software is subject to the terms of the Autodesk license agreement
7  provided at the time of installation or download, or which otherwise accompanies
8  this software in either electronic or hard copy form.
9 
10 ****************************************************************************************/
11 
13 #ifndef _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
14 #define _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_
15 
16 #include <fbxsdk/fbxsdk_def.h>
17 
18 #include <fbxsdk/fbxsdk_nsbegin.h>
19 
24 {
25 public:
32  FbxBaseAllocator(const size_t pRecordSize) :
33  mRecordSize(pRecordSize)
34  {
35  }
36 
44  void Reserve(const size_t /*pRecordCount*/)
45  {
46  // By default, ignore all preallocating requests.
47  }
48 
54  void* AllocateRecords(const size_t pRecordCount=1)
55  {
56  return FbxMalloc(pRecordCount * mRecordSize);
57  }
58 
62  void FreeMemory(void* pRecord)
63  {
64  FbxFree(pRecord);
65  }
66 
69  size_t GetRecordSize() const
70  {
71  return mRecordSize;
72  }
73 
74 private:
75  size_t mRecordSize;
76 };
77 
83 {
84 public:
85  FbxHungryAllocator(size_t pRecordSize) :
86  mRecordSize(pRecordSize),
87  mRecordPoolSize(0),
88  mData(NULL)
89  {
90  }
91 
93  mRecordSize(pOther.mRecordSize),
94  mRecordPoolSize(pOther.mRecordPoolSize),
95  mData(NULL)
96  {
97  }
98 
100  {
101  MemoryBlock* lCurrent = mData;
102  MemoryBlock* lNext = lCurrent ? lCurrent->mNextBlock : 0;
103  while (lCurrent)
104  {
105  FbxDelete(lCurrent);
106  lCurrent = lNext;
107  lNext = lCurrent ? lCurrent->mNextBlock : 0;
108  }
109  }
110 
111  void Reserve(const size_t pRecordCount)
112  {
113  MemoryBlock* lMem = FbxNew< MemoryBlock >(pRecordCount* mRecordSize);
114  lMem->mNextBlock = mData;
115  mData = lMem;
116  mRecordPoolSize += pRecordCount;
117  }
118 
119  void* AllocateRecords(const size_t pRecordCount = 1)
120  {
121  MemoryBlock* lBlock = mData;
122  void* lRecord = NULL;
123 
124  while( (lBlock != NULL) && ((lRecord = lBlock->GetChunk(pRecordCount * mRecordSize)) == NULL) )
125  {
126  lBlock = lBlock->mNextBlock;
127  }
128 
129  if( lRecord == NULL )
130  {
131  size_t lNumRecordToAllocate = mRecordPoolSize / 8 == 0 ? 2 : mRecordPoolSize / 8;
132  if( lNumRecordToAllocate < pRecordCount )
133  {
134  lNumRecordToAllocate = pRecordCount;
135  }
136  Reserve(lNumRecordToAllocate);
137  lRecord = AllocateRecords(pRecordCount);
138  }
139  return lRecord;
140  }
141 
142  void FreeMemory(void* /*pRecord*/)
143  {
144  // "Hungry": release memory only when the allocator is destroyed.
145  }
146 
147  size_t GetRecordSize() const
148  {
149  return mRecordSize;
150  }
151 
153  {
154  if( this != &pOther )
155  {
156  // The next call to AllocateRecords() may skip over currently reserved
157  // records if the size changes drastically, but otherwise GetChunk()
158  // is size-oblivious.
159  if( mRecordSize < pOther.mRecordSize )
160  {
161  mRecordPoolSize = 0;
162  }
163 
164  mRecordSize = pOther.mRecordSize;
165  }
166  return(*this);
167  }
168 
169 private:
170  class MemoryBlock
171  {
172  public:
173  MemoryBlock(size_t pSize) :
174  mNextBlock(NULL),
175  mData(NULL),
176  mFreeData(NULL),
177  mEnd(NULL)
178  {
179  mData = FbxMalloc(pSize);
180  mFreeData = mData;
181  mEnd = reinterpret_cast<char*>(mData) + pSize;
182  }
183 
184  ~MemoryBlock()
185  {
186  FbxFree(mData);
187  }
188 
189  void* GetChunk(const size_t pSize)
190  {
191  if( reinterpret_cast<char*>(mFreeData) + pSize < mEnd )
192  {
193  void* lChunk = mFreeData;
194  mFreeData = reinterpret_cast<char*>(mFreeData) + pSize;
195  return lChunk;
196  }
197  return NULL;
198  }
199 
200  MemoryBlock* mNextBlock;
201  void* mData;
202  void* mFreeData;
203  void* mEnd;
204  };
205 
206  size_t mRecordSize;
207  size_t mRecordPoolSize;
208  MemoryBlock* mData;
209 };
210 
211 #include <fbxsdk/fbxsdk_nsend.h>
212 
213 #endif /* _FBXSDK_CORE_BASE_CONTAINER_ALLOCATORS_H_ */
An allocator class for use as a template parameter to one of the container class (FbxMap, FbxSet, FbxDynamicArray...) must implement these.
FBX SDK environment definition.
#define NULL
Definition: fbxarch.h:210
size_t GetRecordSize() const
void FbxDelete(T *p)
Deletion policy for pointer template classes that uses the FbxDelete() function.
Definition: fbxnew.h:341
This allocator only frees the allocated memory when it is deleted.
FbxHungryAllocator(size_t pRecordSize)
void FreeMemory(void *pRecord)
Frees a block of memory returned by AllocateRecords.
FbxBaseAllocator(const size_t pRecordSize)
The class constructor.
FbxHungryAllocator & operator=(const FbxHungryAllocator &pOther)
void Reserve(const size_t pRecordCount)
void Reserve(const size_t)
This tells the allocator that we are about to call AllocateRecords one or many times to allocate pRec...
void * AllocateRecords(const size_t pRecordCount=1)
#define FBXSDK_DLL
Definition: fbxarch.h:173
size_t GetRecordSize() const
FbxHungryAllocator(const FbxHungryAllocator &pOther)
void * AllocateRecords(const size_t pRecordCount=1)
Returns a pointer to a uninitialized continuous block of memory able to hold pRecordCount * pRecordSi...