OROCHI
 
Loading...
Searching...
No Matches
GxMap.h
Go to the documentation of this file.
1//===========================================================================
9//===========================================================================
10#pragma once
11
12GX_CORE_NAMESPACE_BEGIN()
13
14//===========================================================================
16//===========================================================================
17template<class K, class V>
18class GxMap
19{
20 //-----------------------------------------------------------
22 //-----------------------------------------------------------
24public:
26 static constexpr u32 DEFAULT_SPLIT_COUNT = 32;
27
28 class GxPair;
29
31 //-----------------------------------------------------------
33 //-----------------------------------------------------------
35public:
37 GxMap(void) : _splitCount(DEFAULT_SPLIT_COUNT), _invalidKey(0), _invalidValue(0)
38 {
39 initialize();
40 }
42 GxMap(K invalidKey, V invalidValue) : _splitCount(DEFAULT_SPLIT_COUNT), _invalidKey(invalidKey), _invalidValue(invalidValue)
43 {
44 initialize();
45 }
47 GxMap(K invalidKey, V invalidValue, u32 splitCount) : _splitCount(splitCount), _invalidKey(invalidKey), _invalidValue(invalidValue)
48 {
49 initialize();
50 }
52 ~GxMap(void);// override;
53private:
55 void initialize(void);
56
58 //-----------------------------------------------------------
60 //-----------------------------------------------------------
62public:
64 V find(K key) const;
66 K findKey(V pObject) const;
68 void insert(K key, V pObject);
70 void setObject(K key, V pObject);
72 void erase(K key);
74 void eraseObject(const V pObject);
76 void eraseAll(void);
77
78private:
80 GX_FORCE_INLINE u32 getHashValue(K key) const { return key % _splitCount; }
82 GxPair* findPair(K key) const;
84 GxPair* allocatePair(K key, V pObject);
86 void freePair(GxPair* pPair);
87
89 //-----------------------------------------------------------
91 //-----------------------------------------------------------
93public:
95 GX_FORCE_INLINE V operator[](K key) const { return find(key); }
97 u32 getCount(void) const;
99 constexpr u32 getSplitCount(void) const { return _splitCount; }
101 GX_FORCE_INLINE const GxArray& getPairArray(void) const { return _pairArray; }
103 GX_FORCE_INLINE b32 isInvalidKey(K key) const { return _invalidKey == key; }
105 GX_FORCE_INLINE b32 isInvalidValue(V value) const { return _invalidValue == value; }
106
108 //-----------------------------------------------------------
110 //-----------------------------------------------------------
112private:
113 GxArrayClassBase _hashArray;
114 GxArray _pairArray;
115 GxArray _pairFreeArray;
116 GxArray _pairBufferArray;
117 u32 _splitCount;
118 K _invalidKey;
119 V _invalidValue;
120
122};
123
124//===========================================================================
126//===========================================================================
127template<class K, class V>
128class GxMap<K, V>::GxPair
129{
130 //-------------------------------------------------------------
132 //-------------------------------------------------------------
134public:
136 GxPair(void) : _key(0), _pObject(0) {}
137
139 //-------------------------------------------------------------
141 //-------------------------------------------------------------
143
145 GX_FORCE_INLINE void set(K key, V pObject) { _key = key; _pObject = pObject; }
147 GX_FORCE_INLINE K getKey(void) const { return _key; }
149 GX_FORCE_INLINE V getObject(void) const { return _pObject; }
150
152 //-------------------------------------------------------------
154 //-------------------------------------------------------------
156private:
157 K _key;
158 V _pObject;
159
161};
162
163//---------------------------------------------------------------------------
164// 初期化
165//---------------------------------------------------------------------------
166template<class K, class V>
168{
169 const u32 INITIAL_PAIR_COUNT = 256;
170 auto* pBuffer = GX_NEW GxPair[INITIAL_PAIR_COUNT];
171 _pairBufferArray.addBottom(pBuffer);
172 for (u32 i = 0; i < INITIAL_PAIR_COUNT; i++)
173 {
174 _pairFreeArray.addBottom(&pBuffer[i]);
175 }
176
177 _hashArray.setCount(_splitCount);
178 auto* pArray = GX_NEW GxArray[_splitCount];
179 for (u32 i = 0; i < _splitCount; i++)
180 {
181 _hashArray[i] = &pArray[i];
182 }
183}
184
185//---------------------------------------------------------------------------
186// デストラクタ
187//---------------------------------------------------------------------------
188template<class K, class V>
190{
191 auto* pArray = static_cast<GxArray*>(_hashArray[0]);
192 GX_SAFE_DELETE_ARRAY(pArray);
193 for (u32 i = 0; i < _pairBufferArray.getCount(); i++)
194 {
195 auto* pBuffer = static_cast<GxPair*>(_pairBufferArray[i]);
196 GX_SAFE_DELETE_ARRAY(pBuffer);
197 }
198}
199
200//---------------------------------------------------------------------------
201// 検索
204//---------------------------------------------------------------------------
205template<class K, class V>
206V GxMap<K, V>::find(K key) const
207{
208 auto* pPair = findPair(key);
209 if (pPair)
210 {
211 return pPair->getObject();
212 }
213 return _invalidValue;
214}
215
216//---------------------------------------------------------------------------
217// キーを検索
220//---------------------------------------------------------------------------
221template<class K, class V>
222K GxMap<K, V>::findKey(V pObject) const
223{
224 for (auto* pPair : _pairArray)
225 {
226 if (static_cast<GxPair*>(pPair)->getObject() == pObject)
227 {
228 return static_cast<GxPair*>(pPair)->getKey();
229 }
230 }
231 return _invalidKey;
232}
233
234//---------------------------------------------------------------------------
235// 挿入
238//---------------------------------------------------------------------------
239template<class K, class V>
240void GxMap<K, V>::insert(K key, V pObject)
241{
242 const auto keyValue = getHashValue(key);
243 auto* pPair = allocatePair(key, pObject);
244 static_cast<GxArray*>(_hashArray[keyValue])->addBottom(pPair);
245}
246
247//---------------------------------------------------------------------------
248// オブジェクトを設定
251//---------------------------------------------------------------------------
252template<class K, class V>
253void GxMap<K, V>::setObject(K key, V pObject)
254{
255 auto* pPair = findPair(key);
256 if (pPair)
257 {
258 pPair->set(pPair->getKey(), pObject);
259 }
260}
261
262//---------------------------------------------------------------------------
263// 削除
265//---------------------------------------------------------------------------
266template<class K, class V>
268{
269 const auto keyValue = getHashValue(key);
270 auto* pArray = static_cast<GxArray*>(_hashArray[keyValue]);
271 for (u32 i = 0; i < pArray->getCount(); i++)
272 {
273 auto* pPair = static_cast<GxPair*>(pArray->getObject(i));
274 if (pPair->getKey() == key)
275 {
276 freePair(pPair);
277 pArray->remove(i);
278 break;
279 }
280 }
281}
282
283//---------------------------------------------------------------------------
284// 削除
286//---------------------------------------------------------------------------
287template<class K, class V>
288void GxMap<K, V>::eraseObject(const V pObject)
289{
290 for (u32 i = 0; i < _hashArray.getCount(); i++)
291 {
292 auto* pArray = static_cast<GxArray*>(_hashArray[i]);
293 for (u32 j = 0; j < pArray->getCount(); j++)
294 {
295 auto* pPair = static_cast<GxPair*>(pArray->getObject(j));
296 if (pPair->getObject() == pObject)
297 {
298 pArray->remove(j);
299 }
300 }
301 }
302}
303
304//---------------------------------------------------------------------------
305// 全削除
306//---------------------------------------------------------------------------
307template<class K, class V>
309{
310 for (u32 i = 0; i < _hashArray.getCount(); i++)
311 {
312 auto* pArray = static_cast<GxArray*>(_hashArray[i]);
313 for (u32 j = 0; j < pArray->getCount(); j++)
314 {
315 auto* pPair = static_cast<GxPair*>(pArray->getObject(j));
316 freePair(pPair);
317 }
318 pArray->removeAll();
319 }
320}
321
322//---------------------------------------------------------------------------
323// ペアを確保
327//---------------------------------------------------------------------------
328template<class K, class V>
329typename GxMap<K, V>::GxPair* GxMap<K, V>::allocatePair(K key, V pObject)
330{
331 if (_pairFreeArray.getCount() == 0)
332 {
333 // メモリ追加
334 u32 size = _pairArray.getCount() * 2;
335 auto* pBuffer = GX_NEW GxPair[size];
336 _pairBufferArray.addBottom(pBuffer);
337 for (u32 i = 0; i < size; i++)
338 {
339 _pairFreeArray.addBottom(&pBuffer[i]);
340 }
341 }
342 auto* pPair = static_cast<GxPair*>(_pairFreeArray.pop());
343 pPair->set(key, pObject);
344 _pairArray.addBottom(pPair);
345 return pPair;
346}
347
348//---------------------------------------------------------------------------
349// ペアを解放
351//---------------------------------------------------------------------------
352template<class K, class V>
353void GxMap<K, V>::freePair(GxPair* pPair)
354{
355 GX_ASSERT(pPair, "pPair is nullptr");
356 GX_ASSERT(_pairArray.indexOf(pPair) >= 0, "pPair is invalid");
357
358 _pairArray.removeFirst(pPair);
359 _pairFreeArray.addBottom(pPair);
360}
361
362//---------------------------------------------------------------------------
363// 要素数を取得
365//---------------------------------------------------------------------------
366template<class K, class V>
368{
369 u32 count = 0;
370 for (u32 i = 0; i < _hashArray.getCount(); i++)
371 {
372 count += static_cast<GxArray*>(_hashArray[i])->getCount();
373 }
374 return count;
375}
376
377//---------------------------------------------------------------------------
378// 検索
381//---------------------------------------------------------------------------
382template<class K, class V>
383typename GxMap<K, V>::GxPair* GxMap<K, V>::findPair(K key) const
384{
385 const auto keyValue = getHashValue(key);
386 auto* pArray = static_cast<GxArray*>(_hashArray[keyValue]);
387 for (u32 j = 0; j < pArray->getCount(); j++)
388 {
389 auto* pPair = static_cast<GxPair*>(pArray->getObject(j));
390 if(pPair->getKey() == key)
391 {
392 return pPair;
393 }
394 }
395 return nullptr;
396}
397
398GX_CORE_NAMESPACE_END()
配列クラス
Definition GxArrayClassBase.h:18
配列クラス
Definition GxArray.h:18
GX_FORCE_INLINE void removeAll(void)
全削除
Definition GxArray.h:97
ペア情報
Definition GxMap.h:129
GX_FORCE_INLINE V getObject(void) const
オブジェクトを取得
Definition GxMap.h:149
GX_FORCE_INLINE void set(K key, V pObject)
設定
Definition GxMap.h:145
GxPair(void)
デフォルトコンストラクタ
Definition GxMap.h:136
GX_FORCE_INLINE K getKey(void) const
キーを取得
Definition GxMap.h:147
連想配列クラス
Definition GxMap.h:19
void setObject(K key, V pObject)
オブジェクトを設定
Definition GxMap.h:253
GX_FORCE_INLINE b32 isInvalidKey(K key) const
無効なキーか判定
Definition GxMap.h:103
GX_FORCE_INLINE b32 isInvalidValue(V value) const
無効な値か判定
Definition GxMap.h:105
u32 getCount(void) const
要素数を取得
Definition GxMap.h:367
GxMap(K invalidKey, V invalidValue, u32 splitCount)
コンストラクタ
Definition GxMap.h:47
K findKey(V pObject) const
キーを検索
Definition GxMap.h:222
GX_FORCE_INLINE const GxArray & getPairArray(void) const
ペア配列を取得
Definition GxMap.h:101
GxMap(K invalidKey, V invalidValue)
コンストラクタ
Definition GxMap.h:42
constexpr u32 getSplitCount(void) const
分割数を取得
Definition GxMap.h:99
void eraseAll(void)
全削除
Definition GxMap.h:308
GX_FORCE_INLINE V operator[](K key) const
配列演算子
Definition GxMap.h:95
~GxMap(void)
デストラクタ
Definition GxMap.h:189
void insert(K key, V pObject)
挿入
Definition GxMap.h:240
void erase(K key)
削除
Definition GxMap.h:267
void eraseObject(const V pObject)
削除
Definition GxMap.h:288
V find(K key) const
検索
Definition GxMap.h:206
GxMap(void)
デフォルトコンストラクタ
Definition GxMap.h:37
32bitブーリアン
Definition GxDefine.h:173