gwnavruntime/containers/pool.h Source File

pool.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 
13 
14 namespace Kaim
15 {
16 
17 
18 // PoolHandle
19 // - allows Delete(Handle handle) in O(1)
20 // - has sizeof() = 8 on 32 bits
21 // - has sizeof() = 16 on 64 bits
22 // - points directly to the value
23 template <typename T>
24 class PoolHandle
25 {
26  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
27 
28 public:
29  KY_INLINE PoolHandle() : m_chunkIdx(KyUInt32MAXVAL), m_ptr(nullptr) {}
30  KY_INLINE PoolHandle(KyUInt32 chunkIdx, T* value) : m_chunkIdx(chunkIdx), m_ptr(value) {}
31  KY_INLINE PoolHandle(const PoolHandle& rhs) : m_chunkIdx(rhs.m_chunkIdx), m_ptr(rhs.m_ptr) {}
32 
33  KY_INLINE PoolHandle& operator=(const PoolHandle& rhs) { m_chunkIdx = rhs.m_chunkIdx; m_ptr = rhs.m_ptr; return *this; }
34 
35  KY_INLINE T& Get() const { return *m_ptr; }
36  KY_INLINE T& operator*() { return *m_ptr; }
37  KY_INLINE T* operator->() { return m_ptr; }
38 
39  KY_INLINE void Invalidate() { m_chunkIdx = KyUInt32MAXVAL; m_ptr = nullptr; }
40  KY_INLINE bool IsValid() const { return m_ptr != nullptr; }
41 
42  KY_INLINE bool operator==(const PoolHandle& rhs) const { return m_ptr == rhs.m_ptr; }
43  KY_INLINE bool operator!=(const PoolHandle& rhs) const { return m_ptr != rhs.m_ptr; }
44 
45 public:
46  KyUInt32 m_chunkIdx;
47  T* m_ptr;
48 };
49 
50 
51 // PoolKey
52 // - allows Delete(Key compactKey) in O(1)
53 // - has sizeof() = 4
54 // - requires 2 indirections to get the value
55 class PoolKey
56 {
57  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
58 
59 public:
60  KY_INLINE PoolKey() : m_chunkIdx(KyUInt16MAXVAL), m_idxInChunk(KyUInt16MAXVAL) {}
61 
62  KY_INLINE PoolKey(KyUInt32 chunkIdx, KyUInt32 idxInChunk) : m_chunkIdx(KyUInt16(chunkIdx)), m_idxInChunk(KyUInt16(idxInChunk)) {}
63 
64  KY_INLINE PoolKey(const PoolKey& rhs) : m_chunkIdx(rhs.m_chunkIdx), m_idxInChunk(rhs.m_idxInChunk) {}
65 
66  KY_INLINE PoolKey& operator=(const PoolKey& rhs) { m_chunkIdx = rhs.m_chunkIdx; m_idxInChunk = rhs.m_idxInChunk; return *this; }
67 
68  KY_INLINE void Invalidate() { m_chunkIdx = KyUInt16MAXVAL; m_idxInChunk = KyUInt16MAXVAL; }
69  KY_INLINE bool IsValid() const { return m_chunkIdx != KyUInt16MAXVAL && m_idxInChunk != KyUInt16MAXVAL; }
70 
71  KY_INLINE bool operator==(const PoolKey& rhs) const { return m_chunkIdx == rhs.m_chunkIdx && m_idxInChunk == rhs.m_idxInChunk; }
72  KY_INLINE bool operator!=(const PoolKey& rhs) const { return !(*this == rhs); }
73 
74 public:
75  KyUInt16 m_chunkIdx;
76  KyUInt16 m_idxInChunk;
77 };
78 
79 
80 struct PoolChunkSize
81 {
82  enum Mode { ByteSize, SlotCount, WaitInit };
83 };
84 
85 template <typename T>
86 struct PoolChunkElement
87 {
88  PoolChunkElement() : m_chunk(nullptr), m_next(KyUInt32MAXVAL) {}
89  PoolChunkElement(PoolChunk<T>* chunk) : m_chunk(chunk), m_next(KyUInt32MAXVAL) {}
90  PoolChunk<T>* m_chunk;
91  KyUInt32 m_next; // next non full chunk
92 };
93 
94 
95 template <typename T>
96 class Pool
97 {
98  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
100  typedef PoolChunk<T> ChunkT;
101  typedef PoolChunkElement<T> ChunkElemT;
102 
103 public:
104  typedef PoolHandle<T> Handle;
105  typedef PoolKey Key;
106 
107 public:
108  explicit Pool(MemoryHeap* heap, KyInt32 memStat, PoolChunkSize::Mode chunkSizeMode = PoolChunkSize::ByteSize, KyUInt32 byteOrSlotCount = 256);
109 
110  void Init(PoolChunkSize::Mode chunkSizeMode, KyUInt32 byteOrSlotCount);
111 
112  ~Pool();
113 
114  KY_INLINE KyUInt32 GetCount() const { return m_count; }
115 
116  // -------- Key access --------
117  KY_INLINE Key New_CompactKey();
118  KY_INLINE Key New_CompactKey(const T& data);
119 
120  KY_INLINE void New_CompactKeyAndPtr(Key& key, T*& ptr);
121 
122  KY_INLINE const T& Get(Key key) const { return *GetChunk(key).Get(key.m_idxInChunk); }
123  KY_INLINE T& Get(Key key) { return *GetChunk(key).Get(key.m_idxInChunk); }
124 
125  KY_INLINE void Delete(Key key) { Delete(key.m_chunkIdx, key.m_idxInChunk); }
126 
127  // -------- Handle access --------
128  KY_INLINE Handle New_Handle();
129  KY_INLINE Handle New_Handle(const T& data);
130  KY_INLINE void Delete(const Handle& handle) { Delete(handle.m_chunkIdx, GetChunk(handle).GetIdxInChunk(handle.m_ptr)); }
131 
132  // -------- ptr access Delete() is in O(nbChunks) --------
133  KY_INLINE T* New_Ptr();
134  KY_INLINE T* New_Ptr(const T& data);
135  KY_INLINE void Delete(T* ptr)
136  {
137  KyUInt32 chunkIdx = Ptr2ChunkIdx(ptr);
138  Delete(chunkIdx, GetChunk(chunkIdx).GetIdxInChunk(ptr));
139  }
140 
141  // --------
142  KY_INLINE Key Handle2CompactKey(const Handle& h) const { return Key(h.m_chunkIdx, Ptr2IdxInChunk(h.m_chunkIdx, h.m_ptr)); }
143  KY_INLINE Handle CompactKey2Handle(Key key) const { return Handle(key.m_chunkIdx, GetChunk(key).Get(key.m_idxInChunk)); }
144 
145  KY_INLINE KyUInt32 GetChunkCount() const { return m_chunkElems.GetCount(); }
146  KY_INLINE KyUInt32 GetNbSlotsByChunk() const { return m_nbSlotsByChunk; }
147 
148  KyUInt32 Ptr2ChunkIdx(T* ptr) const; // O(NbChunks)
149  KY_INLINE KyUInt32 Ptr2IdxInChunk(KyUInt32 chunkIdx, T* ptr) const { return GetChunk(chunkIdx).GetIdxInChunk(ptr); }
150 
151  KY_INLINE T& Get(KyUInt32 chunkIdx, KyUInt32 idxInChunk) const { return *GetChunk(chunkIdx).Get(idxInChunk); }
152 
153  KY_INLINE KyUInt32 GetGlobalIdx(const Handle& handle) { return handle.m_chunkIdx * m_nbSlotsByChunk + Ptr2IdxInChunk(handle.m_chunkIdx, handle.m_ptr); }
154  KY_INLINE KyUInt32 GetGlobalIdx(Key key) { return key.m_chunkIdx * m_nbSlotsByChunk + key.m_idxInChunk; }
155  KY_INLINE KyUInt32 GetGlobalIdx(T* ptr) { KyUInt32 chunkIdx = Ptr2ChunkIdx(ptr); return chunkIdx * m_nbSlotsByChunk + Ptr2IdxInChunk(chunkIdx, ptr); }
156 
157 private:
158  void PushBackNewChunk();
159 
160  struct Slot
161  {
162  void Set(KyUInt32 chunkIdx, ChunkT* chunk, KyUInt32 idxInChunk) { m_chunkIdx = chunkIdx; m_idxInchunk = idxInChunk; m_chunk = chunk; m_value = chunk->Get(idxInChunk); }
163  KyUInt32 m_chunkIdx; KyUInt32 m_idxInchunk; ChunkT* m_chunk; T* m_value;
164  };
165 
166  void NewSlot(Slot& slot);
167  void Delete(KyUInt32 chunkIdx, KyUInt32 idxInChunk);
168 
169  void Slot2CompactKey(const Slot& slot, Key& key);
170 
171  ChunkT& GetChunk(const Handle& handle) { return *m_chunkElems[handle.m_chunkIdx].m_chunk; }
172  ChunkT& GetChunk(Key key) { return *m_chunkElems[key.m_chunkIdx].m_chunk; }
173  ChunkT& GetChunk(Key key) const { return *m_chunkElems[key.m_chunkIdx].m_chunk; }
174  ChunkT& GetChunk(T* ptr) { return *m_chunkElems[Ptr2ChunkIdx(ptr)].m_chunk; }
175  ChunkT& GetChunk(KyUInt32 idx) { return *m_chunkElems[idx].m_chunk; }
176  ChunkT& GetChunk(KyUInt32 idx) const { return *m_chunkElems[idx].m_chunk; }
177 
178 private:
179  KyArrayDH_POD<ChunkElemT> m_chunkElems;
180  KyUInt32 m_first; // first non full chunk, if KyUInt32MAXVAL, then
181  KyUInt32 m_chunkByteSize;
182  KyUInt32 m_nbSlotsByChunk;
183  KyUInt32 m_count;
184  PoolChunkSize::Mode m_chunkSizeMode;
185  MemoryHeap* m_heap;
186  KyInt32 m_memStat;
187 };
188 
189 } // namespace Kaim
190 
192 
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
#define KY_CLASS_WITHOUT_COPY(ClassName)
Define to forbid copy constructor and copy assignment.
Definition: types.h:196
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
std::uint16_t KyUInt16
uint16_t
Definition: types.h:28
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
Vec2f operator*(KyFloat32 s, const Vec2f &v)
scalar * vec operator
Definition: vec2f.h:120
#define KyUInt16MAXVAL
KyUInt16 max value
Definition: types.h:67
std::int32_t KyInt32
int32_t
Definition: types.h:24
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68