aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Bebenita <[email protected]>2010-07-28 00:06:04 -0700
committerGraydon Hoare <[email protected]>2010-07-28 20:30:29 -0700
commit436efdcb4f31e780590110492554a64e16596cb8 (patch)
tree8b273143cead535242d036cb96c35766d7ebfc49 /src
parentLet circular buffers actually grow to max sz, reset _next when resizing. (diff)
downloadrust-436efdcb4f31e780590110492554a64e16596cb8.tar.xz
rust-436efdcb4f31e780590110492554a64e16596cb8.zip
Add C++ wrapper around uthash.
Diffstat (limited to 'src')
-rw-r--r--src/rt/util/hash_map.h193
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 */