/*****************************************************************************/
struct hashtable *
-create_hashtable(unsigned int minsize, float maxloadfactor,
- unsigned int (*hashf) (void*),
- int (*eqf) (void*, void*))
+create_hashtable_ext(unsigned int minsize, float maxloadfactor,
+ unsigned int (*hashf) (void*),
+ int (*eqf) (void*, void*),
+ void (*freekfn) (void*),
+ void (*freevfn) (void*))
{
struct hashtable *h;
unsigned int i, size = 1u;
h->hashfn = hashf;
h->eqfn = eqf;
h->loadlimit = (unsigned int) ((float)size * maxloadfactor);
+ h->freekfn = freekfn;
+ h->freevfn = freevfn;
return h;
}
+struct hashtable *
+create_hashtable(unsigned int (*hashf) (void*),
+ int (*eqf) (void*, void*),
+ void (*freekfn) (void*),
+ void (*freevfn) (void*))
+{
+ return create_hashtable_ext(16, 0.75, hashf, eqf, freekfn, freevfn);
+}
+
/*****************************************************************************/
static unsigned int
hash(struct hashtable *h, void *k)
/* Check hash value to short circuit heavier comparison */
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
{
- free(e->v);
+ if (h->freevfn != NULL)
+ h->freevfn(e->v);
e->v = v;
return -1;
{
*pE = e->next;
h->entrycount--;
- v = e->v;
- free(e->k);
+ v = NULL;
+ if (h->freekfn != NULL)
+ h->freekfn(e->k);
+ if (h->freevfn != NULL)
+ h->freevfn(e->v);
+ else
+ v = e->v;
free(e);
return v;
/*****************************************************************************/
/* destroy */
void
-hashtable_destroy(struct hashtable *h, int free_values)
+hashtable_destroy(struct hashtable *h)
{
unsigned int i;
struct entry *e, *f;
{
f = e;
e = e->next;
- free(f->k);
-
- if (free_values)
- free(f->v);
+ if (h->freekfn != NULL)
+ h->freekfn(f->k);
+ if (h->freevfn != NULL)
+ h->freevfn(f->v);
free(f);
}
free(h);
}
-
/*****************************************************************************/
/* hashtable_iterator - iterator constructor */
* static unsigned int hash_from_key_fn( void *k );
* static int keys_equal_fn ( void *key1, void *key2 );
*
- * h = create_hashtable(16, 0.75, hash_from_key_fn, keys_equal_fn);
+ * h = create_hashtable(16, 0.75, hash_from_key_fn, keys_equal_fn, free, free);
* k = (struct some_key *) malloc(sizeof(struct some_key));
* v = (struct some_value *) malloc(sizeof(struct some_value));
*
unsigned int loadlimit;
unsigned int (*hashfn) (void *k);
int (*eqfn) (void *k1, void *k2);
+ void (*freekfn) (void *k);
+ void (*freevfn) (void *v);
};
/*****************************************************************************/
/*****************************************************************************
- * create_hashtable
+ * create_hashtable_ext
* @name create_hashtable
* @param minsize minimum initial size of hashtable
* @param maxloadfactor maximum ratio entries / tablesize
* @param hashfunction function for hashing keys
* @param key_eq_fn function for determining key equality
+ * @param key_free_fn function for freeing keys
+ * @param value_free_fn function for freeing values
* @return newly created hashtable or NULL on failure
*/
struct hashtable *
-create_hashtable(unsigned int minsize, float maxloadfactor,
- unsigned int (*hashfunction) (void*),
- int (*key_eq_fn) (void*, void*));
+create_hashtable_ext(unsigned int minsize, float maxloadfactor,
+ unsigned int (*hashfunction) (void*),
+ int (*key_eq_fn) (void*, void*),
+ void (*key_free_fn) (void*),
+ void (*value_free_fn) (void*));
+
+/* wrapper function using reasonable default values for some parameters */
+struct hashtable *
+create_hashtable(unsigned int (*hashfunction) (void*),
+ int (*key_eq_fn) (void*, void*),
+ void (*key_free_fn) (void*),
+ void (*value_free_fn) (void*));
/*****************************************************************************
* hashtable_insert
* @name hashtable_insert
* @param h the hashtable to insert into
- * @param k the key - hashtable claims ownership and will free on removal
- * @param v the value - does not claim ownership
+ * @param k the key - will be freed on removal if free function defined
+ * @param v the value - will be freed on removal if free function defined
* @return non-zero for successful insertion
*
* This function will cause the table to expand if the insertion would take
* @name hashtable_search
* @param h the hashtable to search
- * @param k the key to search for - does not claim ownership
+ * @param k the key to search for
* @return the value associated with the key, or NULL if none found
*/
* @name hashtable_remove
* @param h the hashtable to remove the item from
- * @param k the key to search for - does not claim ownership
+ * @param k the key to search for
* @return the value associated with the key, or NULL if none found
*/
* hashtable_destroy
* @name hashtable_destroy
- * @param free_values whether to call 'free' on the remaining values
*/
void
-hashtable_destroy(struct hashtable *h, int free_values);
+hashtable_destroy(struct hashtable *h);
/*****************************************************************************/
SetupFileHash *newSetupFileHash(void)
{
SetupFileHash *new_hash =
- create_hashtable(16, 0.75, get_hash_from_string, hash_key_strings_are_equal);
+ create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, free);
if (new_hash == NULL)
Fail("create_hashtable() failed -- out of memory");
if (hash == NULL)
return;
- hashtable_destroy(hash, 1); // 1 == also free values stored in hash
+ hashtable_destroy(hash);
}
char *getHashEntry(SetupFileHash *hash, char *token)
static void TestGeneratingUUIDs_RunTest(int nr, int always_seed, int num_uuids)
{
struct hashtable *hash_seeds =
- create_hashtable(16, 0.75, get_hash_from_string, hash_key_strings_are_equal);
+ create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, NULL);
struct hashtable *hash_uuids =
- create_hashtable(16, 0.75, get_hash_from_string, hash_key_strings_are_equal);
+ create_hashtable(get_hash_from_string, hash_key_strings_are_equal, free, NULL);
static char message[100];
int i;
Request(message, REQ_CONFIRM);
- hashtable_destroy(hash_seeds, 0);
- hashtable_destroy(hash_uuids, 0);
+ hashtable_destroy(hash_seeds);
+ hashtable_destroy(hash_uuids);
}
void TestGeneratingUUIDs(void)