44bef5f2cb
This is the new way to refer to tasks in rust-land. Currently all they do is serve as a key to look up the old rust_task structure. Ideally they won't be ref counted, but baby steps.
195 lines
4.3 KiB
C++
195 lines
4.3 KiB
C++
// -*- c++ -*-
|
|
/**
|
|
* 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 */
|