gwnavgeneration/common/growinglistpool.h Source File

growinglistpool.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 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 #pragma once
9 
13 
14 
15 namespace Kaim
16 {
17 
18 // forward declare
19 template<class T, KyUInt32 NbEl> class GrowingListPool;
20 
21 
22 // ---------------------------------------------------------------------
23 template<class T, KyUInt32 NbEl = 8>
24 class GrowingListNode
25 {
26  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
27 public:
28  GrowingListNode() : m_next(nullptr) {}
29 
30 public:
31  T m_values[NbEl];
32  GrowingListNode<T, NbEl>* m_next;
33 };
34 
35 
36 // ---------------------------------------------------------------------
37 template<class T, KyUInt32 NbEl = 8>
38 class GrowingList
39 {
40  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
41 public:
42  typedef GrowingListPool<T, NbEl> Pool;
43  typedef GrowingListNode<T, NbEl> Node;
44 
45 public:
46  GrowingList();
47 
48  void Init(Pool* pool);
49 
50  T* GetNew();
51 
52  void PushBack(const T& value) { *GetNew() = value; }
53 
54  KyInt32 Count() const { return m_count; }
55 
56  void ToArray(T* values) const;
57 
58 private:
59  Pool* m_pool;
60  KyUInt32 m_count;
61  Node* m_first;
62  Node* m_last;
63  KyUInt32 m_countInLast;
64 };
65 
66 
67 // ---------------------------------------------------------------------
68 template<class T, KyUInt32 NbEl = 8>
69 class GrowingListPool
70 {
71  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
72 public:
73  typedef GrowingListNode<T, NbEl> Node;
74  typedef GrowingList<T, NbEl> List;
75 
76  friend class GrowingList<T, NbEl>;
77 public:
78  explicit GrowingListPool(MemoryHeap* heap, KyUInt32 byteCountInChunk = 0) :
79  m_lists(heap, byteCountInChunk), m_nodes(heap, byteCountInChunk), m_elementCount(0), m_heap(heap) {}
80 
81  List* GetNewList();
82 
83  KyUInt32 GetListChunkCount() { return m_lists.GetChunkCount(); }
84 
85  void Clear();
86 
87  void Release();
88 
89  KyUInt32 ByteCountAllocated() const;
90 
91  KyUInt32 ElementCount() const { return m_elementCount; }
92 
93 private:
94  Node* GetNewNode();
95 private:
96  GrowingPool<List> m_lists;
97  GrowingPool<Node> m_nodes;
98  KyUInt32 m_elementCount;
99  MemoryHeap* m_heap;
100 };
101 
102 
103 template<class T, KyUInt32 NbEl>
104 GrowingList<T, NbEl>::GrowingList()
105 {
106  Init(nullptr);
107 }
108 
109 
110 template<class T, KyUInt32 NbEl>
111 void GrowingList<T, NbEl>::Init(Pool* pool)
112 {
113  m_pool = pool;
114  m_count = 0;
115  m_first = nullptr;
116  m_last = nullptr;
117  m_countInLast = 0;
118 }
119 
120 
121 template<class T, KyUInt32 NbEl>
122 void GrowingList<T, NbEl>::ToArray(T* values) const
123 {
124  if (m_count == 0)
125  return;
126 
127  KyUInt32 idx = 0;
128  for (GrowingListNode<T, NbEl>* node = m_first; node != m_last; node = node->m_next)
129  {
130  for (KyUInt32 i = 0; i < NbEl; ++i, ++idx)
131  values[idx] = node->m_values[i];
132  }
133  for (KyUInt32 i = 0; i < m_countInLast; ++i, ++idx)
134  values[idx] = m_last->m_values[i];
135 }
136 
137 
138 template<class T, KyUInt32 NbEl>
139 T* GrowingList<T, NbEl>::GetNew()
140 {
141  if (m_first == nullptr)
142  {
143  m_last = m_first = m_pool->GetNewNode();
144  }
145  else if (m_countInLast == NbEl)
146  {
147  GrowingListNode<T, NbEl>* newNode = m_pool->GetNewNode();
148  m_last->m_next = newNode;
149  m_last = newNode;
150  m_countInLast = 0;
151  }
152 
153 
154  KY_DEBUG_ASSERTN(m_countInLast >= 0 && m_countInLast < NbEl, ("Can not get a new element"));
155 
156  T* value = &m_last->m_values[m_countInLast];
157 
158  ++m_countInLast;
159  ++m_count;
160  ++m_pool->m_elementCount;
161 
162  return value;
163 }
164 
165 
166 template<class T, KyUInt32 NbEl>
167 GrowingList<T, NbEl>* GrowingListPool<T, NbEl>::GetNewList()
168 {
169  List* list = m_lists.GetNew();
170  list->Init(this);
171  return list;
172 }
173 
174 
175 template<class T, KyUInt32 NbEl>
176 GrowingListNode<T, NbEl>* GrowingListPool<T, NbEl>::GetNewNode()
177 {
178  Node* node = m_nodes.GetNew();
179  return node;
180 }
181 
182 
183 template<class T, KyUInt32 NbEl>
184 void GrowingListPool<T, NbEl>::Clear()
185 {
186  m_lists.Clear();
187  m_nodes.Clear();
188  m_elementCount = 0;
189 }
190 
191 template<class T, KyUInt32 NbEl>
192 void GrowingListPool<T, NbEl>::Release()
193 {
194  m_lists.Release();
195  m_nodes.Release();
196  m_elementCount = 0;
197 }
198 
199 
200 template<class T, KyUInt32 NbEl>
201 KyUInt32 GrowingListPool<T, NbEl>::ByteCountAllocated() const
202 {
203  return m_lists.ByteCountAllocated() + m_nodes.ByteCountAllocated();
204 }
205 
206 
207 }
208 
209 
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
std::int32_t KyInt32
int32_t
Definition: types.h:24