* \see xbt_dict_free()
*
* Creates and initialize a new dictionary with a default hashtable size.
+ * The dictionary is heterogeneous: each element can have a different free
+ * function.
*/
xbt_dict_t xbt_dict_new(void)
+{
+ xbt_dict_t dict = xbt_dict_new_homogeneous(NULL);
+ dict->homogeneous = 0;
+
+ return dict;
+}
+
+/**
+ * \brief Constructor
+ * \param free_ctn function to call with (\a data as argument) when
+ * \a data is removed from the dictionary
+ * \return pointer to the destination
+ * \see xbt_dict_new(), xbt_dict_free()
+ *
+ * Creates and initialize a new dictionary with a default hashtable size.
+ * The dictionary is homogeneous: each element share the same free function.
+ */
+xbt_dict_t xbt_dict_new_homogeneous(void_f_pvoid_t free_ctn)
{
xbt_dict_t dict;
dict = xbt_new(s_xbt_dict_t, 1);
+ dict->free_f = free_ctn;
dict->table_size = 127;
dict->table = xbt_new0(xbt_dictelm_t, dict->table_size + 1);
dict->count = 0;
dict->fill = 0;
+ dict->homogeneous = 1;
return dict;
}
while (current != NULL) {
previous = current;
current = current->next;
- xbt_dictelm_free(previous);
+ xbt_dictelm_free(*dict, previous);
(*dict)->count--;
}
}
if (current == NULL) {
/* this key doesn't exist yet */
- current = xbt_dictelm_new(key, key_len, hash_code, data, free_ctn);
+ current = xbt_dictelm_new(dict, key, key_len, hash_code, data, free_ctn);
dict->count++;
if (previous == NULL) {
dict->table[hash_code & dict->table_size] = current;
previous->next = current;
}
} else {
-
XBT_DEBUG("Replace %.*s by %.*s under key %.*s",
key_len, (char *) current->content,
key_len, (char *) data, key_len, (char *) key);
/* there is already an element with the same key: overwrite it */
- if (current->content != NULL && current->free_f != NULL) {
- current->free_f(current->content);
- }
- current->content = data;
- current->free_f = free_ctn;
+ xbt_dictelm_set_data(dict, current, data, free_ctn);
}
}
if (!dict->table[hash_code & dict->table_size])
dict->fill--;
- xbt_dictelm_free(current);
+ xbt_dictelm_free(dict, current);
dict->count--;
}
XBT_INLINE void xbt_dicti_set(xbt_dict_t dict,
uintptr_t key, uintptr_t data)
{
-
- unsigned int hash_code =
- xbt_dict_hash_ext((void *) &key, sizeof(uintptr_t));
-
- xbt_dictelm_t current, previous = NULL;
- xbt_assert(dict);
-
- XBT_DEBUG("ADD %zu->%zu; hash = %d, size = %d, & = %d", key, data,
- hash_code, dict->table_size, hash_code & dict->table_size);
- current = dict->table[hash_code & dict->table_size];
- while (current != NULL &&
- (hash_code != current->hash_code
- || sizeof(uintptr_t) != current->key_len
- || (((uintptr_t) key) != ((uintptr_t) current->key)))) {
- previous = current;
- current = current->next;
- }
-
- if (current == NULL) {
- /* this key doesn't exist yet */
- current = xbt_dictielm_new(key, hash_code, data);
- dict->count++;
- if (previous == NULL) {
- dict->table[hash_code & dict->table_size] = current;
- dict->fill++;
- if ((dict->fill * 100) / (dict->table_size + 1) > MAX_FILL_PERCENT)
- xbt_dict_rehash(dict);
- } else {
- previous->next = current;
- }
- } else {
-
- /* there is already an element with the same key: overwrite it */
- if (current->content != NULL && current->free_f != NULL) {
- current->free_f(current->content);
- }
- current->content = (void *) data;
- current->free_f = NULL;
- }
+ xbt_dict_set_ext(dict, (void *)&key, sizeof key, (void*)data, NULL);
}
/**
*/
XBT_INLINE uintptr_t xbt_dicti_get(xbt_dict_t dict, uintptr_t key)
{
-
- unsigned int hash_code =
- xbt_dict_hash_ext(((void *) &key), sizeof(uintptr_t));
- xbt_dictelm_t current;
-
- xbt_assert(dict);
-
- current = dict->table[hash_code & dict->table_size];
- while (current != NULL &&
- (hash_code != current->hash_code
- || sizeof(uintptr_t) != current->key_len
- || (((uintptr_t) key) != ((uintptr_t) current->key)))) {
- current = current->next;
- }
-
- if (current == NULL)
- return 0;
-
- return (uintptr_t) (current->content);
+ return (uintptr_t)xbt_dict_get_or_null_ext(dict, (void *)&key, sizeof key);
}
/** Remove a uintptr_t key from the dict */
XBT_INLINE void xbt_dicti_remove(xbt_dict_t dict, uintptr_t key)
{
-
- unsigned int hash_code =
- xbt_dict_hash_ext(((void *) &key), sizeof(uintptr_t));
- xbt_dictelm_t current, previous = NULL;
-
-
- current = dict->table[hash_code & dict->table_size];
- while (current != NULL &&
- (hash_code != current->hash_code
- || sizeof(uintptr_t) != current->key_len
- || (((uintptr_t) key) != ((uintptr_t) current->key)))) {
- previous = current; /* save the previous node */
- current = current->next;
- }
-
- if (current == NULL)
- THROWF(not_found_error, 0, "key %zu not found", key);
-
- if (previous != NULL) {
- previous->next = current->next;
- } else {
- dict->table[hash_code & dict->table_size] = current->next;
- }
-
- if (!dict->table[hash_code & dict->table_size])
- dict->fill--;
-
- xbt_dictelm_free(current);
- dict->count--;
+ xbt_dict_remove_ext(dict, (void *)&key, sizeof key);
}
while (current != NULL) {
previous = current;
current = current->next;
- xbt_dictelm_free(previous);
+ xbt_dictelm_free(dict, previous);
}
dict->table[i] = NULL;
}
if (dict_elm_mallocator != NULL) {
/* Already created. I guess we want to switch to MC mode, so kill the previously created mallocator */
xbt_mallocator_free(dict_elm_mallocator);
+ xbt_mallocator_free(dict_het_elm_mallocator);
}
dict_elm_mallocator = xbt_mallocator_new(256,
dict_elm_mallocator_new_f,
dict_elm_mallocator_free_f,
dict_elm_mallocator_reset_f);
+ dict_het_elm_mallocator = xbt_mallocator_new(256,
+ dict_het_elm_mallocator_new_f,
+ dict_het_elm_mallocator_free_f,
+ dict_het_elm_mallocator_reset_f);
}
/**
if (dict_elm_mallocator != NULL) {
xbt_mallocator_free(dict_elm_mallocator);
dict_elm_mallocator = NULL;
+ xbt_mallocator_free(dict_het_elm_mallocator);
+ dict_het_elm_mallocator = NULL;
}
if (all_sizes) {
unsigned int count;