Cafu Engine
Pool.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_POOL_HPP_INCLUDED
8 #define CAFU_POOL_HPP_INCLUDED
9 
10 
11 namespace cf
12 {
13  /// This class manages memory for a pool of objects.
14  /// Works best for POD- and simple class types, because:
15  /// - Only calls the default ctor.
16  /// - Does not really free the elements, only when the entire pool is deleted.
17  /// - Works best when only small arrays (with few elements) are alloc'ed, so that there is not too much Verschnitt.
18  /// - GetSize() does not take calls Free() into account.
19  template<class T> class PoolNoFreeT
20  {
21  public:
22 
23  PoolNoFreeT(unsigned long SizeOfFirstBlock=8) : SizeOfNextBlock(SizeOfFirstBlock), ElementsRemaining(0), UserSize(0)
24  {
25  }
26 
27  ~PoolNoFreeT()
28  {
29  // TODO: It would be great if we could assert that each call to Alloc() has been matched by a call to Free() when we get here.
30  for (unsigned long BlockNr=0; BlockNr<Blocks.Size(); BlockNr++)
31  delete[] Blocks[BlockNr];
32  }
33 
34  /// Returns a pointer to Size allocated objects of type T.
35  T* Alloc(unsigned long Size=1)
36  {
37  if (Size==0) return NULL;
38 
39  if (Size>ElementsRemaining)
40  {
41  // There are not enough elements left for an array of length Size.
42  // First make sure that the next block *will* have enough elements.
43  while (SizeOfNextBlock<Size) SizeOfNextBlock*=2;
44 
45  Blocks.PushBack(new T[SizeOfNextBlock]);
46  ElementsRemaining=SizeOfNextBlock;
47 
48  SizeOfNextBlock*=2;
49  }
50 
51  ElementsRemaining-=Size;
52  UserSize+=Size;
53  return Blocks[Blocks.Size()-1]+ElementsRemaining;
54  }
55 
56  void Free(T* /*Array*/)
57  {
58  // Intentionally do nothing here - we can't do anything useful anyway, that is.
59  // TODO: assert(Array is actually from one of our Blocks);
60  // TODO: Update the UserSize variable!
61  }
62 
63  unsigned long GetSize() const
64  {
65  return UserSize;
66  }
67 
68 
69  private:
70 
71  PoolNoFreeT(const PoolNoFreeT<T>&); ///< Use of the Copy Constructor is not allowed.
72  void operator = (const PoolNoFreeT<T>&); ///< Use of the Assignment Operator is not allowed.
73 
74  unsigned long SizeOfNextBlock;
75  unsigned long ElementsRemaining; ///< How many elements are still unused and thus free for allocation in the last block.
76  unsigned long UserSize; ///< The total number of elements requested with and returned by Alloc().
77  ArrayT<T*> Blocks;
78  };
79 
80 
81  /// This class manages memory for a pool of objects.
82  /// Works best for POD- and simple class types, because:
83  /// - Doesn't really care about ctor and dtor calls.
84  /// - Can only allocate a single element at a time.
85  template<class T> class PoolSingleT
86  {
87  public:
88 
89  PoolSingleT(unsigned long SizeOfFirstBlock=8) : SizeOfNextBlock(SizeOfFirstBlock), ElementsRemaining(0), AllocedElemCount(0)
90  {
91  FreeElements.PushBackEmpty(SizeOfFirstBlock*3); // Reserve enough for first and second block.
92  FreeElements.Overwrite();
93  }
94 
95  ~PoolSingleT()
96  {
97  // If AllocedElemCount!=0 here, the user is leaking memory.
98  assert(AllocedElemCount==0);
99 
100  for (unsigned long BlockNr=0; BlockNr<Blocks.Size(); BlockNr++)
101  delete[] Blocks[BlockNr];
102  }
103 
104  /// Returns a pointer to an objects of type T.
105  T* Alloc()
106  {
107  AllocedElemCount++;
108 
109  if (FreeElements.Size()>0)
110  {
111  T* Element=FreeElements[FreeElements.Size()-1];
112 
113  FreeElements.DeleteBack();
114  // Note: No constructor call for Element here.
115  return Element;
116  }
117 
118  if (ElementsRemaining>0)
119  {
120  ElementsRemaining--;
121  return Blocks[Blocks.Size()-1]+ElementsRemaining;
122  }
123 
124  // No elements were left in the last block.
125  assert(SizeOfNextBlock>0);
126  Blocks.PushBack(new T[SizeOfNextBlock]);
127  ElementsRemaining=SizeOfNextBlock;
128 
129  SizeOfNextBlock*=2;
130 
131  ElementsRemaining--;
132  return Blocks[Blocks.Size()-1]+ElementsRemaining;
133  }
134 
135  void Free(T* Element)
136  {
137  // Note: No destructor call for Element here.
138  FreeElements.PushBack(Element);
139  AllocedElemCount--;
140  }
141 
142 
143  private:
144 
145  PoolSingleT(const PoolSingleT<T>&); ///< Use of the Copy Constructor is not allowed.
146  void operator = (const PoolSingleT<T>&); ///< Use of the Assignment Operator is not allowed.
147 
148  unsigned long SizeOfNextBlock; ///< How many elements the next allocated block will have.
149  unsigned long ElementsRemaining;///< How many elements are still unused and thus free for allocation in the last block.
150  ArrayT<T*> Blocks; ///< The actual blocks of allocated T.
151  ArrayT<T*> FreeElements; ///< Instances of T that have been freed and are thus ready for reuse.
152  unsigned long AllocedElemCount; ///< The number of elements that are currently been allocated by the user.
153  };
154 }
155 
156 
157 
158 /*
159 // Variante 1:
160 // - Only calls the default ctor.
161 // - Cannot alloc arrays (only just one).
162 
163 // Variante 2:
164 // - Only calls the default ctor.
165 // - Can alloc arrays, but not individually free().
166 
167 template<class T> class PoolT
168 {
169  public:
170 
171  PoolT(); ///< Constructor.
172  ~PoolT(); ///< Destructor.
173 
174  /// Returns a pointer to Size allocated objects of type T.
175  T* alloc(unsigned long Size=1);
176 
177  void free(T*);
178 
179 
180  private:
181 
182  PoolT(const PoolT<T>&); ///< Use of the Copy Constructor is not allowed.
183  void operator = (const PoolT<T>&); ///< Use of the Assignment Operator is not allowed.
184 
185  ArrayT<T*> Elements;
186 }; */
187 
188 #endif
This class manages memory for a pool of objects.
Definition: Pool.hpp:85
unsigned long Size() const
Get size of array.
Definition: Array.hpp:138
T * Alloc()
Returns a pointer to an objects of type T.
Definition: Pool.hpp:105
T * Alloc(unsigned long Size=1)
Returns a pointer to Size allocated objects of type T.
Definition: Pool.hpp:35
void Overwrite()
Clear array (but reuse memory)
Definition: Array.hpp:154
This class manages memory for a pool of objects.
Definition: Pool.hpp:19