gwnavgeneration/common/growingpool.h Source File

growingpool.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 // primary contact: GUAL - secondary contact: NOBODY
9 #ifndef GwNavGen_GrowingPool_H
10 #define GwNavGen_GrowingPool_H
11 
12 
15 
16 
17 namespace Kaim
18 {
19 
20 /*
21 // To browse the GrowingPool use the following code
22 MyClass* chunk = KY_NULL;
23 KyUInt32 countInChunk = 0;
24 for (KyUInt32 chunkIdx = 0; chunkIdx < pool.GetChunkCount(); ++chunkIdx)
25 {
26  pool.GetChunk(chunkIdx, chunk, countInChunk);
27  for (KyUInt32 idx = 0; idx < countInChunk; ++idx)
28  {
29  MyClass& obj = chunk[idx];
30  }
31 }
32 */
33 template <class T>
34 class GrowingPool
35 {
36  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
37 public:
38  explicit GrowingPool(MemoryHeap* heap, KyUInt32 byteCountInChunk = 0);
39 
40  ~GrowingPool() { Release(); }
41 
42  // Does call T constructor.
43  T* GetNew();
44 
45  void Clear();
46 
47  void Release();
48 
49  KyUInt32 GetElementCount() const { return m_elementCount; }
50  KyUInt32 GetChunkCount() const { return m_chunkCount; }
51  KyUInt32 ByteCountAllocated() const { return m_byteCountAllocated; }
52 
53  void GetChunk(KyUInt32 idx, T*& chunk, KyUInt32& countInChunk);
54 
55 
56 private:
57  KyUInt32 CalculateElementCountFromByteCount(KyInt32 byteCount);
58  KyUInt32 CalculateWordCount(KyInt32 elementCount);
59 
60 private:
61  KyArrayDH_POD<T*> m_chunks;
62  KyUInt32 m_chunkCount;
63  KyUInt32 m_elementCount;
64  KyUInt32 m_maxWordCountInChunk;
65  KyUInt32 m_maxElementCountInChunk;
66  KyUInt32 m_elementCountInLastChunk;
67  KyUInt32 m_byteCountAllocated;
68  MemoryHeap* m_heap;
69 };
70 
71 
72 template<class T>
73 inline GrowingPool<T>::GrowingPool(MemoryHeap* heap, KyUInt32 byteCountInChunk) : m_chunks(heap)
74 {
75  if (byteCountInChunk <= 0)
76  byteCountInChunk = 512 * 1024; // 512 KB by default
77 
78  m_chunks.Resize(16);
79  for (KyUInt32 i = 0 ; i < m_chunks.GetCount(); ++i)
80  m_chunks[i] = KY_NULL;
81 
82  m_chunkCount = 0;
83  m_elementCount = 0;
84  m_maxElementCountInChunk = CalculateElementCountFromByteCount(byteCountInChunk);
85  m_maxWordCountInChunk = CalculateWordCount(m_maxElementCountInChunk);
86  m_elementCountInLastChunk = m_maxElementCountInChunk;
87  m_byteCountAllocated = 0;
88  m_heap = heap;
89 }
90 
91 
92 template<class T>
93 inline T* GrowingPool<T>::GetNew()
94 {
95  if (m_elementCountInLastChunk == m_maxElementCountInChunk) // we reached the end of the current chunk
96  {
97  KyUInt32 oldSize = m_chunks.GetCount();
98  if (m_chunkCount >= oldSize) // no more chunks in m_chunks, resize it
99  {
100  m_chunks.Resize(oldSize * 2);
101  for (KyUInt32 i = oldSize; i < m_chunks.GetCount(); ++i)
102  m_chunks[i] = KY_NULL;
103  }
104 
105  if (m_chunks[m_chunkCount] == KY_NULL) // need to allocate a new chunk
106  {
107  m_chunks[m_chunkCount] = (T*)KY_HEAP_MALLOC(m_heap, KyUInt32, m_maxWordCountInChunk, MemStat_NavDataGen);
108  m_byteCountAllocated += m_maxWordCountInChunk * sizeof(KyUInt32);
109  }
110 
111  ++m_chunkCount;
112  m_elementCountInLastChunk = 0;
113  }
114 
115  ++m_elementCount;
116 
117  T* ptr = &m_chunks[m_chunkCount - 1][m_elementCountInLastChunk];
118  ::new(ptr) T;
119 
120  ++m_elementCountInLastChunk;
121  return ptr;
122 }
123 
124 
125 template<class T>
126 inline void GrowingPool<T>::Clear()
127 {
128  // call destructor on elements
129  T* chunk = KY_NULL;
130  KyUInt32 countInChunk = 0;
131 
132  for (KyUInt32 chunkIdx = 0; chunkIdx < GetChunkCount(); ++chunkIdx)
133  {
134  GetChunk(chunkIdx, chunk, countInChunk);
135  for (KyUInt32 idx = 0; idx < countInChunk; ++idx)
136  chunk[idx].~T();
137  }
138 
139  m_elementCount = 0;
140  m_chunkCount = 0;
141  m_elementCountInLastChunk = m_maxElementCountInChunk;
142 }
143 
144 
145 template<class T>
146 inline void GrowingPool<T>::Release()
147 {
148  Clear();
149 
150  for (KyUInt32 i = 0; i < m_chunks.GetCount(); ++i)
151  KY_FREE(m_chunks[i]);
152 
153  m_chunks.ClearAndRelease();
154  m_byteCountAllocated = 0;
155 }
156 
157 
158 template<class T>
159 KY_INLINE void GrowingPool<T>::GetChunk(KyUInt32 idx, T*& chunk, KyUInt32& countInChunk)
160 {
161  chunk = m_chunks[idx];
162  countInChunk = (idx != m_chunkCount - 1) ? m_maxElementCountInChunk : m_elementCountInLastChunk;
163 }
164 
165 
166 template<class T>
167 KY_INLINE KyUInt32 GrowingPool<T>::CalculateElementCountFromByteCount(KyInt32 byteCount)
168 {
169  return (byteCount - 1) / (KyInt32)sizeof (T) + 1;
170 }
171 
172 template<class T>
173 KY_INLINE KyUInt32 GrowingPool<T>::CalculateWordCount(KyInt32 elementCount)
174 {
175  return (elementCount * (KyInt32)sizeof (T) - 1) / sizeof(KyUInt32) + 1;
176 }
177 
178 } // namespace Kaim
179 
180 #endif
int KyInt32
Type used internally to represent a 32-bit integer.
Definition: types.h:35
#define KY_NULL
Null value.
Definition: types.h:247
Definition: gamekitcrowddispersion.h:20
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36