@@ -6,6 +6,8 @@
#include <string.h>
#include <math.h>
#include <stdint.h>
+#include <stdarg.h>
+#include "talloc.h"
struct entry
{
@@ -50,7 +52,7 @@ indexFor(unsigned int tablelength, unsigned int hashvalue) {
/*****************************************************************************/
struct hashtable *
-create_hashtable(unsigned int minsize,
+create_hashtable(const void *ctx, unsigned int minsize,
unsigned int (*hashf) (void*),
int (*eqf) (void*,void*),
unsigned int flags)
@@ -66,10 +68,10 @@ create_hashtable(unsigned int minsize,
if (primes[pindex] > minsize) { size = primes[pindex]; break; }
}
- h = (struct hashtable *)calloc(1, sizeof(struct hashtable));
+ h = talloc_zero(ctx, struct hashtable);
if (NULL == h)
goto err0;
- h->table = (struct entry **)calloc(size, sizeof(struct entry *));
+ h->table = talloc_zero_array(h, struct entry *, size);
if (NULL == h->table)
goto err1;
@@ -83,7 +85,7 @@ create_hashtable(unsigned int minsize,
return h;
err1:
- free(h);
+ talloc_free(h);
err0:
return NULL;
}
@@ -115,47 +117,32 @@ hashtable_expand(struct hashtable *h)
if (h->primeindex == (prime_table_length - 1)) return 0;
newsize = primes[++(h->primeindex)];
- newtable = (struct entry **)calloc(newsize, sizeof(struct entry*));
- if (NULL != newtable)
+ newtable = talloc_realloc(h, h->table, struct entry *, newsize);
+ if (!newtable)
{
- /* This algorithm is not 'stable'. ie. it reverses the list
- * when it transfers entries between the tables */
- for (i = 0; i < h->tablelength; i++) {
- while (NULL != (e = h->table[i])) {
- h->table[i] = e->next;
- index = indexFor(newsize,e->h);
+ h->primeindex--;
+ return 0;
+ }
+
+ h->table = newtable;
+ memset(newtable + h->tablelength, 0,
+ (newsize - h->tablelength) * sizeof(*newtable));
+ for (i = 0; i < h->tablelength; i++) {
+ for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+ index = indexFor(newsize,e->h);
+ if (index == i)
+ {
+ pE = &(e->next);
+ }
+ else
+ {
+ *pE = e->next;
e->next = newtable[index];
newtable[index] = e;
}
}
- free(h->table);
- h->table = newtable;
- }
- /* Plan B: realloc instead */
- else
- {
- newtable = (struct entry **)
- realloc(h->table, newsize * sizeof(struct entry *));
- if (NULL == newtable) { (h->primeindex)--; return 0; }
- h->table = newtable;
- memset(newtable + h->tablelength, 0,
- (newsize - h->tablelength) * sizeof(*newtable));
- for (i = 0; i < h->tablelength; i++) {
- for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
- index = indexFor(newsize,e->h);
- if (index == i)
- {
- pE = &(e->next);
- }
- else
- {
- *pE = e->next;
- e->next = newtable[index];
- newtable[index] = e;
- }
- }
- }
}
+
h->tablelength = newsize;
h->loadlimit = (unsigned int)
(((uint64_t)newsize * max_load_factor) / 100);
@@ -184,7 +171,7 @@ hashtable_insert(struct hashtable *h, void *k, void *v)
* element may be ok. Next time we insert, we'll try expanding again.*/
hashtable_expand(h);
}
- e = (struct entry *)calloc(1, sizeof(struct entry));
+ e = talloc_zero(h, struct entry);
if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
e->h = hash(h,k);
index = indexFor(h->tablelength,e->h);
@@ -238,8 +225,8 @@ hashtable_remove(struct hashtable *h, void *k)
h->entrycount--;
v = e->v;
if (h->flags & HASHTABLE_FREE_KEY)
- free(e->k);
- free(e);
+ talloc_free(e->k);
+ talloc_free(e);
return v;
}
pE = &(e->next);
@@ -280,25 +267,20 @@ void
hashtable_destroy(struct hashtable *h)
{
unsigned int i;
- struct entry *e, *f;
+ struct entry *e;
struct entry **table = h->table;
for (i = 0; i < h->tablelength; i++)
{
- e = table[i];
- while (NULL != e)
+ for (e = table[i]; e; e = e->next)
{
- f = e;
- e = e->next;
if (h->flags & HASHTABLE_FREE_KEY)
- free(f->k);
+ talloc_free(e->k);
if (h->flags & HASHTABLE_FREE_VALUE)
- free(f->v);
- free(f);
+ talloc_free(e->v);
}
}
- free(h->table);
- free(h);
+ talloc_free(h);
}
/*
@@ -9,6 +9,7 @@ struct hashtable;
* create_hashtable
* @name create_hashtable
+ * @param ctx talloc context to use for allocations
* @param minsize minimum initial size of hashtable
* @param hashfunction function for hashing keys
* @param key_eq_fn function for determining key equality
@@ -22,7 +23,7 @@ struct hashtable;
#define HASHTABLE_FREE_KEY (1U << 1)
struct hashtable *
-create_hashtable(unsigned int minsize,
+create_hashtable(const void *ctx, unsigned int minsize,
unsigned int (*hashfunction) (void*),
int (*key_eq_fn) (void*,void*),
unsigned int flags
@@ -2410,11 +2410,10 @@ static int keys_equal_fn(void *key1, void *key2)
int remember_string(struct hashtable *hash, const char *str)
{
- char *k = malloc(strlen(str) + 1);
+ char *k = talloc_strdup(NULL, str);
if (!k)
return 0;
- strcpy(k, str);
return hashtable_insert(hash, k, (void *)1);
}
@@ -2509,7 +2508,7 @@ void check_store(void)
};
/* Don't free values (they are all void *1) */
- reachable = create_hashtable(16, hash_from_key_fn, keys_equal_fn,
+ reachable = create_hashtable(NULL, 16, hash_from_key_fn, keys_equal_fn,
HASHTABLE_FREE_KEY);
if (!reachable) {
log("check_store: ENOMEM");
@@ -936,7 +936,7 @@ void domain_init(int evtfd)
int rc;
/* Start with a random rather low domain count for the hashtable. */
- domhash = create_hashtable(8, domhash_fn, domeq_fn, 0);
+ domhash = create_hashtable(NULL, 8, domhash_fn, domeq_fn, 0);
if (!domhash)
barf_perror("Failed to allocate domain hashtable");
Instead of using malloc() and friends, let the hashtable implementation use the talloc framework. Signed-off-by: Juergen Gross <jgross@suse.com> --- tools/xenstore/hashtable.c | 86 ++++++++++++------------------- tools/xenstore/hashtable.h | 3 +- tools/xenstore/xenstored_core.c | 5 +- tools/xenstore/xenstored_domain.c | 2 +- 4 files changed, 39 insertions(+), 57 deletions(-)