DCL 4.0
Loading...
Searching...
No Matches
__HashMapT-GCC.h
Go to the documentation of this file.
1#ifndef __DCL_HASH_MAP_T_H__
2#error "Never include <dcl/__HashMapT-GCC.h> directly; use <dcl/HashMapT.h> instead."
3#endif
4
5__DCL_BEGIN_NAMESPACE
6
7#if __DCL_HAVE_THIS_FILE__
8 static const char_t __szHashMap_h__[] = __T("dcl/__HashMapT-GCC.h");
9 #undef __THIS_FILE__
10 #define __THIS_FILE__ __szHashMap_h__
11#endif
12
13template<typename KEY, typename VALUE, typename HASH_FUN = HashFun<KEY> >
14class HashMap : public Object
15{
17public:
18 struct Assoc
19 {
20 KEY key;
21 VALUE value;
22
23 Assoc() {}
24 Assoc(const KEY& _key, const VALUE& _value)
25 {
26 this->key = _key;
27 this->value = _value;
28 }
29 };
30
31 struct HashNode : public Assoc
32 {
33 HashNode* pNext;
34 };
35
36 class ConstIterator;
37 class Iterator
38 {
39 public:
40 Iterator(HashNode* _pNode, HashMap* _pMap);
41 Iterator& operator=(const Iterator& _it);
42 Iterator& operator++();
43 Iterator operator++(int);
44 bool operator==(const Iterator& _it) const;
45 bool operator!=(const Iterator& _it) const;
46 Assoc& operator*() const;
47 protected:
48 HashMap* __pMap;
49 HashNode* __pNode;
50 friend class ConstIterator;
51 };
52
53 class ConstIterator
54 {
55 public:
56 ConstIterator(const HashNode* _pNode, const HashMap* _pMap);
57 ConstIterator(const ConstIterator& _it);
58 ConstIterator(const Iterator& _it);
59 ConstIterator& operator=(const ConstIterator& _it);
60 ConstIterator& operator++();
61 ConstIterator operator++(int);
62 bool operator==(const ConstIterator& _it) const;
63 bool operator!=(const ConstIterator& _it) const;
64 const Assoc& operator*() const;
65 protected:
66 const HashMap* __pMap;
67 const HashNode* __pNode;
68 };
69
70public:
71 virtual ~HashMap();
72 void initBuckets(size_t _bucketSize);
73 HashMap(size_t _bucketSize = 21);
74
75 HashMap(const HashMap& _src);
76 const HashMap& operator=(const HashMap& _src);
77
78 ConstIterator begin() const;
79 ConstIterator end() const;
80 Iterator begin();
81 Iterator end();
82
83 size_t bucketSize() const;
84 size_t size() const;
85 size_t sizeOfBucket(size_t _index) const;
86 bool isEmpty() const;
87 Iterator find(const KEY& _key);
88 ConstIterator find(const KEY& _key) const;
89 bool lookup(const KEY& _key, VALUE& _rValue) const;
90 VALUE& operator[](const KEY& _key);
91 size_t erase(const KEY& _key);
92 void clear();
93
94protected:
95 size_t bucketIndex(const KEY& _key) const;
96 HashNode* createNode(const KEY& _key);
97 void destroyNode(HashNode* _pNode);
98
99protected:
100 HASH_FUN __hashFun;
101 size_t __size; // count of all elements
102 PointerArray __buckets;
103
104 friend class Iterator;
105 friend class ConstIterator;
106};
107
109
110template<typename KEY, typename VALUE, typename HASH_FUN>
111inline
114 HashNode* _pNode,
116 )
117{
118 __pNode = _pNode;
119 __pMap = _pMap;
120}
121
122template<typename KEY, typename VALUE, typename HASH_FUN>
123inline
124typename HashMap<KEY, VALUE, HASH_FUN>::Iterator&
126::Iterator::operator = (const Iterator& _it)
127{
128 __pNode = _it.__pNode;
129 __pMap = _it.__pMap;
130 return *this;
131}
132
133template<typename KEY, typename VALUE, typename HASH_FUN>
134inline
135bool
137::Iterator::operator == (const Iterator& _it) const
138{
139 return __pNode == _it.__pNode;
140}
141
142template<typename KEY, typename VALUE, typename HASH_FUN>
143inline
144bool
146::Iterator::operator != (const Iterator& _it) const
147{
148 return __pNode != _it.__pNode;
149}
150
151template<typename KEY, typename VALUE, typename HASH_FUN>
152inline
154HashMap<KEY, VALUE, HASH_FUN>::Iterator::operator*()const
155{
156 return *__pNode;
157}
158
160
161template<typename KEY, typename VALUE, typename HASH_FUN>
162inline
165 const HashNode* _pNode,
167 )
168{
169 __pNode = _pNode;
170 __pMap = _pMap;
171}
172
173template<typename KEY, typename VALUE, typename HASH_FUN>
174inline
176::ConstIterator::ConstIterator(const ConstIterator& _it)
177{
178 __pNode = _it.__pNode;
179 __pMap = _it.__pMap;
180}
181
182template<typename KEY, typename VALUE, typename HASH_FUN>
183inline
185::ConstIterator::ConstIterator(const Iterator& _it)
186{
187 __pNode = _it.__pNode;
188 __pMap = _it.__pMap;
189}
190
191template<typename KEY, typename VALUE, typename HASH_FUN>
192inline
195::ConstIterator::operator=(const ConstIterator& _it)
196{
197 __pNode = _it.__pNode;
198 __pMap = _it.__pMap;
199 return *this;
200}
201
202template<typename KEY, typename VALUE, typename HASH_FUN>
203inline
204bool
206::ConstIterator::operator == (const ConstIterator& _it) const
207{
208 return __pNode == _it.__pNode;
209}
210
211template<typename KEY, typename VALUE, typename HASH_FUN>
212inline
213bool
215::ConstIterator::operator != (const ConstIterator& _it) const
216{
217 return __pNode != _it.__pNode;
218}
219
220template<typename KEY, typename VALUE, typename HASH_FUN>
221inline
225{
226 return *__pNode;
227}
228
230
231template<typename KEY, typename VALUE, typename HASH_FUN>
232inline
235{
236 return Iterator(NULL, this);
237}
238
239template<typename KEY, typename VALUE, typename HASH_FUN>
240inline
241typename HashMap<KEY, VALUE, HASH_FUN>::ConstIterator
243{
244 return ConstIterator(NULL, this);
245}
246
247template<typename KEY, typename VALUE, typename HASH_FUN>
248inline
249size_t
251{
252 return __buckets.size();
253}
254
255template<typename KEY, typename VALUE, typename HASH_FUN>
256inline
257size_t
259{
260 return __size;
261}
262
263template<typename KEY, typename VALUE, typename HASH_FUN>
264inline
265bool
267{
268 return __size == 0;
269}
270
272
273template<typename KEY, typename VALUE, typename HASH_FUN>
274typename HashMap<KEY, VALUE, HASH_FUN>::Iterator&
275HashMap<KEY, VALUE, HASH_FUN>::Iterator::operator++()
276{
277 __DCL_ASSERT(__pNode != NULL);
278 __DCL_ASSERT(__pMap != NULL);
279
280 const HashNode* pOldNode = __pNode;
281 __pNode = __pNode->pNext;
282 if (__pNode == NULL)
283 {
284 size_t index = __pMap->bucketIndex(pOldNode->key);
285 while((__pNode == NULL) && (++index < __pMap->__buckets.size()))
286 __pNode = (HashNode*)__pMap->__buckets[index];
287 }
288 return *this;
289}
290
291template<typename KEY, typename VALUE, typename HASH_FUN>
294{
295 Iterator itTemp = *this;
296 ++(*this);
297 return itTemp;
298}
299
301
302// IMPLEMENT_CLASSINFO(HashMap<KEY, VALUE, HASH_FUN>, Object)
303#ifdef __DCL_NO_RTTI
304template<typename KEY, typename VALUE, typename HASH_FUN>
305const Object::ClassInfo HashMap<KEY, VALUE, HASH_FUN>::m_classInfo =
306{
307 __DCL_NAMESPACE_STRING __S(HashMap),
308 sizeof(class HashMap),
309 &Object::m_classInfo
310};
311
312template<typename KEY, typename VALUE, typename HASH_FUN>
313const Object::ClassInfo* HashMap<KEY, VALUE, HASH_FUN>::classInfo() const
314{
315 return CLASSINFO(class_name);
316}
317#else
318template<typename KEY, typename VALUE, typename HASH_FUN>
319const std::type_info& HashMap<KEY, VALUE, HASH_FUN>::typeInfo() const
320{
321 return typeid(HashMap);
322}
323#endif
324
325template<typename KEY, typename VALUE, typename HASH_FUN>
328{
329 __DCL_ASSERT(__pNode != NULL);
330 __DCL_ASSERT(__pMap != NULL);
331
332 const HashNode* pOldNode = __pNode;
333 __pNode = __pNode->pNext;
334 if (__pNode == NULL)
335 {
336 size_t index = __pMap->bucketIndex(pOldNode->key);
337 while((__pNode == NULL) && (++index < __pMap->__buckets.size()))
338 __pNode = (HashNode*)__pMap->__buckets[index];
339 }
340 return *this;
341}
342
343template<typename KEY, typename VALUE, typename HASH_FUN>
346{
347 ConstIterator itTemp = *this;
348 ++(*this);
349 return itTemp;
350}
351
353
354template<typename KEY, typename VALUE, typename HASH_FUN>
359
360template<typename KEY, typename VALUE, typename HASH_FUN>
361HashMap<KEY, VALUE, HASH_FUN>::HashMap(size_t _bucketSize /* = 10 */)
362 : __buckets(DCLGetNextPrimNumber(_bucketSize))
363{
364 __size = 0;
365// __buckets.resize(DCLGetNextPrimNumber(_bucketSize));
366}
367
368template<typename KEY, typename VALUE, typename HASH_FUN>
370{
371 clear();
372 __buckets.resize(DCLGetNextPrimNumber(_bucketSize));
373}
374
375template<typename KEY, typename VALUE, typename HASH_FUN>
380
381template<typename KEY, typename VALUE, typename HASH_FUN>
384{
385 if (&_src != this)
386 {
387 clear();
388 __size = _src.__size;
389 __buckets.resize(_src.__buckets.size());
390
391 for(size_t index = 0; index < _src.__buckets.size(); index++)
392 {
393 const HashNode* pNode = (HashNode*) _src.__buckets[index];
394 if (pNode != NULL)
395 {
396 HashNode* pNewNode = createNode(pNode->key);
397 pNewNode->value = pNode->value;
398 __buckets[index] = pNewNode;
399 for(pNode = pNode->pNext; pNode != NULL; pNode = pNode->pNext)
400 {
401 pNewNode->pNext = createNode(pNode->key);
402 pNewNode = pNewNode->pNext;
403 pNewNode->value = pNode->value;
404 }
405 }
406 }
407 }
408 return *this;
409}
410
411template<typename KEY, typename VALUE, typename HASH_FUN>
412typename HashMap<KEY, VALUE, HASH_FUN>::ConstIterator
414{
415 for(size_t i = 0; i < __buckets.size(); i++)
416 {
417 if (__buckets[i] != NULL)
418 return ConstIterator((HashNode*)__buckets[i], this);
419 }
420 return ConstIterator(NULL, this);
421}
422
423template<typename KEY, typename VALUE, typename HASH_FUN>
424typename HashMap<KEY, VALUE, HASH_FUN>::Iterator
426{
427 for(size_t i = 0; i < __buckets.size(); i++)
428 {
429 if (__buckets[i] != NULL)
430 return Iterator((HashNode*)__buckets[i], this);
431 }
432 return Iterator(NULL, this);
433}
434
435template<typename KEY, typename VALUE, typename HASH_FUN>
436size_t
438{
439 __DCL_ASSERT(_index < __buckets.size());
440
441 size_t nCount = 0;
442 HashNode* pNode = (HashNode*)__buckets[_index];
443 for(; pNode != NULL; pNode = pNode->pNext)
444 nCount++;
445 return nCount;
446}
447
448template<typename KEY, typename VALUE, typename HASH_FUN>
449typename HashMap<KEY, VALUE, HASH_FUN>::Iterator
451{
452 size_t index = bucketIndex(_key);
453 HashNode* pNode = (HashNode*)__buckets[index];
454 while (pNode) {
455 if (pNode->key == _key) {
456 break;
457 }
458 pNode = pNode->pNext;
459 }
460 return Iterator(pNode, this);
461}
462
463template<typename KEY, typename VALUE, typename HASH_FUN>
464typename HashMap<KEY, VALUE, HASH_FUN>::ConstIterator
466{
467 size_t index = bucketIndex(_key);
468 const HashNode* pNode = (HashNode*)__buckets[index];
469 while (pNode) {
470 if (pNode->key == _key) {
471 break;
472 }
473 pNode = pNode->pNext;
474 }
475 return ConstIterator(pNode, this);
476}
477
478template<typename KEY, typename VALUE, typename HASH_FUN>
479bool
480HashMap<KEY, VALUE, HASH_FUN>::lookup(const KEY& _key, VALUE& _rValue) const
481{
482 size_t index = bucketIndex(_key);
483 HashNode* pNode = (HashNode*)__buckets[index];
484 while(pNode != NULL) {
485 if (pNode->key == _key) {
486 _rValue = pNode->value;
487 return true;
488 }
489 pNode = pNode->pNext;
490 }
491 return false;
492}
493
494template<typename KEY, typename VALUE, typename HASH_FUN>
495VALUE&
497{
498 size_t index = bucketIndex(_key);
499 HashNode* pFirstNode = (HashNode*)__buckets[index];
500 for(HashNode* pCurrentNode = pFirstNode; pCurrentNode!= NULL;
501 pCurrentNode = pCurrentNode->pNext)
502 {
503 if (pCurrentNode->key == _key)
504 return pCurrentNode->value;
505 }
506
507 HashNode* pNewNode = createNode(_key);
508 pNewNode->pNext = pFirstNode;
509 __buckets[index] = pNewNode;
510 __size++;
511 return pNewNode->value;
512}
513
514template<typename KEY, typename VALUE, typename HASH_FUN>
515inline
516size_t
518{
519 return __hashFun.hashKey(_key) % __buckets.size();
520}
521
522template<typename KEY, typename VALUE, typename HASH_FUN>
523typename HashMap<KEY, VALUE, HASH_FUN>::HashNode*
525{
526 HashNode* pNode = (HashNode*) malloc(sizeof(HashNode));
527 // FIXME!
528 // if (pNode == NULL)
529 // throw new BadAllocException(sizeof(HashNode), __THIS_FILE__, __LINE__);
530 __DCL_ASSERT(pNode != NULL);
531
532 memset((void*) pNode, 0, sizeof(HashNode));
533
534#if __DCL_HAVE_ALLOC_DEBUG
535#undef new
536#endif
537
538 new(&(pNode->key)) KEY;
539 new(&(pNode->value)) VALUE;
540
541#if __DCL_HAVE_ALLOC_DEBUG
542#define new __DCL_DEBUG_NEW
543#endif
544
545 pNode->key = _key;
546 return pNode;
547}
548
549template<typename KEY, typename VALUE, typename HASH_FUN>
550void
552{
553 _pNode->key.~KEY();
554 _pNode->value.~VALUE();
555 free(_pNode);
556}
557
558template<typename KEY, typename VALUE, typename HASH_FUN>
559size_t
561{
562 size_t nErased = 0;
563 size_t index = bucketIndex(_key);
564 HashNode* pCurrentNode = (HashNode*)__buckets[index];
565 if (pCurrentNode != NULL)
566 {
567 if (pCurrentNode->key == _key) // first
568 {
569 __buckets[index] = pCurrentNode->pNext;
570 destroyNode(pCurrentNode);
571 nErased++;
572 __size--;
573 }
574 else
575 {
576 HashNode* pNextNode = pCurrentNode->pNext;
577 while(pNextNode != NULL)
578 {
579 if (pNextNode->key == _key)
580 {
581 pCurrentNode->pNext = pNextNode->pNext;
582 destroyNode(pNextNode);
583 nErased++;
584 __size--;
585 break;
586 }
587 else
588 {
589 pCurrentNode = pNextNode;
590 pNextNode = pCurrentNode->pNext;
591 }
592 }
593 }
594 }
595 return nErased;
596}
597
598template<typename KEY, typename VALUE, typename HASH_FUN>
599void
601{
602 for(size_t i = 0; i < __buckets.size(); i++)
603 {
604 HashNode* pNode = (HashNode*)__buckets[i];
605 while(pNode)
606 {
607 HashNode* pNext = pNode->pNext;
608 destroyNode(pNode);
609 pNode = pNext;
610 }
611 __buckets[i] = NULL;
612 }
613 __size = 0;
614}
615
616#if __DCL_HAVE_THIS_FILE__
617 #undef __THIS_FILE__
618 #define __THIS_FILE__ __T(__FILE__)
619#endif
620
621__DCL_END_NAMESPACE
DCLCAPI bool operator!=(const STRING_T &_str1, const STRING_T &_str2)
Definition __STRING.h:424
DCLCAPI bool operator==(const STRING_T &_str1, const STRING_T &_str2)
Definition __STRING.h:397
#define NULL
Definition Config.h:340
wchar_t char_t
Definition Config.h:275
DCLCAPI size_t DCLGetNextPrimNumber(size_t _n)
Definition HashFun.cpp:23
#define DECLARE_CLASSINFO(class_name)
Definition Object.h:210
#define CLASSINFO(class_name)
Definition Object.h:209
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define __T(str)
Definition Object.h:44
void CharsetConvertException *__fields clear()
virtual ~HashMap()
void clear()
ConstIterator begin() const
ConstIterator end() const
HashNode * createNode(const KEY &_key)
const HashMap & operator=(const HashMap &_src)
size_t sizeOfBucket(size_t _index) const
friend class ConstIterator
bool lookup(const KEY &_key, VALUE &_rValue) const
HashMap(size_t _bucketSize=21)
VALUE & operator[](const KEY &_key)
ConstIterator find(const KEY &_key) const
void initBuckets(size_t _bucketSize)
bool isEmpty() const
size_t size() const
friend class Iterator
Iterator begin()
size_t erase(const KEY &_key)
void destroyNode(HashNode *_pNode)
Iterator find(const KEY &_key)
HashMap(const HashMap &_src)
size_t bucketSize() const
Iterator end()
size_t bucketIndex(const KEY &_key) const
Object()
Definition Object.cpp:183
virtual const std::type_info & typeInfo() const
Definition Object.cpp:126
Definition AssocT.h:12
KEY key
Definition AssocT.h:13
VALUE value
Definition AssocT.h:14