DCL 4.0
Loading...
Searching...
No Matches
__HASHMAP.cpp
Go to the documentation of this file.
1#ifdef __DCL_INTERNAL__
2
3#ifdef __COMPILE_StringToStringMap__
4 #define THIS_NAME __szStringToStringMap_cpp__
5 #define THIS_VALUE __T("dcl/__HASHMAP.cpp/StringToStringMap")
6 #define HASHMAP_T StringToStringMap
7 #define HASHFUN_T HashFun<String>
8 #define KEY_T String
9 #define VALUE_T String
10 #define HAVE_CONSTRUCTOR_KEY 1
11 #define HAVE_CONSTRUCTOR_VALUE 1
12#elif defined(__COMPILE_StringToPointerMap__)
13 #define THIS_NAME __szStringToPointerMap_cpp__
14 #define THIS_VALUE __T("dcl/__HASHMAP.cpp/StringToPointerMap")
15 #define HASHMAP_T StringToPointerMap
16 #define HASHFUN_T HashFun<String>
17 #define KEY_T String
18 #define VALUE_T void*
19 #define HAVE_CONSTRUCTOR_KEY 1
20 #define HAVE_CONSTRUCTOR_VALUE 0
21#elif defined(__COMPILE_IntToPointerMap__)
22 #define THIS_NAME __szIntToPointerMap_cpp__
23 #define THIS_VALUE __T("dcl/__HASHMAP.cpp/IntToPointerMap")
24 #define HASHMAP_T IntToPointerMap
25 #define HASHFUN_T HashFun<int>
26 #define KEY_T int
27 #define VALUE_T void*
28 #define HAVE_CONSTRUCTOR_KEY 0
29 #define HAVE_CONSTRUCTOR_VALUE 0
30#endif
31
32#if __DCL_HAVE_THIS_FILE__
33 static const char_t THIS_NAME[] = THIS_VALUE;
34 #undef __THIS_FILE__
35 #define __THIS_FILE__ THIS_NAME
36#endif
37
38#if __DCL_HAVE_ALLOC_DEBUG
39 #undef __DCL_ALLOC_LEVEL
40 #define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
41#endif
42
44
47{
50
51 const HashNode* pOldNode = __pNode;
52 __pNode = __pNode->pNext;
53 if (__pNode == NULL)
54 {
55 size_t index = __pMap->bucketIndex(pOldNode->key);
56 while((__pNode == NULL) && (++index < __pMap->__buckets.size()))
57 __pNode = (HashNode*)__pMap->__buckets[index];
58 }
59 return *this;
60}
61
64{
65 Iterator itTemp = *this;
66 ++(*this);
67 return itTemp;
68}
69
71
74{
77
78 const HashNode* pOldNode = __pNode;
79 __pNode = __pNode->pNext;
80 if (__pNode == NULL)
81 {
82 size_t index = __pMap->bucketIndex(pOldNode->key);
83 while((__pNode == NULL) && (++index < __pMap->__buckets.size()))
84 __pNode = (HashNode*)__pMap->__buckets[index];
85 }
86 return *this;
87}
88
91{
92 ConstIterator itTemp = *this;
93 ++(*this);
94 return itTemp;
95}
96
98
100
101String HASHMAP_T::toString() const
102{
103 StringBuilder r = __T("{");
104 for (ConstIterator it = begin(); it != end(); it++)
105 {
106 if (it != begin())
107 r += __T(", ");
108 r.format(
110 __T("{\"%ls\", \"%ls\"}"), (*it).key.data(), (*it).value.data()
112 __T("{\"%ls\", %p}"), (*it).key.data(), (*it).value
113#elif defined(__COMPILE_IntToPointerMap__)
114 __T("{%d, %p}"), (*it).key, (*it).value
115#endif
116 );
117 }
118 r += __T("}");
119 return r;
120}
121
123{
124 clear();
125}
126
127HASHMAP_T::HASHMAP_T(size_t _bucketSize)
128 : __buckets(DCLGetNextPrimNumber(_bucketSize))
129{
130 __size = 0;
131// __buckets.resize(DCLGetNextPrimNumber(_bucketSize));
132}
133
134void HASHMAP_T::initBuckets(size_t _bucketSize)
135{
136 clear();
137 __buckets.resize(DCLGetNextPrimNumber(_bucketSize));
138}
139
141{
142 *this = _src;
143}
144
145const HASHMAP_T&
147{
148 if (&_src != this)
149 {
150 clear();
151 __size = _src.__size;
152 __buckets.resize(_src.__buckets.size());
153
154 for(size_t index = 0; index < _src.__buckets.size(); index++)
155 {
156 const HashNode* pNode = (HashNode*) _src.__buckets[index];
157 if (pNode != NULL)
158 {
159 HashNode* pNewNode = createNode(pNode->key);
160 pNewNode->value = pNode->value;
161 __buckets[index] = pNewNode;
162 for(pNode = pNode->pNext; pNode != NULL; pNode = pNode->pNext)
163 {
164 pNewNode->pNext = createNode(pNode->key);
165 pNewNode = pNewNode->pNext;
166 pNewNode->value = pNode->value;
167 }
168 }
169 }
170 }
171 return *this;
172}
173
176{
177 for(size_t i = 0; i < __buckets.size(); i++)
178 {
179 if (__buckets[i] != NULL)
180 return ConstIterator((HashNode*)__buckets[i], this);
181 }
182 return ConstIterator(NULL, this);
183}
184
187{
188 for(size_t i = 0; i < __buckets.size(); i++)
189 {
190 if (__buckets[i] != NULL)
191 return Iterator((HashNode*)__buckets[i], this);
192 }
193 return Iterator(NULL, this);
194}
195
196size_t
197HASHMAP_T::sizeOfBucket(size_t _index) const
198{
199 __DCL_ASSERT(_index < __buckets.size());
200
201 size_t nCount = 0;
202 HashNode* pNode = (HashNode*)__buckets[_index];
203 for(; pNode != NULL; pNode = pNode->pNext)
204 nCount++;
205 return nCount;
206}
207
209HASHMAP_T::find(const KEY_T& _key)
210{
211 size_t index = bucketIndex(_key);
212 HashNode* pNode = (HashNode*)__buckets[index];
213 while (pNode) {
214 if (pNode->key == _key) {
215 break;
216 }
217 pNode = pNode->pNext;
218 }
219 return Iterator(pNode, this);
220}
221
223HASHMAP_T::find(const KEY_T& _key) const
224{
225 size_t index = bucketIndex(_key);
226 const HashNode* pNode = (HashNode*)__buckets[index];
227 while (pNode) {
228 if (pNode->key == _key) {
229 break;
230 }
231 pNode = pNode->pNext;
232 }
233 return ConstIterator(pNode, this);
234}
235
236bool
237HASHMAP_T::lookup(const KEY_T& _key, VALUE_T& _rValue) const
238{
239 size_t index = bucketIndex(_key);
240 HashNode* pNode = (HashNode*)__buckets[index];
241 while(pNode != NULL) {
242 if (pNode->key == _key) {
243 _rValue = pNode->value;
244 return true;
245 }
246 pNode = pNode->pNext;
247 }
248 return false;
249}
250
251VALUE_T&
252HASHMAP_T::operator[](const KEY_T& _key)
253{
254 size_t index = bucketIndex(_key);
255 HashNode* pFirstNode = (HashNode*)__buckets[index];
256 for(HashNode* pCurrentNode = pFirstNode; pCurrentNode!= NULL;
257 pCurrentNode = pCurrentNode->pNext)
258 {
259 if (pCurrentNode->key == _key)
260 return pCurrentNode->value;
261 }
262
263 HashNode* pNewNode = createNode(_key);
264 pNewNode->pNext = pFirstNode;
265 __buckets[index] = pNewNode;
266 __size++;
267 return pNewNode->value;
268}
269
270inline
271size_t
272HASHMAP_T::bucketIndex(const KEY_T& _key) const
273{
274 return __hashFun.hashKey(_key) % __buckets.size();
275}
276
278HASHMAP_T ::createNode(const KEY_T& _key)
279{
280 HashNode* pNode = (HashNode*) malloc(sizeof(HashNode));
281 // FIXME!
282 // if (pNode == NULL)
283 // throw new BadAllocException(sizeof(HashNode), __THIS_FILE__, __LINE__);
284 __DCL_ASSERT(pNode != NULL);
285
286 memset((void*) pNode, 0, sizeof(HashNode));
287
288#if __DCL_HAVE_ALLOC_DEBUG
289#undef new
290#endif
291
292#if HAVE_CONSTRUCTOR_KEY
293 new(&(pNode->key)) KEY_T;
294#endif
295#if HAVE_CONSTRUCTOR_VALUE
296 new(&(pNode->value)) VALUE_T;
297#endif
298
299#if __DCL_HAVE_ALLOC_DEBUG
300#define new __DCL_DEBUG_NEW
301#endif
302
303 pNode->key = _key;
304 return pNode;
305}
306
307void
309{
310#if HAVE_CONSTRUCTOR_KEY
311 _pNode->key.~KEY_T();
312#endif
313#if HAVE_CONSTRUCTOR_VALUE
314 _pNode->value.~VALUE_T();
315#endif
316 free(_pNode);
317}
318
319size_t
320HASHMAP_T::erase(const KEY_T& _key)
321{
322 size_t nErased = 0;
323 size_t index = bucketIndex(_key);
324 HashNode* pCurrentNode = (HashNode*)__buckets[index];
325 if (pCurrentNode != NULL)
326 {
327 if (pCurrentNode->key == _key) // first
328 {
329 __buckets[index] = pCurrentNode->pNext;
330 destroyNode(pCurrentNode);
331 nErased++;
332 __size--;
333 }
334 else
335 {
336 HashNode* pNextNode = pCurrentNode->pNext;
337 while(pNextNode != NULL)
338 {
339 if (pNextNode->key == _key)
340 {
341 pCurrentNode->pNext = pNextNode->pNext;
342 destroyNode(pNextNode);
343 nErased++;
344 __size--;
345 break;
346 }
347 else
348 {
349 pCurrentNode = pNextNode;
350 pNextNode = pCurrentNode->pNext;
351 }
352 }
353 }
354 }
355 return nErased;
356}
357
358void
360{
361 for(size_t i = 0; i < __buckets.size(); i++)
362 {
363 HashNode* pNode = (HashNode*)__buckets[i];
364 while(pNode)
365 {
366 HashNode* pNext = pNode->pNext;
367 destroyNode(pNode);
368 pNode = pNext;
369 }
370 __buckets[i] = NULL;
371 }
372 __size = 0;
373}
374
375#if __DCL_HAVE_THIS_FILE__
376 #undef __THIS_FILE__
377 #define __THIS_FILE__ __T(__FILE__)
378#endif
379
380#undef THIS_NAME
381#undef THIS_VALUE
382#undef HASHMAP_T
383#undef HASHFUN_T
384#undef KEY_T
385#undef VALUE_T
386#undef HAVE_CONSTRUCTOR_KEY
387#undef HAVE_CONSTRUCTOR_VALUE
388
389#endif // __DCL_INTERNAL_
#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 __COMPILE_StringToPointerMap__
Definition HashMap.h:25
#define __COMPILE_IntToPointerMap__
Definition HashMap.h:31
#define __COMPILE_StringToStringMap__
Definition HashMap.h:20
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
ByteString r
const HASHMAP_T * __pMap
Definition __HASHMAP.h:110
ConstIterator(const HashNode *_pNode, const HASHMAP_T *_pMap)
Definition __HASHMAP.h:201
ConstIterator & operator++()
Definition __HASHMAP.cpp:73
const HashNode * __pNode
Definition __HASHMAP.h:111
Iterator(HashNode *_pNode, HASHMAP_T *_pMap)
Definition __HASHMAP.h:155
HASHMAP_T * __pMap
Definition __HASHMAP.h:92
Iterator & operator++()
Definition __HASHMAP.cpp:46
HashNode * __pNode
Definition __HASHMAP.h:93
Iterator find(const KEY_T &_key)
const HASHMAP_T & operator=(const HASHMAP_T &_src)
size_t bucketIndex(const KEY_T &_key) const
size_t erase(const KEY_T &_key)
ConstIterator begin() const
friend class ConstIterator
Definition __HASHMAP.h:148
void initBuckets(size_t _bucketSize)
HASHMAP_T(size_t _bucketSize=21)
VALUE_T & operator[](const KEY_T &_key)
ConstIterator end() const
Definition __HASHMAP.h:271
size_t __size
Definition __HASHMAP.h:144
HASHFUN_T __hashFun
Definition __HASHMAP.h:143
friend class Iterator
Definition __HASHMAP.h:147
size_t sizeOfBucket(size_t _index) const
virtual ~HASHMAP_T()
HashNode * createNode(const KEY_T &_key)
void destroyNode(HashNode *_pNode)
void clear()
bool lookup(const KEY_T &_key, VALUE_T &_rValue) const
PointerArray __buckets
Definition __HASHMAP.h:145
virtual String toString() const
Definition Object.cpp:187
HashNode * pNext
Definition __HASHMAP.h:77