11 #ifndef __PARALLEL_HASH_MAP__ 12 #define __PARALLEL_HASH_MAP__ 32 template <
class K,
class V>
35 node(K k_in, V v_in) : next(NULL), key(k_in), value(v_in) {}
52 void insert(K key, V value);
75 template <
class K,
class V>
79 struct paddedPointer {
100 paddedPointer *_announce;
113 void update(K& key, V value);
114 void insert(K key, V value);
137 template <
class K,
class V>
141 if ((M & (M-1)) != 0) {
144 for (
size_t i = 1; i < 8 *
sizeof(size_t); i*=2)
152 _buckets =
new node*[_M]();
160 template <
class K,
class V>
163 for (
size_t i=0; i<_M; i++) {
164 node *iter_node = _buckets[i];
165 while (iter_node != NULL) {
166 node *next_node = iter_node->next;
168 iter_node = next_node;
184 template <
class K,
class V>
188 size_t key_hash = std::hash<K>()(key) & (_M-1);
191 node *iter_node = _buckets[key_hash];
192 while (iter_node != NULL) {
193 if (iter_node->key == key)
196 iter_node = iter_node->next;
211 template <
class K,
class V>
215 size_t key_hash = std::hash<K>()(key) & (_M-1);
218 node *iter_node = _buckets[key_hash];
219 while (iter_node != NULL) {
220 if (iter_node->key == key)
221 return iter_node->value;
223 iter_node = iter_node->next;
240 template <
class K,
class V>
244 size_t key_hash = std::hash<K>()(key) & (_M-1);
251 node *new_node =
new node(key, value);
254 node **iter_node = &_buckets[key_hash];
255 while (*iter_node != NULL)
256 iter_node = &(*iter_node)->next;
259 *iter_node = new_node;
278 template <
class K,
class V>
282 size_t key_hash = std::hash<K>()(key) & (_M-1);
289 node *new_node =
new node(key, value);
292 node **iter_node = &_buckets[key_hash];
293 while (*iter_node != NULL)
294 iter_node = &(*iter_node)->next;
297 *iter_node = new_node;
301 #pragma omp atomic capture 312 template <
class K,
class V>
322 template <
class K,
class V>
337 template <
class K,
class V>
341 K *key_list =
new K[_N];
345 for (
size_t i=0; i<_M; i++) {
346 node *iter_node = _buckets[i];
347 while (iter_node != NULL) {
348 key_list[ind] = iter_node->key;
349 iter_node = iter_node->next;
366 template <
class K,
class V>
370 V *values =
new V[_N];
374 for (
size_t i=0; i<_M; i++) {
375 node *iter_node = _buckets[i];
376 while (iter_node != NULL) {
377 values[ind] = iter_node->value;
378 iter_node = iter_node->next;
389 template <
class K,
class V>
393 for (
size_t i=0; i<_M; i++) {
394 node *iter_node = _buckets[i];
395 while (iter_node != NULL) {
396 node *next_node = iter_node->next;
398 iter_node = next_node;
403 for (
size_t i=0; i<_M; i++)
418 template <
class K,
class V>
421 for (
size_t i=0; i<_M; i++) {
422 if (_buckets[i] == NULL)
434 template <
class K,
class V>
443 _num_threads = omp_get_max_threads();
445 _locks =
new omp_lock_t[_num_locks];
446 for (
size_t i=0; i<_num_locks; i++)
447 omp_init_lock(&_locks[i]);
449 _announce =
new paddedPointer[_num_threads];
450 for (
size_t t=0; t<_num_threads; t++)
451 _announce[t].value = NULL;
459 template <
class K,
class V>
479 template <
class K,
class V>
484 tid = omp_get_thread_num();
491 _announce[tid].value = table_ptr;
493 }
while (table_ptr != _table);
496 bool present = table_ptr->
contains(key);
499 _announce[tid].value = NULL;
517 template <
class K,
class V>
522 return _table->at(key);
526 tid = omp_get_thread_num();
532 _announce[tid].value = table_ptr;
534 }
while (table_ptr != _table);
537 V value = table_ptr->
at(key);
540 _announce[tid].value = NULL;
556 template <
class K,
class V>
559 if (2*_table->size() > _table->bucket_count())
567 size_t lock_hash = (std::hash<K>()(key) & (_table->bucket_count() - 1))
571 omp_set_lock(&_locks[lock_hash]);
574 _table->insert(key, value);
577 omp_unset_lock(&_locks[lock_hash]);
590 template <
class K,
class V>
594 size_t lock_hash = (std::hash<K>()(key) & (_table->bucket_count() - 1))
598 omp_set_lock(&_locks[lock_hash]);
601 _table->at(key) = value;
604 omp_unset_lock(&_locks[lock_hash]);
621 template <
class K,
class V>
625 if (2*_table->size() > _table->bucket_count())
633 size_t lock_hash = (std::hash<K>()(key) & (_table->bucket_count() - 1))
637 omp_set_lock(&_locks[lock_hash]);
640 long N =_table->insert_and_get_count(key, value);
643 omp_unset_lock(&_locks[lock_hash]);
661 template <
class K,
class V>
669 for (
size_t i=0; i<_num_locks; i++)
670 omp_set_lock(&_locks[i]);
673 if (2*_table->size() < _table->bucket_count()) {
675 for (
size_t i=0; i<_num_locks; i++)
676 omp_unset_lock(&_locks[i]);
686 K *key_list = _table->
keys();
687 V *value_list = _table->values();
690 for (
size_t i=0; i<_table->size(); i++)
691 new_map->
insert(key_list[i], value_list[i]);
701 for (
size_t i=0; i<_num_locks; i++)
702 omp_unset_lock(&_locks[i]);
706 delete [] value_list;
709 for (
size_t i=0; i<_num_threads; i++) {
710 while (_announce[i].value == old_table) {
725 template <
class K,
class V>
727 return _table->size();
735 template <
class K,
class V>
737 return _table->bucket_count();
745 template <
class K,
class V>
761 template <
class K,
class V>
766 tid = omp_get_thread_num();
772 _announce[tid].value = table_ptr;
774 }
while (table_ptr != _table);
777 K* key_list = table_ptr->
keys();
780 _announce[tid].value = NULL;
796 template <
class K,
class V>
801 tid = omp_get_thread_num();
807 _announce[tid].value = table_ptr;
809 }
while (table_ptr != _table);
812 V* value_list = table_ptr->
values();
815 _announce[tid].value = NULL;
824 template <
class K,
class V>
833 template <
class K,
class V>
837 for (
size_t i=0; i<_num_locks; i++)
838 omp_set_lock(&_locks[i]);
844 for (
size_t i=0; i<_num_locks; i++)
845 omp_unset_lock(&_locks[i]);
857 template <
class K,
class V>
862 tid = omp_get_thread_num();
868 _announce[tid].value = table_ptr;
870 }
while (table_ptr != _table);
876 _announce[tid].value = NULL;
883 template <
class K,
class V>
size_t bucket_count()
Returns the number of buckets in the fixed-size table.
Definition: ParallelHashMap.h:323
void insert(K key, V value)
Insert a given key/value pair into the parallel hash map.
Definition: ParallelHashMap.h:557
void insert(K key, V value)
Inserts a key/value pair into the fixed-size table.
Definition: ParallelHashMap.h:241
K * keys()
Returns an array of the keys in the fixed-size table.
Definition: ParallelHashMap.h:338
bool contains(K &key)
Determine whether the parallel hash map contains a given key.
Definition: ParallelHashMap.h:480
ParallelHashMap(size_t M=64, size_t L=64)
Constructor generates initial underlying table as a fixed-sized hash map and initializes concurrency ...
Definition: ParallelHashMap.h:435
FixedHashMap(size_t M=64)
Constructor initializes fixed-size table of buckets filled with empty linked lists.
Definition: ParallelHashMap.h:138
A fixed-size hash map supporting insertion and lookup operations.
Definition: ParallelHashMap.h:33
long insert_and_get_count(K key, V value)
Insert a given key/value pair into the parallel hash map and return the order number.
Definition: ParallelHashMap.h:622
V at(K &key)
Determine the value associated with a given key.
Definition: ParallelHashMap.h:518
V * values()
Returns an array of the values in the underlying table.
Definition: ParallelHashMap.h:797
size_t num_locks()
Returns the number of locks in the parallel hash map.
Definition: ParallelHashMap.h:746
void clear()
Clears all key/value pairs form the hash table.
Definition: ParallelHashMap.h:390
K * keys()
Returns an array of the keys in the underlying table.
Definition: ParallelHashMap.h:762
virtual ~ParallelHashMap()
Destructor frees memory associated with fixed-sized hash map and concurrency structures.
Definition: ParallelHashMap.h:460
long insert_and_get_count(K key, V value)
Inserts a key/value pair into the fixed-size table and returns the order number with which it was ins...
Definition: ParallelHashMap.h:279
void update(K &key, V value)
Updates the value associated with a key in the parallel hash map.
Definition: ParallelHashMap.h:591
void setFixedSize()
Prevents the parallel hash map from further resizing.
Definition: ParallelHashMap.h:825
virtual ~FixedHashMap()
Destructor deletes all nodes in the linked lists associated with each bucket in the fixed-size table ...
Definition: ParallelHashMap.h:161
V * values()
Returns an array of the values in the fixed-size table.
Definition: ParallelHashMap.h:367
size_t bucket_count()
Returns the number of buckets in the underlying table.
Definition: ParallelHashMap.h:736
bool contains(K &key)
Determine whether the fixed-size table contains a given key.
Definition: ParallelHashMap.h:185
void log_printf(logLevel level, const char *format,...)
Print a formatted message to the console.
Definition: log.cpp:300
void realloc(size_t M)
Reallocates the underlying table to the desired size.
Definition: ParallelHashMap.h:884
V & at(K &key)
Determine the value associated with a given key in the fixed-size table.
Definition: ParallelHashMap.h:212
void print_buckets()
Prints the contents of each bucket to the screen.
Definition: ParallelHashMap.h:419
size_t size()
Returns the number of key/value pairs in the underlying table.
Definition: ParallelHashMap.h:726
void print_buckets()
Prints the contents of each bucket to the screen.
Definition: ParallelHashMap.h:858
size_t size()
Returns the number of key/value pairs in the fixed-size table.
Definition: ParallelHashMap.h:313
Utility functions for writing log messages to the screen.
A thread-safe hash map supporting insertion and lookup operations.
Definition: ParallelHashMap.h:76
void clear()
Clears all key/value pairs form the hash table.
Definition: ParallelHashMap.h:834