1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
23 #ifndef _DBE_HASHMAP_H
24 #define _DBE_HASHMAP_H
28 #include "StringBuilder.h"
30 #include "MemObject.h"
32 template <typename Key_t> inline int get_hash_code (Key_t a);
33 template <typename Key_t> inline bool is_equals (Key_t a, Key_t b);
34 template <typename Key_t> inline Key_t copy_key (Key_t a);
35 template <typename Key_t> inline void delete_key (Key_t a);
37 // Specialization for char*
39 get_hash_code (char *a)
41 return (int) (crc64 (a, strlen (a)) & 0x7fffffff);
44 template<> inline bool
45 is_equals (char *a, char *b)
47 return dbe_strcmp (a, b) == 0;
50 template<> inline char *
53 return dbe_strdup (a);
56 template<> inline void
63 get_hash_code (uint64_t a)
65 return (int) (a & 0x7fffffff);
68 template<> inline bool
69 is_equals (uint64_t a, uint64_t b)
74 template<> inline uint64_t
80 template<> inline void
81 delete_key (uint64_t a)
87 get_hash_code (Histable* a)
89 return (int) (a->id & 0x7fffffff);
92 template<> inline bool
93 is_equals (Histable* a, Histable* b)
98 template<> inline Histable*
99 copy_key (Histable* a)
104 template<> inline void
105 delete_key (Histable* a)
110 template<> inline int
111 get_hash_code (MemObj* a)
113 return (int) (a->id & 0x7fffffff);
116 template<> inline bool
117 is_equals (MemObj* a, MemObj* b)
122 template<> inline MemObj*
128 template<> inline void
129 delete_key (MemObj* a)
134 template <typename Key_t, typename Value_t>
138 HashMap (int initialCapacity = 0);
147 Value_t put (Key_t key, Value_t val);
148 Value_t get (Key_t key);
149 Value_t get (Key_t key, Value_t val); // Create a new map if key is not here
151 Value_t remove (Key_t);
152 Vector<Value_t> *values (Key_t key); // Return a list of values for 'key'
155 containsKey (Key_t key)
157 Value_t p = get (key);
180 set_phaseIdx (int phase)
182 if (phase == 0) clear ();
192 MAX_HASH_SIZE = 1048575
207 return get_hash_code (key) % hash_sz;
211 equals (Key_t a, Key_t b)
213 return is_equals (a, b);
219 return copy_key (key);
223 Vector<Value_t> *vals;
229 template <typename Key_t, typename Value_t>
230 HashMap<Key_t, Value_t>
231 ::HashMap (int initialCapacity)
233 if (initialCapacity > 0)
234 vals = new Vector<Value_t>(initialCapacity);
236 vals = new Vector<Value_t>();
240 hashTable = new Hash_t*[hash_sz];
241 for (int i = 0; i < hash_sz; i++)
245 template <typename Key_t, typename Value_t>
247 HashMap<Key_t, Value_t>::clear ()
252 for (int i = 0; i < hash_sz; i++)
255 for (Hash_t *p = hashTable[i]; p; p = next)
265 template <typename Key_t, typename Value_t>
267 HashMap<Key_t, Value_t>::resize ()
269 int old_hash_sz = hash_sz;
270 hash_sz = old_hash_sz * 2 + 1;
271 Hash_t **old_hash_table = hashTable;
272 hashTable = new Hash_t*[hash_sz];
273 for (int i = 0; i < hash_sz; i++)
276 for (int i = 0; i < old_hash_sz; i++)
278 if (old_hash_table[i] != NULL)
281 Hash_t *p = old_hash_table[i];
284 put (p->key, p->val);
291 delete[] old_hash_table;
294 template <typename Key_t, typename Value_t>
296 HashMap<Key_t, Value_t>::get (Key_t key)
298 int hash_code = hashCode (key);
299 for (Hash_t *p = hashTable[hash_code]; p; p = p->next)
300 if (equals (key, p->key))
305 template <typename Key_t, typename Value_t>
307 HashMap<Key_t, Value_t>::values (Key_t key)
309 Vector<Value_t> *list = new Vector<Value_t>();
310 int hash_code = hashCode (key);
311 for (Hash_t *p = hashTable[hash_code]; p; p = p->next)
313 if (equals (key, p->key))
314 list->append (p->val);
319 template <typename Key_t, typename Value_t>
321 HashMap<Key_t, Value_t>::get (const Key_t key, Value_t val)
323 int hash_code = hashCode (key);
324 Hash_t *p, *first = NULL;
325 for (p = hashTable[hash_code]; p; p = p->next)
327 if (equals (key, p->key))
332 return first->val; // Always return the first value
341 p->next = first->next;
343 return first->val; // Always return the first value
347 p->next = hashTable[hash_code];
348 hashTable[hash_code] = p;
353 template <typename Key_t, typename Value_t>
355 HashMap<Key_t, Value_t>::remove (Key_t key)
357 int hash_code = hashCode (key);
359 for (Hash_t *prev = NULL, *p = hashTable[hash_code]; p != NULL;)
361 if (equals (key, p->key))
364 hashTable[hash_code] = p->next;
366 prev->next = p->next;
381 template <typename Key_t, typename Value_t>
383 HashMap<Key_t, Value_t>::put (Key_t key, Value_t val)
385 int hash_code = hashCode (key);
387 for (Hash_t *p = hashTable[hash_code]; p != NULL; p = p->next)
389 if (equals (key, p->key))
396 Hash_t *p = new Hash_t ();
399 p->next = hashTable[hash_code];
400 hashTable[hash_code] = p;
402 if (nelem == hash_sz)
407 template <typename Key_t, typename Value_t>
409 HashMap<Key_t, Value_t>::dump ()
413 snprintf (buf, sizeof (buf), "HashMap: size=%d ##########\n", vals->size ());
415 for (int i = 0; i < hash_sz; i++)
417 if (hashTable[i] == NULL)
419 snprintf (buf, sizeof (buf), "%3d:", i);
421 char *s = NTXT (" ");
422 for (Hash_t *p = hashTable[i]; p; p = p->next)
427 snprintf (buf, sizeof (buf), " --> 0x%p '%s'\n",
428 p->val, p->val->get_name ());
432 return sb.toString ();
435 #endif // _DBE_HASHMAP_H