FBX C++ API Reference
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 
20 #if defined(FBXSDK_COMPILER_MSC) && _MSC_VER < 1900
21 #pragma warning(push)
22 #pragma warning(disable : 4512) // to avoid: assignment operator could not be generated
23 #endif
24 
29 {
30 public:
37  FbxBaseAllocator(const size_t pRecordSize) :
38  mRecordSize(pRecordSize)
39  {
40  }
41 
49  void Reserve(const size_t /*pRecordCount*/)
50  {
51  // By default, ignore all preallocating requests.
52  }
53 
59  void* AllocateRecords(const size_t pRecordCount=1)
60  {
61  return FbxMalloc(FbxAllocSize(pRecordCount, mRecordSize));
62  }
63 
67  void FreeMemory(void* pRecord)
68  {
69  FbxFree(pRecord);
70  }
71 
74  size_t GetRecordSize() const
75  {
76  return mRecordSize;
77  }
78 
79 private:
80  const size_t mRecordSize;
81 };
82 
88 {
89 public:
90  FbxHungryAllocator(size_t pRecordSize) :
91  mRecordSize(pRecordSize),
92  mRecordPoolSize(0),
93  mData(NULL)
94  {
95  }
96 
98  mRecordSize(pOther.mRecordSize),
99  mRecordPoolSize(pOther.mRecordPoolSize),
100  mData(NULL)
101  {
102  }
103 
105  {
106  MemoryBlock* lCurrent = mData;
107  MemoryBlock* lNext = lCurrent ? lCurrent->mNextBlock : 0;
108  while (lCurrent)
109  {
110  FbxDelete(lCurrent);
111  lCurrent = lNext;
112  lNext = lCurrent ? lCurrent->mNextBlock : 0;
113  }
114  }
115 
116  void Reserve(const size_t pRecordCount)
117  {
118  MemoryBlock* lMem = FbxNew< MemoryBlock >(pRecordCount* mRecordSize);
119  lMem->mNextBlock = mData;
120  mData = lMem;
121  mRecordPoolSize += pRecordCount;
122  }
123 
124  void* AllocateRecords(const size_t pRecordCount = 1)
125  {
126  MemoryBlock* lBlock = mData;
127  void* lRecord = NULL;
128 
129  while( (lBlock != NULL) && ((lRecord = lBlock->GetChunk(pRecordCount * mRecordSize)) == NULL) )
130  {
131  lBlock = lBlock->mNextBlock;
132  }
133 
134  if( lRecord == NULL )
135  {
136  size_t lNumRecordToAllocate = mRecordPoolSize / 8 == 0 ? 2 : mRecordPoolSize / 8;
137  if( lNumRecordToAllocate < pRecordCount )
138  {
139  lNumRecordToAllocate = pRecordCount;
140  }
141  Reserve(lNumRecordToAllocate);
142  lRecord = AllocateRecords(pRecordCount);
143  }
144  return lRecord;
145  }
146 
147  void FreeMemory(void* /*pRecord*/)
148  {
149  // "Hungry": release memory only when the allocator is destroyed.
150  }
151 
152  size_t GetRecordSize() const
153  {
154  return mRecordSize;
155  }
156 
158  {
159  if( this != &pOther )
160  {
161  // The next call to AllocateRecords() may skip over currently reserved
162  // records if the size changes drastically, but otherwise GetChunk()
163  // is size-oblivious.
164  if( mRecordSize < pOther.mRecordSize )
165  {
166  mRecordPoolSize = 0;
167  }
168 
169  mRecordSize = pOther.mRecordSize;
170  }
171  return(*this);
172  }
173 
174 private:
175  class MemoryBlock
176  {
177  public:
178  MemoryBlock(size_t pSize) :
179  mNextBlock(NULL),
180  mData(NULL),
181  mFreeData(NULL),
182  mEnd(NULL)
183  {
184  mData = FbxMalloc(pSize);
185  mFreeData = mData;
186  mEnd = reinterpret_cast<char*>(mData) + pSize;
187  }
188 
189  ~MemoryBlock()
190  {
191  FbxFree(mData);
192  }
193 
194  void* GetChunk(const size_t pSize)
195  {
196  if( reinterpret_cast<char*>(mFreeData) + pSize < mEnd )
197  {
198  void* lChunk = mFreeData;
199  mFreeData = reinterpret_cast<char*>(mFreeData) + pSize;
200  return lChunk;
201  }
202  return NULL;
203  }
204 
205  MemoryBlock* mNextBlock;
206  void* mData;
207  void* mFreeData;
208  void* mEnd;
209  };
210 
211  size_t mRecordSize;
212  size_t mRecordPoolSize;
213  MemoryBlock* mData;
214 };
215 
216 #if defined(FBXSDK_COMPILER_MSC) && _MSC_VER < 1900
217 #pragma warning(pop)
218 #endif
219 
220 #include <fbxsdk/fbxsdk_nsend.h>
221 
222 #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:213
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:176
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...