CUGL
Cornell University Game Library
CUFreeList.h
1 //
2 // CUFreeList.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This header provides a template for a free list class. A free list allows
6 // you to "recycle" memory. As allocating and deleting memory is an expensive
7 // operation, this has significant performance problems with systems that
8 // create a lot of short live objects (e.g. particle systems). Free lists
9 // solve this problem by replacing the new operator with a method to manage
10 // your memory.
11 //
12 // A free list can also allocate a block of memory at creation. This allows
13 // you to group all your initial allocations ahead of time. See the class
14 // documentation for more information.
15 //
16 // This is not a class. It is a class template. Templates do not have cpp
17 // files. They only have a header file. When you include the header, it
18 // compiles the specific template used by your program. Hence all of the code
19 // for this templated class is in this header.
20 //
21 // CUGL zlib License:
22 // This software is provided 'as-is', without any express or implied
23 // warranty. In no event will the authors be held liable for any damages
24 // arising from the use of this software.
25 //
26 // Permission is granted to anyone to use this software for any purpose,
27 // including commercial applications, and to alter it and redistribute it
28 // freely, subject to the following restrictions:
29 //
30 // 1. The origin of this software must not be misrepresented; you must not
31 // claim that you wrote the original software. If you use this software
32 // in a product, an acknowledgment in the product documentation would be
33 // appreciated but is not required.
34 //
35 // 2. Altered source versions must be plainly marked as such, and must not
36 // be misrepresented as being the original software.
37 //
38 // 3. This notice may not be removed or altered from any source distribution.
39 //
40 // Author: Walker White
41 // Version: 11/29/16
42 //
43 #ifndef __CU_FREE_LIST_H__
44 #define __CU_FREE_LIST_H__
45 #include <queue>
46 
47 namespace cugl {
48 
49 #pragma mark -
50 #pragma mark FreeList Template
51 
89 template <class T>
90 class FreeList {
91 protected:
93  size_t _allocated;
95  size_t _released;
97  size_t _peaksize;
98 
102  size_t _capacity;
103 
105  std::queue<T*> _freeobjs;
106 
110  std::queue<T*> _expansion;
111 
112 #pragma mark Constructors
113 public:
122  FreeList() : _allocated(0), _released(0), _peaksize(0), _prealloc(nullptr),
123  _capacity(0), _expandable(false) { }
124 
132 
140  void dispose() {
141  clear();
142  if (_prealloc != nullptr) {
143  delete[] _prealloc;
144  }
145  }
146 
157  bool init(size_t capacity) {
158  CUAssertLog(capacity, "An unexapandable free list must have non-zero capacity");
159  _expandable = false;
160  _capacity = capacity;
161  _released = 0;
162  _allocated = 0;
163  _prealloc = (_capacity > 0 ? new T[_capacity] : nullptr);
164  return _prealloc;
165  }
166 
179  bool init(size_t capacity, bool expand) {
180  CUAssertLog(capacity || expand, "The free list must be expandable or have capacity non-zero");
181  _expandable = expand;
182  _capacity = capacity;
183  _released = 0;
184  _allocated = 0;
185  _prealloc = (_capacity > 0 ? new T[_capacity] : nullptr);
186  return _capacity == 0 || _prealloc;
187  }
188 
201  static std::shared_ptr<FreeList<T>> alloc(size_t capacity=0, bool expand=false) {
202  std::shared_ptr<FreeList<T>> result = std::make_shared<FreeList<T>>();
203  return (result->init(capacity,expand) ? result : nullptr);
204  }
205 
206 
207 #pragma mark Accessors
208 
216  size_t getAvailable() const { return (_capacity-(long)_allocated)+_freeobjs.size(); }
217 
226  size_t getCapacity() const { return _capacity; }
227 
236  size_t getUsage() const { return _allocated-_released; }
237 
246  size_t getPeakUsage() const { return _peaksize; }
247 
256  bool isExpandable() const { return _expandable; }
257 
265  const T* getPreallocated() const { return _prealloc; }
266 
267 
268 #pragma mark Memory Managment
269 
279  T* malloc();
280 
295  void free(T* obj);
296 
304  virtual void clear();
305 };
306 
307 
308 #pragma mark -
309 #pragma mark Method Implementations
310 
321 template <class T>
323  T* result = nullptr;
324  if (!_freeobjs.empty()) {
325  result = _freeobjs.front();
326  _freeobjs.pop();
327  _allocated++;
328  } else if (_allocated < _capacity) {
329  result = &_prealloc[_allocated];
330  _allocated++;
331  } else if (_expandable) {
332  result = new T();
333  _expansion.push(result);
334  _allocated++;
335  }
336  _peaksize = (_peaksize < getUsage() ? getUsage() : _peaksize);
337  return result;
338 }
339 
354 template <class T>
355 void FreeList<T>::free(T* obj) {
356  CCASSERT(obj != nullptr, "Attempt to free null pointer");
357  _freeobjs.push(obj);
358  obj->reset();
359  _released++;
360 }
361 
369 template <class T>
371  // We own anything in expansion. Clear it.
372  while (!_expansion.empty()) {
373  T* a = _expansion.front();
374  _expansion.pop();
375  delete a;
376  }
377 
378  // Clear the preallocated
379  for(int ii =0; ii < _capacity; ii++) {
380  _prealloc[ii].reset();
381  }
382 
383  // Clear everything else
384  while (!_expansion.empty()) {
385  _freeobjs.pop();
386  }
387 
388  _allocated = 0;
389  _released = 0;
390 }
391 
392 }
393 #endif /* __CU_FREE_LIST_H__ */
size_t _peaksize
Definition: CUFreeList.h:97
bool isExpandable() const
Definition: CUFreeList.h:256
size_t getCapacity() const
Definition: CUFreeList.h:226
Definition: CUFreeList.h:90
size_t getUsage() const
Definition: CUFreeList.h:236
FreeList()
Definition: CUFreeList.h:122
size_t _allocated
Definition: CUFreeList.h:93
size_t getAvailable() const
Definition: CUFreeList.h:216
void free(T *obj)
Definition: CUFreeList.h:355
static std::shared_ptr< FreeList< T > > alloc(size_t capacity=0, bool expand=false)
Definition: CUFreeList.h:201
bool _expandable
Definition: CUFreeList.h:108
std::queue< T * > _freeobjs
Definition: CUFreeList.h:105
std::queue< T * > _expansion
Definition: CUFreeList.h:110
size_t _released
Definition: CUFreeList.h:95
T * malloc()
Definition: CUFreeList.h:322
size_t getPeakUsage() const
Definition: CUFreeList.h:246
const T * getPreallocated() const
Definition: CUFreeList.h:265
void dispose()
Definition: CUFreeList.h:140
virtual void clear()
Definition: CUFreeList.h:370
~FreeList()
Definition: CUFreeList.h:131
bool init(size_t capacity, bool expand)
Definition: CUFreeList.h:179
Definition: CUAnimationNode.h:52
size_t _capacity
Definition: CUFreeList.h:102
T * _prealloc
Definition: CUFreeList.h:100
bool init(size_t capacity)
Definition: CUFreeList.h:157