summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/hash.c')
-rw-r--r--libs/libcurl/src/hash.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c
index dc0fb62e1e..ca55a4bb04 100644
--- a/libs/libcurl/src/hash.c
+++ b/libs/libcurl/src/hash.c
@@ -40,7 +40,10 @@ hash_element_dtor(void *user, void *element)
struct Curl_hash_element *e = (struct Curl_hash_element *) element;
if(e->ptr) {
- h->dtor(e->ptr);
+ if(e->dtor)
+ e->dtor(e->key, e->key_len, e->ptr);
+ else
+ h->dtor(e->ptr);
e->ptr = NULL;
}
@@ -77,7 +80,8 @@ Curl_hash_init(struct Curl_hash *h,
}
static struct Curl_hash_element *
-mk_hash_element(const void *key, size_t key_len, const void *p)
+mk_hash_element(const void *key, size_t key_len, const void *p,
+ Curl_hash_elem_dtor dtor)
{
/* allocate the struct plus memory after it to store the key */
struct Curl_hash_element *he = malloc(sizeof(struct Curl_hash_element) +
@@ -87,22 +91,15 @@ mk_hash_element(const void *key, size_t key_len, const void *p)
memcpy(he->key, key, key_len);
he->key_len = key_len;
he->ptr = (void *) p;
+ he->dtor = dtor;
}
return he;
}
#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
-/* Insert the data in the hash. If there already was a match in the hash, that
- * data is replaced. This function also "lazily" allocates the table if
- * needed, as it isn't done in the _init function (anymore).
- *
- * @unittest: 1305
- * @unittest: 1602
- * @unittest: 1603
- */
-void *
-Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
+void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p,
+ Curl_hash_elem_dtor dtor)
{
struct Curl_hash_element *he;
struct Curl_llist_element *le;
@@ -130,7 +127,7 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
}
}
- he = mk_hash_element(key, key_len, p);
+ he = mk_hash_element(key, key_len, p, dtor);
if(he) {
Curl_llist_append(l, he, &he->list);
++h->size;
@@ -140,6 +137,20 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
return NULL; /* failure */
}
+/* Insert the data in the hash. If there already was a match in the hash, that
+ * data is replaced. This function also "lazily" allocates the table if
+ * needed, as it is not done in the _init function (anymore).
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void *
+Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
+{
+ return Curl_hash_add2(h, key, key_len, p, NULL);
+}
+
/* Remove the identified hash entry.
* Returns non-zero on failure.
*
@@ -259,8 +270,9 @@ size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num)
size_t h = 5381;
while(key_str < end) {
+ size_t j = (size_t)*key_str++;
h += h << 5;
- h ^= *key_str++;
+ h ^= j;
}
return (h % slots_num);