diff options
| author | Michael Bebenita <[email protected]> | 2010-07-28 00:06:04 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-07-28 20:30:29 -0700 |
| commit | 436efdcb4f31e780590110492554a64e16596cb8 (patch) | |
| tree | 8b273143cead535242d036cb96c35766d7ebfc49 /src | |
| parent | Let circular buffers actually grow to max sz, reset _next when resizing. (diff) | |
| download | rust-436efdcb4f31e780590110492554a64e16596cb8.tar.xz rust-436efdcb4f31e780590110492554a64e16596cb8.zip | |
Add C++ wrapper around uthash.
Diffstat (limited to 'src')
| -rw-r--r-- | src/rt/util/hash_map.h | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/rt/util/hash_map.h b/src/rt/util/hash_map.h new file mode 100644 index 00000000..08d30837 --- /dev/null +++ b/src/rt/util/hash_map.h @@ -0,0 +1,193 @@ +/** + * A C++ wrapper around uthash. + */ + +#ifndef HASH_MAP +#define HASH_MAP + +#include <assert.h> +#include "../uthash/uthash.h" + +template<typename K, typename V> class hash_map { + struct map_entry { + K key; + V value; + UT_hash_handle hh; + }; + map_entry * _head; +public: + hash_map(); + ~hash_map(); + + /** + * Associates a value with the specified key in this hash map. + * If a mapping already exists the old value is replaced. + * + * returns: + * true if the mapping was successfully created and false otherwise. + */ + bool put(K key, V value); + + /** + * Updates the value associated with the specified key in this hash map. + * + * returns: + * true if the value was updated, or false if the key was not found. + */ + bool set(K key, V value); + + /** + * Gets the value associated with the specified key in this hash map. + * + * returns: + * true if the value was found and updates the specified *value parameter + * with the associated value, or false otherwise. + */ + bool get(K key, V *value); + + /** + * Removes a key-value pair from this hash map. + * + * returns: + * true if a key-value pair exists and updates the specified + * *key and *value parameters, or false otherwise. + */ + bool pop(K *key, V *value); + + /** + * Checks if the specified key exists in this hash map. + * + * returns: + * true if the specified key exists in this hash map, or false otherwise. + */ + bool contains(K key); + + /** + * Removes the value associated with the specified key from this hash map. + * + * returns: + * true if the specified key exists and updates the specified *old_value + * parameter with the associated value, or false otherwise. + */ + bool remove(K key, V *old_value); + bool remove(K key); + + /** + * Returns the number of key-value pairs in this hash map. + */ + size_t count(); + + bool is_empty() { + return count() == 0; + } + + /** + * Clears all the key-value pairs in this hash map. + * + * returns: + * the number of deleted key-value pairs. + */ + size_t clear(); +}; + +template<typename K, typename V> +hash_map<K,V>::hash_map() { + _head = NULL; +} + +template<typename K, typename V> +hash_map<K,V>::~hash_map() { + clear(); +} + +template<typename K, typename V> bool +hash_map<K,V>::put(K key, V value) { + if (contains(key)) { + return set(key, value); + } + map_entry *entry = (map_entry *) malloc(sizeof(map_entry)); + entry->key = key; + entry->value = value; + HASH_ADD(hh, _head, key, sizeof(K), entry); + return true; +} + +template<typename K, typename V> bool +hash_map<K,V>::get(K key, V *value) { + map_entry *entry = NULL; + HASH_FIND(hh, _head, &key, sizeof(K), entry); + if (entry == NULL) { + return false; + } + *value = entry->value; + return true; +} + +template<typename K, typename V> bool +hash_map<K,V>::set(K key, V value) { + map_entry *entry = NULL; + HASH_FIND(hh, _head, &key, sizeof(K), entry); + if (entry == NULL) { + return false; + } + entry->value = value; + return true; +} + +template<typename K, typename V> bool +hash_map<K,V>::contains(K key) { + V value; + return get(key, &value); +} + +template<typename K, typename V> bool +hash_map<K,V>::remove(K key, V *old_value) { + map_entry *entry = NULL; + HASH_FIND(hh, _head, &key, sizeof(K), entry); + if (entry == NULL) { + return false; + } + *old_value = entry->value; + HASH_DEL(_head, entry); + free(entry); + return true; +} + +template<typename K, typename V> bool +hash_map<K,V>::pop(K *key, V *value) { + if (is_empty()) { + return false; + } + map_entry *entry = _head; + HASH_DEL(_head, entry); + *key = entry->key; + *value = entry->value; + free(entry); + return true; +} + +template<typename K, typename V> bool +hash_map<K,V>::remove(K key) { + V old_value; + return remove(key, &old_value); +} + +template<typename K, typename V> size_t +hash_map<K,V>::count() { + return HASH_CNT(hh, _head); +} + +template<typename K, typename V> size_t +hash_map<K,V>::clear() { + size_t deleted_entries = 0; + while (_head != NULL) { + map_entry *entry = _head; + HASH_DEL(_head, entry); + free(entry); + deleted_entries ++; + } + assert(count() == 0); + return deleted_entries; +} + +#endif /* HASH_MAP */ |