gwnavruntime/containers/poolchunk.h Source File

poolchunk.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 #pragma once
8 
9 #include "gwnavruntime/basesystem/logger.h" // KY_DEBUG_ASSERT
12 
13 namespace Kaim
14 {
15 
16 template<typename T>
17 class PoolChunk
18 {
19  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
20 public:
21  explicit PoolChunk(MemoryHeap* heap, KyUInt32 slotCount, KyUInt32 memStat);
22 
23  ~PoolChunk();
24 
25  KyUInt32 New();
26  KyUInt32 New(const T& data);
27 
28  KY_INLINE void Delete(T* ptr) { Delete(GetIdxInChunk(ptr)); }
29  void Delete(KyUInt32 index);
30 
31  const T* Get(KyUInt32 index) const { return ((T*)m_buffer) + index; }
32  T* Get(KyUInt32 index) { return ((T*)m_buffer) + index; }
33 
34  KY_INLINE bool IsFull() const { return (m_nbFreeSlots == 0); }
35  KY_INLINE bool IsEmpty() const { return (m_nbFreeSlots == GetNbSlots()); }
36 
37  KY_INLINE bool IsPtrInChunk(const T* ptr) const { return ((T*)m_buffer) <= ptr && ptr < (((T*)m_buffer) + m_nbTotalSlots); }
38 
39  KY_INLINE KyUInt32 GetNbSlots() const { return m_nbTotalSlots; }
40  KY_INLINE KyUInt32 GetNbUsedSlots() const { return m_nbTotalSlots - m_nbFreeSlots; }
41 
42  KyUInt32 GetIdxInChunk(const T* ptr) const { return KyUInt32(ptr - (T*)m_buffer); }
43 
44  bool SuperSlow_IsSlotFree(KyUInt32 index) const;
45 
46 private:
47 
48  KyUInt32 GetNextFreeSlot(KyUInt32 index) const { return *((KyUInt32*) (m_buffer + (sizeof(T) * index))); }
49  void SetNextFreeSlot(KyUInt32 index, KyUInt32 freeSlotIndex) { *((KyUInt32*) (m_buffer + (sizeof(T) * index))) = freeSlotIndex; }
50 
51  KyUInt32 GetFreeSlotAndMakeUsed();
52  void MakeSlotFree(KyUInt32 index);
53 
54 private:
55  char* m_buffer;
56  KyUInt32 m_nbFreeSlots;
57  KyUInt32 m_nbTotalSlots;
58  KyUInt32 m_firstFreeSlot;
59 };
60 
61 
62 
63 template<typename T>
64 PoolChunk<T>::PoolChunk(MemoryHeap* heap, KyUInt32 slotCount, KyUInt32 memStat) :
65  m_buffer((char*)KY_HEAP_ALLOC(heap, (sizeof(T) * slotCount), memStat)),
66  m_nbFreeSlots(slotCount),
67  m_nbTotalSlots(slotCount),
68  m_firstFreeSlot(0)
69 {
70  KY_DEBUG_ASSERTN(sizeof (T) >= 4, ("Type should be bigger to enable some functionalities"));
71  KY_DEBUG_ASSERTN(slotCount != 0, ("Bad parameter"));
72 
73  KY_UNUSED(memStat);
74 
75  for (KyUInt32 i = 0; i < slotCount; ++i)
76  SetNextFreeSlot(i, i + 1);
77 }
78 
79 
80 template<typename T>
81 PoolChunk<T>::~PoolChunk()
82 {
83  if (IsEmpty() == false)
84  {
85  KY_LOG_WARNING(("Bad usage of PoolChunk : you should call 'Delete' for each 'New'."));
86  }
87  KY_FREE(m_buffer);
88 }
89 
90 
91 template<typename T>
92 KyUInt32 PoolChunk<T>::New()
93 {
94  KY_ASSERT(IsFull() == false);
95 
96  const KyUInt32 index = GetFreeSlotAndMakeUsed();
97  T* mem = Get(index);
98 
99  new (mem) T;
100  return index;
101 }
102 
103 template<typename T>
104 KyUInt32 PoolChunk<T>::New(const T& data)
105 {
106  KY_ASSERT(IsFull() == false);
107 
108  const KyUInt32 index = GetFreeSlotAndMakeUsed();
109  T* mem = Get(index);
110 
111  new (mem) T(data);
112  return index;
113 }
114 
115 template<typename T>
116 void PoolChunk<T>::Delete(KyUInt32 index)
117 {
118  KY_ASSERT(index < m_nbTotalSlots);
119  Get(index)->~T();
120  MakeSlotFree(index);
121 }
122 
123 
124 template<typename T>
125 bool PoolChunk<T>::SuperSlow_IsSlotFree(KyUInt32 index) const
126 {
127  KyUInt32 freeSlotIdx = m_firstFreeSlot;
128 
129  for (KyUInt32 i = 0; i != m_nbFreeSlots; ++i)
130  {
131  if (freeSlotIdx == index)
132  return true;
133  freeSlotIdx = GetNextFreeSlot(freeSlotIdx);
134  }
135  return false;
136 }
137 
138 
139 template<typename T>
140 KyUInt32 PoolChunk<T>::GetFreeSlotAndMakeUsed()
141 {
142  const KyUInt32 res = m_firstFreeSlot;
143  m_firstFreeSlot = GetNextFreeSlot(m_firstFreeSlot);
144  --m_nbFreeSlots;
145  return res;
146 }
147 
148 
149 template<typename T>
150 void PoolChunk<T>::MakeSlotFree(KyUInt32 index)
151 {
152  SetNextFreeSlot(index, m_firstFreeSlot);
153  m_firstFreeSlot = index;
154  ++m_nbFreeSlots;
155 }
156 
157 
158 } // namespace Kaim
159 
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