diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 132cae855..0484a4c4f 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -215,7 +215,6 @@ foreach( ert_util_clamp ert_util_chdir ert_util_filename - ert_util_hash_test ert_util_parent_path ert_util_realpath ert_util_relpath_test diff --git a/lib/include/ert/util/hash.hpp b/lib/include/ert/util/hash.hpp index 98e580823..739b13144 100644 --- a/lib/include/ert/util/hash.hpp +++ b/lib/include/ert/util/hash.hpp @@ -12,58 +12,28 @@ extern "C" { typedef struct hash_struct hash_type; typedef struct hash_iter_struct hash_iter_type; -typedef void(hash_apply_ftype)(void *); UTIL_SAFE_CAST_HEADER(hash); UTIL_SAFE_CAST_HEADER_CONST(hash); hash_type *hash_alloc(void); -void hash_iter_complete(hash_type *); void hash_free(hash_type *); -void hash_free__(void *); void hash_insert_ref(hash_type *, const char *, const void *); -void hash_insert_copy(hash_type *, const char *, const void *, copyc_ftype *, - free_ftype *); void hash_insert_string(hash_type *, const char *, const char *); bool hash_has_key(const hash_type *, const char *); -void *hash_pop(hash_type *hash, const char *key); -void *hash_safe_get(const hash_type *hash, const char *key); void *hash_get(const hash_type *, const char *); char *hash_get_string(const hash_type *, const char *); -void hash_del(hash_type *, const char *); -void hash_safe_del(hash_type *, const char *); -void hash_clear(hash_type *); int hash_get_size(const hash_type *); -void hash_set_keylist(const hash_type *, char **); char **hash_alloc_keylist(const hash_type *); stringlist_type *hash_alloc_stringlist(const hash_type *); - -char **hash_alloc_sorted_keylist(const hash_type *hash, - int(hash_get_cmp_value)(const void *)); -char **hash_alloc_key_sorted_list(const hash_type *hash, - int (*cmp)(const void *, const void *)); -bool hash_key_list_compare(const hash_type *hash1, const hash_type *hash2); void hash_insert_hash_owned_ref(hash_type *, const char *, const void *, free_ftype *); void hash_resize(hash_type *hash, int new_size); -hash_iter_type *hash_iter_alloc(const hash_type *); -void hash_iter_free(hash_iter_type *); -bool hash_iter_is_complete(const hash_iter_type *); -const char *hash_iter_get_next_key(hash_iter_type *); -void *hash_iter_get_next_value(hash_iter_type *); -void hash_iter_restart(hash_iter_type *iter); - -hash_type *hash_alloc_from_options(const stringlist_type *); -bool hash_add_option(hash_type *hash, const char *key_value); - -int hash_inc_counter(hash_type *hash, const char *counter_key); -int hash_get_counter(const hash_type *hash, const char *key); void hash_insert_int(hash_type *, const char *, int); int hash_get_int(const hash_type *, const char *); void hash_insert_double(hash_type *, const char *, double); double hash_get_double(const hash_type *, const char *); -void hash_apply(hash_type *hash, hash_apply_ftype *func); UTIL_IS_INSTANCE_HEADER(hash); diff --git a/lib/include/ert/util/hash_node.hpp b/lib/include/ert/util/hash_node.hpp index a17ae8233..c340609dc 100644 --- a/lib/include/ert/util/hash_node.hpp +++ b/lib/include/ert/util/hash_node.hpp @@ -19,13 +19,10 @@ typedef enum { bool hash_node_key_eq(const hash_node_type *, uint32_t, const char *); hash_node_type *hash_node_get_next(const hash_node_type *); -uint32_t hash_node_get_insert_nr(const hash_node_type *); void hash_node_set_next(hash_node_type *, const hash_node_type *); hash_node_type *hash_node_alloc_new(const char *, node_data_type *, hashf_type *, uint32_t); -void hash_node_set_insert_nr(hash_node_type *, uint32_t); uint32_t hash_node_get_table_index(const hash_node_type *); -uint32_t hash_node_get_global_index(const hash_node_type *); const char *hash_node_get_key(const hash_node_type *); node_data_type *hash_node_get_data(const hash_node_type *); void hash_node_free(hash_node_type *); diff --git a/lib/include/ert/util/hash_sll.hpp b/lib/include/ert/util/hash_sll.hpp index d018b6c74..d2e05f54c 100644 --- a/lib/include/ert/util/hash_sll.hpp +++ b/lib/include/ert/util/hash_sll.hpp @@ -13,7 +13,6 @@ hash_sll_type **hash_sll_alloc_table(int); void hash_sll_del_node(hash_sll_type *, hash_node_type *); void hash_sll_add_node(hash_sll_type *, hash_node_type *); void hash_sll_free(hash_sll_type *); -bool hash_sll_has_key(const hash_sll_type *, uint32_t, const char *); bool hash_sll_empty(const hash_sll_type *hash_sll); hash_node_type *hash_sll_get(const hash_sll_type *, uint32_t, const char *); hash_node_type *hash_sll_get_head(const hash_sll_type *); diff --git a/lib/util/dependencies b/lib/util/dependencies deleted file mode 100644 index 797ab904c..000000000 --- a/lib/util/dependencies +++ /dev/null @@ -1,26 +0,0 @@ -list.o : list.c list.h list_node.o -block_fs.o : block_fs.c block_fs.h hash.o util.o vector.o buffer.o -hash_node.o : hash_node.c hash_node.h util.o node_data.o -menu.o : menu.c menu.h util.o vector.o -buffer.o : buffer.c buffer.h util.o -util.o : util.c util.h util_path.c -stringlist.o : stringlist.c stringlist.h util.o vector.o buffer.o -hash.o : hash.c hash.h hash_sll.o hash_node.o node_data.o util.o stringlist.o -timer.o : timer.c timer.h util.o -arg_pack.o : arg_pack.c arg_pack.h util.o node_ctype.o -node_data.o : node_data.c node_data.h util.o node_ctype.o -matrix.o : matrix.c matrix.h util.o thread_pool.o arg_pack.o -vector.o : vector.c vector.h util.o node_data.o -msg.o : msg.c msg.h util.o -hash_sll.o : hash_sll.c hash_sll.h hash_node.o -subst.o : subst.c subst.h util.o vector.o node_data.o -matrix_blas.o : matrix_blas.c matrix_blas.h util.o matrix.o -matrix_lapack.o : matrix_lapack.c matrix_lapack.h matrix.o util.o -template.o : template.c template.h subst.o -list_node.o : list_node.c list_node.h util.o node_data.o -set.o : set.c set.h hash.o util.o -node_ctype.o : node_ctype.c node_ctype.h -path_fmt.o : path_fmt.c path_fmt.h util.o node_ctype.o -str_buffer.o : str_buffer.c str_buffer.h -thread_pool.o : thread_pool.c thread_pool.h util.o -log.o : log.c log.h util.o diff --git a/lib/util/hash.cpp b/lib/util/hash.cpp index da84c1036..363906efc 100644 --- a/lib/util/hash.cpp +++ b/lib/util/hash.cpp @@ -49,11 +49,6 @@ struct hash_struct { hashf_type *hashf; }; -typedef struct hash_sort_node { - char *key; - int cmp_value; -} hash_sort_type; - static void *__hash_get_node(const hash_type *__hash, const char *key, bool abort_on_error) { hash_type *hash = @@ -144,25 +139,6 @@ static void __hash_insert_node(hash_type *hash, hash_node_type *node) { hash_resize(hash, hash->size * 2); } -/** - This function deletes a node from the hash_table. -*/ - -static void hash_del__(hash_type *hash, const char *key) { - const uint32_t global_index = hash->hashf(key, strlen(key)); - const uint32_t table_index = (global_index % hash->size); - hash_node_type *node = - hash_sll_get(hash->table[table_index], global_index, key); - - if (node == NULL) - util_abort("%s: hash does not contain key:%s - aborting \n", __func__, - key); - else - hash_sll_del_node(hash->table[table_index], node); - - hash->elements--; -} - /** This functions takes a hash_node and finds the "next" hash node by traversing the internal hash structure. Should NOT be confused with @@ -243,39 +219,6 @@ int hash_get_int(const hash_type *hash, const char *key) { return node_data_get_int(node_data); } -/** - Small wrapper around hash_get_int() / hash_insert_int() which - implements a zero based counter. - - hash_inc_counter() - - Will increment the integer value stored in the node_data instance, - and return the updated value. If the key is not present in the hash - it will be inserted as an integer with value 0, and 0 will be - returned. -*/ - -int hash_inc_counter(hash_type *hash, const char *counter_key) { - if (hash_has_key(hash, counter_key)) { - node_data_type *node_data = hash_get_node_data(hash, counter_key); - return node_data_fetch_and_inc_int(node_data); - } else { - hash_insert_int(hash, counter_key, 0); - return 0; - } -} - -/** - Will return 0 if the key is not in the hash. -*/ - -int hash_get_counter(const hash_type *hash, const char *key) { - if (hash_has_key(hash, key)) - return hash_get_int(hash, key); - else - return 0; -} - void hash_insert_double(hash_type *hash, const char *key, double value) { node_data_type *node_data = node_data_alloc_double(value); hash_node_type *hash_node = @@ -288,30 +231,11 @@ double hash_get_double(const hash_type *hash, const char *key) { return node_data_get_double(node_data); } -void hash_del(hash_type *hash, const char *key) { hash_del__(hash, key); } - /** This function will delete the key if it exists in the hash, but it will NOT fail if the key is not already in the hash table. */ -void hash_safe_del(hash_type *hash, const char *key) { - if (__hash_get_node(hash, key, false)) - hash_del__(hash, key); -} - -void hash_clear(hash_type *hash) { - int old_size = hash_get_size(hash); - if (old_size > 0) { - char **keyList = hash_alloc_keylist__(hash); - for (int i = 0; i < old_size; i++) { - hash_del__(hash, keyList[i]); - free(keyList[i]); - } - free(keyList); - } -} - void *hash_get(const hash_type *hash, const char *key) { hash_node_type *hash_node = (hash_node_type *)__hash_get_node(hash, key, true); @@ -323,34 +247,13 @@ void *hash_get(const hash_type *hash, const char *key) { This function will return NULL if the hash does not contain 'key'. */ -void *hash_safe_get(const hash_type *hash, const char *key) { - hash_node_type *hash_node = - (hash_node_type *)__hash_get_node(hash, key, false); - if (hash_node != NULL) { - node_data_type *data_node = hash_node_get_data(hash_node); - return node_data_get_ptr(data_node); - } else - return NULL; -} - /** This function will: 1. Return an object from the hash table. 2. Remove it from the table. - - Observe that if the object has been installed with a destructor, - the object will be destroyed by the hash_del() operation, and the - return value is complete gibberish - i.e. this function can NOT be - used on hash-owned references. */ -void *hash_pop(hash_type *hash, const char *key) { - void *value = hash_get(hash, key); - hash_del(hash, key); - return value; -} - static hash_type *__hash_alloc(int size, double resize_fill, hashf_type *hashf) { hash_type *hash; @@ -380,8 +283,6 @@ void hash_free(hash_type *hash) { free(hash); } -void hash_free__(void *void_hash) { hash_free(hash_safe_cast(void_hash)); } - char **hash_alloc_keylist(const hash_type *hash) { return hash_alloc_keylist__(hash); } @@ -399,43 +300,12 @@ stringlist_type *hash_alloc_stringlist(const hash_type *hash) { return stringlist; } -/** - The standard functions for inserting an entry in the hash table: - - hash_insert_copy(): The hash table uses copyc() to make a copy of - value, which is inserted in the table. This means that the - calling scope is free to do whatever it wants with value; and - is also responsible for freeing it. The hash_table takes - responsibility for freeing it's own copy. - - hash_insert_hash_owned_ref(): The hash table takes ownership of - 'value', in the sense that the hash table will call the - 'destructor' del() on value when the node is deleted. - - hash_insert_ref(): The hash table ONLY contains a pointer to - value; the calling scope retains full ownership to - value. When the hash node is deleted, the hash implementation - will just drop the reference on the floor. -*/ +/** Inserts an entry in the hash table so that the hash table takes ownership + of 'value', in the sense that the hash table will call the + 'destructor' del() on value when the node is deleted. -void hash_insert_copy(hash_type *hash, const char *key, const void *value, - copyc_ftype *copyc, free_ftype *del) { - hash_node_type *hash_node; - if (copyc == NULL || del == NULL) - util_abort("%s: must provide copy constructer and delete operator for " - "insert copy - aborting \n", - __func__); - { - node_data_type *data_node = node_data_alloc_ptr(value, copyc, del); - hash_node = - hash_node_alloc_new(key, data_node, hash->hashf, hash->size); - __hash_insert_node(hash, hash_node); - } -} - -/** This function will insert a reference "value" with key "key"; when - the key is deleted - either by an explicit call to hash_del(), or + the key is deleted - when the complete hash table is free'd with hash_free(), the destructur 'del' is called with 'value' as argument. @@ -459,6 +329,11 @@ void hash_insert_hash_owned_ref(hash_type *hash, const char *key, } } +/** Inserts an entry in the hash table so that the hash table ONLY contains a + pointer to value; the calling scope retains full ownership to + value. When the hash node is deleted, the hash implementation + will just drop the reference on the floor. + */ void hash_insert_ref(hash_type *hash, const char *key, const void *value) { hash_node_type *hash_node; { @@ -478,274 +353,6 @@ bool hash_has_key(const hash_type *hash, const char *key) { int hash_get_size(const hash_type *hash) { return hash->elements; } -static hash_sort_type *hash_alloc_sort_list(const hash_type *hash, - const char **keylist) { - - int i; - hash_sort_type *sort_list = - (hash_sort_type *)calloc(hash_get_size(hash), sizeof *sort_list); - for (i = 0; i < hash_get_size(hash); i++) - sort_list[i].key = util_alloc_string_copy(keylist[i]); - - return sort_list; -} - -static void hash_free_sort_list(const hash_type *hash, - hash_sort_type *sort_list) { - int i; - for (i = 0; i < hash_get_size(hash); i++) - free(sort_list[i].key); - free(sort_list); -} - -static int hash_sortlist_cmp(const void *_p1, const void *_p2) { - const hash_sort_type *p1 = (const hash_sort_type *)_p1; - const hash_sort_type *p2 = (const hash_sort_type *)_p2; - - if (p1->cmp_value == p2->cmp_value) - return 0; - else if (p1->cmp_value < p2->cmp_value) - return -1; - else - return 1; -} - -static char ** -__hash_alloc_ordered_keylist(const hash_type *hash, - int(hash_get_cmp_value)(const void *)) { - int i; - char **sorted_keylist; - char **tmp_keylist = hash_alloc_keylist(hash); - hash_sort_type *sort_list = - hash_alloc_sort_list(hash, (const char **)tmp_keylist); - - for (i = 0; i < hash_get_size(hash); i++) - sort_list[i].cmp_value = - hash_get_cmp_value(hash_get(hash, sort_list[i].key)); - - qsort(sort_list, hash_get_size(hash), sizeof *sort_list, - &hash_sortlist_cmp); - sorted_keylist = - (char **)calloc(hash_get_size(hash), sizeof *sorted_keylist); - for (i = 0; i < hash_get_size(hash); i++) { - sorted_keylist[i] = util_alloc_string_copy(sort_list[i].key); - free(tmp_keylist[i]); - } - free(tmp_keylist); - hash_free_sort_list(hash, sort_list); - return sorted_keylist; -} - -char **hash_alloc_sorted_keylist(const hash_type *hash, - int(hash_get_cmp_value)(const void *)) { - char **key_list; - - key_list = __hash_alloc_ordered_keylist(hash, hash_get_cmp_value); - - return key_list; -} - -static int key_cmp(const void *_s1, const void *_s2) { - const char *s1 = *((const char **)_s1); - const char *s2 = *((const char **)_s2); - - return strcmp(s1, s2); -} - -static char **__hash_alloc_key_sorted_list(const hash_type *hash, - int (*cmp)(const void *, - const void *)) { - char **keylist = hash_alloc_keylist(hash); - - qsort(keylist, hash_get_size(hash), sizeof *keylist, cmp); - return keylist; -} - -char **hash_alloc_key_sorted_list(const hash_type *hash, - int (*cmp)(const void *, const void *)) { - char **key_list; - - key_list = __hash_alloc_key_sorted_list(hash, cmp); - - return key_list; -} - -bool hash_key_list_compare(const hash_type *hash1, const hash_type *hash2) { - bool has_equal_keylist; - int i, size1, size2; - char **keylist1, **keylist2; - - size1 = hash_get_size(hash1); - size2 = hash_get_size(hash2); - - if (size1 != size2) - return false; - - keylist1 = hash_alloc_key_sorted_list(hash1, &key_cmp); - keylist2 = hash_alloc_key_sorted_list(hash2, &key_cmp); - - has_equal_keylist = true; - for (i = 0; i < size1; i++) { - if (strcmp(keylist1[i], keylist2[i]) != 0) { - has_equal_keylist = false; - break; - } - } - - for (i = 0; i < size1; i++) { - free(keylist1[i]); - free(keylist2[i]); - } - free(keylist1); - free(keylist2); - return has_equal_keylist; -} - -/** - This function will take a list of strings of type: - - ["OPT1:Value1" , "MIN:0.0001" , "MAX:1.00" , "FILE:XX"] - - and build a hash table where the element in front of ':' is used as - key, and the element behind the ':' is used as value. The value is - internalized as a (char *) pointer with no type conversion. In the - calling scope the values should be extracted with hash_get(). - - Strings which can not be interpreted as KEY:VALUE are simply - ignored. -*/ - -hash_type *hash_alloc_from_options(const stringlist_type *options) { - int num_options = stringlist_get_size(options); - hash_type *opt_hash = hash_alloc(); - int iopt; - - for (iopt = 0; iopt < num_options; iopt++) { - char *option; - char *value; - - util_binary_split_string(stringlist_iget(options, iopt), ":", true, - &option, &value); - if ((option != NULL) && (value != NULL)) - hash_insert_hash_owned_ref(opt_hash, option, - util_alloc_string_copy(value), free); - // Warning: could not interpret string as KEY:VALUE - ignored - - free(option); - free(value); - } - - return opt_hash; -} - -bool hash_add_option(hash_type *hash, const char *key_value) { - bool addOK = false; - { - char *value; - char *key; - - util_binary_split_string(key_value, ":", true, &key, &value); - if (value != NULL) { - hash_insert_hash_owned_ref(hash, key, value, free); - addOK = true; - } - - free(key); - } - return addOK; -} - -/** - This is a **VERY** simple iteration object. - - Do **NOT** use with multi-threading. -*/ -struct hash_iter_struct { - const hash_type *hash; /* The hash we are iterating over. */ - char ** - keylist; /* The keys in the hash table - at the moment of hash_iter_alloc(). */ - int num_keys; - int current_key_num; /* This integer retains the state. */ -}; - -void hash_iter_restart(hash_iter_type *iter) { iter->current_key_num = 0; } - -hash_iter_type *hash_iter_alloc(const hash_type *hash) { - hash_iter_type *iter = (hash_iter_type *)util_malloc(sizeof *iter); - - iter->hash = hash; - iter->num_keys = hash_get_size(hash); - iter->keylist = hash_alloc_keylist((hash_type *)hash); - hash_iter_restart(iter); - return iter; -} - -void hash_iter_free(hash_iter_type *iter) { - util_free_stringlist(iter->keylist, iter->num_keys); - free(iter); -} - -bool hash_iter_is_complete(const hash_iter_type *iter) { - if (iter->current_key_num == iter->num_keys) - return true; - else - return false; -} - -/** - Get the next key. - - Returns NULL if the iteration has ended. -*/ -const char *hash_iter_get_next_key(hash_iter_type *iter) { - const char *key; - - if (iter->current_key_num == iter->num_keys) - return NULL; - - key = iter->keylist[iter->current_key_num]; - iter->current_key_num++; - - if (!hash_has_key(iter->hash, key)) - util_abort( - "%s: Programming error. Using hash_iter with multi-threading??\n", - __func__); - - return key; -} - -void *hash_iter_get_next_value(hash_iter_type *iter) { - const char *key = hash_iter_get_next_key(iter); - - if (key != NULL) - return hash_get(iter->hash, key); - else - return NULL; -} - -/** - This function will iterate through the hash table, and call the - function func on each of the elements in the table inplace: - - .... - value = hash_get( hash , key ); - func( value ); <-- The call is inplace - with no arguments, - .... and no return value. The content of 'value' - can obviously change, but 'value' itself - must still be a valid reference! -*/ - -void hash_apply(hash_type *hash, hash_apply_ftype *func) { - hash_iter_type *iter = hash_iter_alloc(hash); - while (!hash_iter_is_complete(iter)) { - const char *key = hash_iter_get_next_key(iter); - void *value = hash_get(hash, key); - - func(value); - } - hash_iter_free(iter); -} - #undef HASH_GET_SCALAR #undef HASH_INSERT_SCALAR #undef HASH_INSERT_ARRAY diff --git a/lib/util/hash_node.cpp b/lib/util/hash_node.cpp index 073c7e567..8b6996c38 100644 --- a/lib/util/hash_node.cpp +++ b/lib/util/hash_node.cpp @@ -35,10 +35,6 @@ uint32_t hash_node_get_table_index(const hash_node_type *node) { return node->table_index; } -uint32_t hash_node_get_global_index(const hash_node_type *node) { - return node->global_index; -} - const char *hash_node_get_key(const hash_node_type *node) { return node->key; } hash_node_type *hash_node_get_next(const hash_node_type *node) { diff --git a/lib/util/hash_sll.cpp b/lib/util/hash_sll.cpp index d6a4893ce..be0d67be6 100644 --- a/lib/util/hash_sll.cpp +++ b/lib/util/hash_sll.cpp @@ -98,14 +98,6 @@ hash_node_type *hash_sll_get(const hash_sll_type *hash_sll, return node; } -bool hash_sll_has_key(const hash_sll_type *hash_sll, uint32_t global_index, - const char *key) { - if (hash_sll_get(hash_sll, global_index, key)) - return true; - else - return false; -} - #ifdef __cplusplus } #endif diff --git a/lib/util/tests/ert_util_hash_test.cpp b/lib/util/tests/ert_util_hash_test.cpp deleted file mode 100644 index 8119002c2..000000000 --- a/lib/util/tests/ert_util_hash_test.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -#include -#include - -int main(int argc, char **argv) { - - hash_type *h = hash_alloc(); - - test_assert_bool_equal(hash_add_option(h, "Key"), false); - test_assert_false(hash_add_option(h, "Key")); - - test_assert_true(hash_add_option(h, "Key1:Value")); - test_assert_true(hash_add_option(h, "Key2:Value1:Value2")); - test_assert_true(hash_add_option(h, "Key3:Value1:value2:Value3")); - - test_assert_string_equal((const char *)hash_get(h, "Key1"), "Value"); - test_assert_string_equal((const char *)hash_get(h, "Key2"), - "Value1:Value2"); - test_assert_string_equal((const char *)hash_get(h, "Key3"), - "Value1:value2:Value3"); - - test_assert_false(hash_has_key(h, "Key")); - - hash_free(h); - exit(0); -}