gwnavruntime/containers/poolchunk.h Source File

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