From 6de7dc5879b3605a180dafa05f792f132eafdcaa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 3 Jan 2002 10:22:59 +0000 Subject: Sterling Hughes' provided initial DNS cache source code. --- lib/hash.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 lib/hash.c (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c new file mode 100644 index 000000000..c0680e488 --- /dev/null +++ b/lib/hash.c @@ -0,0 +1,271 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2001, Daniel Stenberg, , et al + * + * In order to be useful for every potential user, curl and libcurl are + * dual-licensed under the MPL and the MIT/X-derivate licenses. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the MPL or the MIT/X-derivate + * licenses. You may pick one of these licenses. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id$ + *****************************************************************************/ + +#include "setup.h" + +#include + +#include "hash.h" +#include "llist.h" + +#ifdef MALLOCDEBUG +/* this must be the last include file */ +#include "memdebug.h" +#endif + + +static unsigned long +curl_hash_str(const char *key, unsigned int key_length) +{ + register unsigned long h = 0; + register unsigned long g; + register char *p = (char *) key; + register char *end = (char *) key + key_length; + + while (p < end) { + h = (h << 4) + *p++; + if ((g = (h & 0xF0000000))) { + h = h ^ (g >> 24); + h = h ^ g; + } + } + + return h; +} + +static unsigned long +curl_hash_num(unsigned long key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += (key << 11); + key ^= (key >> 16); + + return key; +} + +static void +hash_element_dtor(void *u, void *ele) +{ + curl_hash_element *e = (curl_hash_element *) ele; + curl_hash *h = (curl_hash *) u; + + if (e->key.type == CURL_HASH_KEY_IS_STRING) { + free(e->key.value.str.val); + } + h->dtor(e->ptr); + + free(e); + e = NULL; +} + +void +curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) +{ + int i; + + h->dtor = dtor; + h->size = 0; + h->slots = slots; + + h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); + for (i = 0; i < h->slots; ++i) { + h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor); + } +} + +curl_hash * +curl_hash_alloc(int slots, curl_hash_dtor dtor) +{ + curl_hash *h; + + h = malloc(sizeof(curl_hash)); + curl_hash_init(h, slots, dtor); + + return h; +} + +#define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \ + ((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots) + +#define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \ + if (__s_key) { \ + if (__dup) { \ + (__k)->value.str.val = (char *) malloc(__s_key_len); \ + memcpy((__k)->value.str.val, __s_key, __s_key_len); \ + } else { \ + (__k)->value.str.val = __s_key; \ + } \ + (__k)->value.str.len = __s_key_len; \ + (__k)->type = CURL_HASH_KEY_IS_STRING; \ + } else { \ + (__k)->value.num = __n_key; \ + (__k)->type = CURL_HASH_KEY_IS_NUM; \ + } + +#define MIN(a, b) (a > b ? b : a) + +static int +curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2) +{ + if (key1->type == CURL_HASH_KEY_IS_NUM) { + if (key2->type == CURL_HASH_KEY_IS_STRING) + return 0; + + if (key1->value.num == key2->value.num) + return 1; + } else { + if (key2->type == CURL_HASH_KEY_IS_NUM) + return 0; + + if (memcmp(key1->value.str.val, key2->value.str.val, + MIN(key1->value.str.len, key2->value.str.len)) == 0) + return 1; + } + + return 0; +} + +int +curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len, + unsigned long num_key, const void *p) +{ + curl_hash_element *e; + curl_hash_key tmp; + curl_llist *l; + curl_llist_element *le; + int slot; + + slot = FIND_SLOT(h, str_key, str_key_len, num_key); + l = h->table[slot]; + KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); + for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { + if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { + curl_hash_element *to_update = CURL_LLIST_VALP(le); + h->dtor(to_update->ptr); + to_update->ptr = (void *) p; + return 1; + } + } + + e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); + KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1); + e->ptr = (void *) p; + + if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) { + ++h->size; + return 1; + } else { + return 0; + } +} + +int +curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, + unsigned long num_key) +{ + curl_llist *l; + curl_llist_element *le; + curl_hash_key tmp; + int slot; + + slot = FIND_SLOT(h, str_key, str_key_len, num_key); + l = h->table[slot]; + + KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); + for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { + if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { + curl_llist_remove(l, le, (void *) h); + --h->size; + return 1; + } + } + + return 0; +} + +int +curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, + unsigned long num_key, void **p) +{ + curl_llist *l; + curl_llist_element *le; + curl_hash_key tmp; + int slot; + + slot = FIND_SLOT(h, str_key, str_key_len, num_key); + l = h->table[slot]; + + KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); + for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { + if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { + *p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr; + return 1; + } + } + + return 0; +} + +void +curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)) +{ + curl_llist_element *le; + int i; + + for (i = 0; i < h->slots; ++i) { + for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) { + cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); + } + } +} + +void +curl_hash_clean(curl_hash *h) +{ + int i; + + for (i = 0; i < h->slots; ++i) { + curl_llist_destroy(h->table[i], (void *) h); + } + + free(h->table); + h->table = NULL; +} + +void +curl_hash_destroy(curl_hash *h) +{ + curl_hash_clean(h); + free(h); +} + +/* + * local variables: + * eval: (load-file "../curl-mode.el") + * end: + * vim600: fdm=marker + * vim: et sw=2 ts=2 sts=2 tw=78 + */ -- cgit v1.2.1 From 8d7f402efbcace85851c6bb8f6aa2452c15a9595 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Mon, 7 Jan 2002 20:52:32 +0000 Subject: Make cach'ing work with threads now, there are now three cases: - Use a global dns cache (via setting the tentatively named, CURLOPT_DNS_USE_GLOBAL_CACHE option to true) - Use a per-handle dns cache, by default - Use a pooled dns cache when in the "multi" interface --- lib/hash.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index c0680e488..1ed3cc21a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -255,11 +255,22 @@ curl_hash_clean(curl_hash *h) h->table = NULL; } +size_t +curl_hash_count(curl_hash *h) +{ + return h->size; +} + void curl_hash_destroy(curl_hash *h) { + if (!h) { + return; + } + curl_hash_clean(h); free(h); + h = NULL; } /* -- cgit v1.2.1 From cbaecca8e948cda6c603a715ac1e984784d77855 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 18 Jan 2002 10:30:51 +0000 Subject: added typecast for a malloc() return, and added check for NULL --- lib/hash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 1ed3cc21a..15f2029c8 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -101,7 +101,10 @@ curl_hash_alloc(int slots, curl_hash_dtor dtor) { curl_hash *h; - h = malloc(sizeof(curl_hash)); + h = (curl_hash *)malloc(sizeof(curl_hash)); + if(NULL = h) + return NULL; + curl_hash_init(h, slots, dtor); return h; -- cgit v1.2.1 From 7bfe853af3258341a0cdc2cba15156c63a84c174 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 18 Jan 2002 10:36:25 +0000 Subject: I wish I could type. Anyway, this proved it is a good habit to put the NULL on the left side of comparisons... --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 15f2029c8..b6f9d76c0 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -102,7 +102,7 @@ curl_hash_alloc(int slots, curl_hash_dtor dtor) curl_hash *h; h = (curl_hash *)malloc(sizeof(curl_hash)); - if(NULL = h) + if(NULL == h) return NULL; curl_hash_init(h, slots, dtor); -- cgit v1.2.1 From e452f467d46d06cb6eee7d314ee5d78efd4e8e9c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 17 Feb 2002 14:55:35 +0000 Subject: Philip Gladstone's 64-bit issues corrected. Reminder for the future: when we're using malloc() we MUST include as otherwise 64bit archs go bananas. Bug report #517687 --- lib/hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index b6f9d76c0..315cd731f 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2001, Daniel Stenberg, , et al + * Copyright (C) 2002, Daniel Stenberg, , et al * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. @@ -24,7 +24,7 @@ #include "setup.h" #include - +#include #include "hash.h" #include "llist.h" -- cgit v1.2.1 From 974f314f5785156af6983675aeb28313cc8ba2ea Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 19 Mar 2002 07:54:55 +0000 Subject: copyright string (year) update --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 315cd731f..e2d577c28 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2002, Daniel Stenberg, , et al + * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * * In order to be useful for every potential user, curl and libcurl are * dual-licensed under the MPL and the MIT/X-derivate licenses. -- cgit v1.2.1 From 9ebcfe9dff762ee1f294b851fd2872fab032455a Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Fri, 12 Apr 2002 23:40:19 +0000 Subject: Speed up the hash code considerably, removing a bunch of legacy crud --- lib/hash.c | 219 +++++++++++++++++++++++++++---------------------------------- 1 file changed, 98 insertions(+), 121 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index e2d577c28..13311e205 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -34,55 +34,45 @@ #endif -static unsigned long -curl_hash_str(const char *key, unsigned int key_length) +/* {{{ static unsigned long _hash_str (const char *, size_t) + */ +static unsigned long +_hash_str (const char *key, size_t key_length) { - register unsigned long h = 0; - register unsigned long g; - register char *p = (char *) key; - register char *end = (char *) key + key_length; - - while (p < end) { - h = (h << 4) + *p++; - if ((g = (h & 0xF0000000))) { - h = h ^ (g >> 24); - h = h ^ g; - } + char *end = (char *) key + key_length; + unsigned long h = 5381; + + while (key < end) { + h += h << 5; + h ^= (unsigned long) *key++; } return h; } +/* }}} */ -static unsigned long -curl_hash_num(unsigned long key) -{ - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += (key << 11); - key ^= (key >> 16); - - return key; -} - +/* {{{ static void _hash_element_dtor (void *, void *) + */ static void -hash_element_dtor(void *u, void *ele) +_hash_element_dtor (void *user, void *element) { - curl_hash_element *e = (curl_hash_element *) ele; - curl_hash *h = (curl_hash *) u; - - if (e->key.type == CURL_HASH_KEY_IS_STRING) { - free(e->key.value.str.val); + curl_hash *h = (curl_hash *) user; + curl_hash_element *e = (curl_hash_element *) element; + + if (e->key) { + free(e->key); } + h->dtor(e->ptr); free(e); - e = NULL; } +/* }}} */ +/* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor) + */ void -curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) +curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) { int i; @@ -91,115 +81,108 @@ curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) h->slots = slots; h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); - for (i = 0; i < h->slots; ++i) { - h->table[i] = curl_llist_alloc((curl_llist_dtor) hash_element_dtor); + for (i = 0; i < slots; ++i) { + h->table[i] = curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); } } +/* }}} */ +/* {{{ curl_hash *curl_hash_alloc (int, curl_hash_dtor) + */ curl_hash * -curl_hash_alloc(int slots, curl_hash_dtor dtor) +curl_hash_alloc (int slots, curl_hash_dtor dtor) { curl_hash *h; - h = (curl_hash *)malloc(sizeof(curl_hash)); - if(NULL == h) + h = (curl_hash *) malloc(sizeof(curl_hash)); + if (NULL == h) return NULL; curl_hash_init(h, slots, dtor); return h; } +/* }}} */ -#define FIND_SLOT(__h, __s_key, __s_key_len, __n_key) \ - ((__s_key ? curl_hash_str(__s_key, __s_key_len) : curl_hash_num(__n_key)) % (__h)->slots) - -#define KEY_CREATE(__k, __s_key, __s_key_len, __n_key, __dup) \ - if (__s_key) { \ - if (__dup) { \ - (__k)->value.str.val = (char *) malloc(__s_key_len); \ - memcpy((__k)->value.str.val, __s_key, __s_key_len); \ - } else { \ - (__k)->value.str.val = __s_key; \ - } \ - (__k)->value.str.len = __s_key_len; \ - (__k)->type = CURL_HASH_KEY_IS_STRING; \ - } else { \ - (__k)->value.num = __n_key; \ - (__k)->type = CURL_HASH_KEY_IS_NUM; \ - } - -#define MIN(a, b) (a > b ? b : a) - +/* {{{ static int _hash_key_compare (char *, size_t, char *, size_t) + */ static int -curl_hash_key_compare(curl_hash_key *key1, curl_hash_key *key2) +_hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) { - if (key1->type == CURL_HASH_KEY_IS_NUM) { - if (key2->type == CURL_HASH_KEY_IS_STRING) - return 0; + if (key1_len == key2_len && + *key1 == *key2 && + memcmp(key1, key2, key1_len) == 0) { + return 1; + } - if (key1->value.num == key2->value.num) - return 1; - } else { - if (key2->type == CURL_HASH_KEY_IS_NUM) - return 0; + return 0; +} +/* }}} */ - if (memcmp(key1->value.str.val, key2->value.str.val, - MIN(key1->value.str.len, key2->value.str.len)) == 0) - return 1; - } +/* {{{ static int _mk_hash_element (curl_hash_element **, char *, size_t, const void *) + */ +static int +_mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void *p) +{ + *e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); + (*e)->key = strdup(key); + (*e)->key_len = key_len; + (*e)->ptr = (void *) p; return 0; } +/* }}} */ + +#define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots) + +#define FETCH_LIST \ + curl_llist *l = h->table[find_slot(h, key, key_len)] + +/* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *) + */ int -curl_hash_add_or_update(curl_hash *h, char *str_key, unsigned int str_key_len, - unsigned long num_key, const void *p) +curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) { - curl_hash_element *e; - curl_hash_key tmp; - curl_llist *l; + curl_hash_element *he; curl_llist_element *le; - int slot; - - slot = FIND_SLOT(h, str_key, str_key_len, num_key); - l = h->table[slot]; - KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); - for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { - if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { - curl_hash_element *to_update = CURL_LLIST_VALP(le); - h->dtor(to_update->ptr); - to_update->ptr = (void *) p; + FETCH_LIST; + + for (le = CURL_LLIST_HEAD(l); + le != NULL; + le = CURL_LLIST_NEXT(le)) { + he = (curl_hash_element *) CURL_LLIST_VALP(le); + if (_hash_key_compare(he->key, he->key_len, key, key_len)) { + h->dtor(he->ptr); + he->ptr = (void *) p; return 1; } } - e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); - KEY_CREATE(&e->key, str_key, str_key_len, num_key, 1); - e->ptr = (void *) p; + if (_mk_hash_element(&he, key, key_len, p) != 0) + return 0; - if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), e)) { + if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) { ++h->size; return 1; - } else { - return 0; } + + return 0; } +/* }}} */ int -curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, - unsigned long num_key) +curl_hash_delete(curl_hash *h, char *key, size_t key_len) { - curl_llist *l; + curl_hash_element *he; curl_llist_element *le; - curl_hash_key tmp; - int slot; + FETCH_LIST; - slot = FIND_SLOT(h, str_key, str_key_len, num_key); - l = h->table[slot]; - - KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); - for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { - if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { + for (le = CURL_LLIST_HEAD(l); + le != NULL; + le = CURL_LLIST_NEXT(le)) { + he = CURL_LLIST_VALP(le); + if (_hash_key_compare(he->key, he->key_len, key, key_len)) { curl_llist_remove(l, le, (void *) h); --h->size; return 1; @@ -210,21 +193,18 @@ curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_len, } int -curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len, - unsigned long num_key, void **p) +curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) { - curl_llist *l; curl_llist_element *le; - curl_hash_key tmp; - int slot; - - slot = FIND_SLOT(h, str_key, str_key_len, num_key); - l = h->table[slot]; - - KEY_CREATE(&tmp, str_key, str_key_len, num_key, 0); - for (le = CURL_LLIST_HEAD(l); le != NULL; le = CURL_LLIST_NEXT(le)) { - if (curl_hash_key_compare(&tmp, &((curl_hash_element *) CURL_LLIST_VALP(le))->key)) { - *p = ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr; + curl_hash_element *he; + FETCH_LIST; + + for (le = CURL_LLIST_HEAD(l); + le != NULL; + le = CURL_LLIST_NEXT(le)) { + he = CURL_LLIST_VALP(le); + if (_hash_key_compare(he->key, he->key_len, key, key_len)) { + *p = he->ptr; return 1; } } @@ -255,7 +235,6 @@ curl_hash_clean(curl_hash *h) } free(h->table); - h->table = NULL; } size_t @@ -267,13 +246,11 @@ curl_hash_count(curl_hash *h) void curl_hash_destroy(curl_hash *h) { - if (!h) { + if (!h) return; - } curl_hash_clean(h); free(h); - h = NULL; } /* -- cgit v1.2.1 From bb44791bf38bf6dd0a24e50f9081f1cc1693ec67 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Sat, 13 Apr 2002 01:56:22 +0000 Subject: Add protos and change return value of curl_hash_count.... --- lib/hash.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 13311e205..dd2f00b6a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -171,6 +171,8 @@ curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) } /* }}} */ +/* {{{ int curl_hash_delete (curl_hash *, char *, size_t) + */ int curl_hash_delete(curl_hash *h, char *key, size_t key_len) { @@ -191,7 +193,10 @@ curl_hash_delete(curl_hash *h, char *key, size_t key_len) return 0; } +/* }}} */ +/* {{{ int curl_hash_find (curl_hash *, char *, size_t, void **) + */ int curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) { @@ -211,7 +216,10 @@ curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) return 0; } +/* }}} */ +/* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *)) + */ void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)) { @@ -224,7 +232,10 @@ curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element * } } } +/* }}} */ +/* {{{ void curl_hash_clean (curl_hash *) + */ void curl_hash_clean(curl_hash *h) { @@ -236,13 +247,19 @@ curl_hash_clean(curl_hash *h) free(h->table); } +/* }}} */ -size_t +/* {{{ int curl_hash_count (curl_hash *) + */ +int curl_hash_count(curl_hash *h) { return h->size; } +/* }}} */ +/* {{{ void curl_hash_destroy (curl_hash *) + */ void curl_hash_destroy(curl_hash *h) { @@ -252,6 +269,7 @@ curl_hash_destroy(curl_hash *h) curl_hash_clean(h); free(h); } +/* }}} */ /* * local variables: -- cgit v1.2.1 From a386562d9a3a351abd567a620a93e4926ce68944 Mon Sep 17 00:00:00 2001 From: Sterling Hughes Date: Wed, 17 Apr 2002 20:13:55 +0000 Subject: Prune old hostcache entries with each call... This can be optimized a tidbit, but this is a start. --- lib/hash.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index dd2f00b6a..a262b2a44 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -249,6 +249,26 @@ curl_hash_clean(curl_hash *h) } /* }}} */ +/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, int (*)(void *, void *)) + */ +void +curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)) +{ + curl_llist_element *le; + int i; + + for (i = 0; i < h->slots; ++i) { + for (le = CURL_LLIST_HEAD(h->table[i]); + le != NULL; + le = CURL_LLIST_NEXT(le)) { + if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) { + curl_llist_remove(h->table[i], le, (void *) h); + --h->size; + } + } + } +} + /* {{{ int curl_hash_count (curl_hash *) */ int -- cgit v1.2.1 From 1c427798452dc4fd68bfa888dc12383777faae33 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 27 Apr 2002 13:06:40 +0000 Subject: DNC cache prune crash removed, made the name spacing follow the general rule: "Curl_" prefix for library-wide private symbols, "curl_" is for exported symbols. --- lib/hash.c | 54 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 23 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index a262b2a44..01a4b1508 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -72,7 +72,7 @@ _hash_element_dtor (void *user, void *element) /* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor) */ void -curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) +Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) { int i; @@ -82,7 +82,7 @@ curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); for (i = 0; i < slots; ++i) { - h->table[i] = curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); + h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); } } /* }}} */ @@ -90,7 +90,7 @@ curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) /* {{{ curl_hash *curl_hash_alloc (int, curl_hash_dtor) */ curl_hash * -curl_hash_alloc (int slots, curl_hash_dtor dtor) +Curl_hash_alloc (int slots, curl_hash_dtor dtor) { curl_hash *h; @@ -98,7 +98,7 @@ curl_hash_alloc (int slots, curl_hash_dtor dtor) if (NULL == h) return NULL; - curl_hash_init(h, slots, dtor); + Curl_hash_init(h, slots, dtor); return h; } @@ -142,7 +142,7 @@ _mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void * /* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *) */ int -curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) +Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) { curl_hash_element *he; curl_llist_element *le; @@ -162,7 +162,7 @@ curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) if (_mk_hash_element(&he, key, key_len, p) != 0) return 0; - if (curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) { + if (Curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) { ++h->size; return 1; } @@ -174,7 +174,7 @@ curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) /* {{{ int curl_hash_delete (curl_hash *, char *, size_t) */ int -curl_hash_delete(curl_hash *h, char *key, size_t key_len) +Curl_hash_delete(curl_hash *h, char *key, size_t key_len) { curl_hash_element *he; curl_llist_element *le; @@ -185,7 +185,7 @@ curl_hash_delete(curl_hash *h, char *key, size_t key_len) le = CURL_LLIST_NEXT(le)) { he = CURL_LLIST_VALP(le); if (_hash_key_compare(he->key, he->key_len, key, key_len)) { - curl_llist_remove(l, le, (void *) h); + Curl_llist_remove(l, le, (void *) h); --h->size; return 1; } @@ -198,7 +198,7 @@ curl_hash_delete(curl_hash *h, char *key, size_t key_len) /* {{{ int curl_hash_find (curl_hash *, char *, size_t, void **) */ int -curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) +Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) { curl_llist_element *le; curl_hash_element *he; @@ -221,13 +221,16 @@ curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) /* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *)) */ void -curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *)) +Curl_hash_apply(curl_hash *h, void *user, + void (*cb)(void *, curl_hash_element *)) { curl_llist_element *le; int i; for (i = 0; i < h->slots; ++i) { - for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) { + for (le = CURL_LLIST_HEAD(h->table[i]); + le != NULL; + le = CURL_LLIST_NEXT(le)) { cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); } } @@ -237,42 +240,47 @@ curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element * /* {{{ void curl_hash_clean (curl_hash *) */ void -curl_hash_clean(curl_hash *h) +Curl_hash_clean(curl_hash *h) { int i; for (i = 0; i < h->slots; ++i) { - curl_llist_destroy(h->table[i], (void *) h); + Curl_llist_destroy(h->table[i], (void *) h); } free(h->table); } /* }}} */ -/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, int (*)(void *, void *)) +/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, + int (*)(void *, void *)) */ void -curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)) +Curl_hash_clean_with_criterium(curl_hash *h, void *user, + int (*comp)(void *, void *)) { curl_llist_element *le; + curl_llist_element *lnext; int i; for (i = 0; i < h->slots; ++i) { - for (le = CURL_LLIST_HEAD(h->table[i]); - le != NULL; - le = CURL_LLIST_NEXT(le)) { + le = CURL_LLIST_HEAD(h->table[i]); + while(le != NULL) if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) { - curl_llist_remove(h->table[i], le, (void *) h); + lnext = CURL_LLIST_NEXT(le); + Curl_llist_remove(h->table[i], le, (void *) h); --h->size; + le = lnext; } - } + else + le = CURL_LLIST_NEXT(le); } } /* {{{ int curl_hash_count (curl_hash *) */ int -curl_hash_count(curl_hash *h) +Curl_hash_count(curl_hash *h) { return h->size; } @@ -281,12 +289,12 @@ curl_hash_count(curl_hash *h) /* {{{ void curl_hash_destroy (curl_hash *) */ void -curl_hash_destroy(curl_hash *h) +Curl_hash_destroy(curl_hash *h) { if (!h) return; - curl_hash_clean(h); + Curl_hash_clean(h); free(h); } /* }}} */ -- cgit v1.2.1 From ba4e69bebc8f7f32f3bc7faa1e13e7580754075b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Sep 2002 11:52:59 +0000 Subject: updated source code boilerplate/header --- lib/hash.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 01a4b1508..7ccbe7958 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | @@ -7,19 +7,19 @@ * * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. * - * In order to be useful for every potential user, curl and libcurl are - * dual-licensed under the MPL and the MIT/X-derivate licenses. - * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the MPL or the MIT/X-derivate - * licenses. You may pick one of these licenses. + * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id$ - *****************************************************************************/ + ***************************************************************************/ #include "setup.h" -- cgit v1.2.1 From 2cff2518631fc538c127c1e94c47c743e2a64661 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 5 Nov 2002 10:51:41 +0000 Subject: Curl_resolv() now returns a different struct, and it contains a reference counter so that the caller needs to decrease that counter when done with the returned data. If compiled with MALLOCDEBUG I've added some extra checking that the counter is decreased before a handle is closed etc. --- lib/hash.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 7ccbe7958..56e7077d8 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -25,6 +25,7 @@ #include #include + #include "hash.h" #include "llist.h" @@ -128,7 +129,6 @@ _mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void * (*e)->key = strdup(key); (*e)->key_len = key_len; (*e)->ptr = (void *) p; - return 0; } /* }}} */ @@ -195,10 +195,10 @@ Curl_hash_delete(curl_hash *h, char *key, size_t key_len) } /* }}} */ -/* {{{ int curl_hash_find (curl_hash *, char *, size_t, void **) +/* {{{ int curl_hash_pick (curl_hash *, char *, size_t, void **) */ -int -Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) +void * +Curl_hash_pick(curl_hash *h, char *key, size_t key_len) { curl_llist_element *le; curl_hash_element *he; @@ -209,12 +209,11 @@ Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) le = CURL_LLIST_NEXT(le)) { he = CURL_LLIST_VALP(le); if (_hash_key_compare(he->key, he->key_len, key, key_len)) { - *p = he->ptr; - return 1; + return he->ptr; } } - return 0; + return NULL; } /* }}} */ @@ -222,7 +221,7 @@ Curl_hash_find(curl_hash *h, char *key, size_t key_len, void **p) */ void Curl_hash_apply(curl_hash *h, void *user, - void (*cb)(void *, curl_hash_element *)) + void (*cb)(void *user, void *ptr)) { curl_llist_element *le; int i; @@ -231,7 +230,8 @@ Curl_hash_apply(curl_hash *h, void *user, for (le = CURL_LLIST_HEAD(h->table[i]); le != NULL; le = CURL_LLIST_NEXT(le)) { - cb(user, (curl_hash_element *) CURL_LLIST_VALP(le)); + curl_hash_element *el = CURL_LLIST_VALP(le); + cb(user, el->ptr); } } } -- cgit v1.2.1 From f26a338a54e04d0a6907f5d2479d8b0fa9daf297 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 16 Jan 2003 21:08:12 +0000 Subject: copyright year update in the source header --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 56e7077d8..d1251bb86 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2002, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 409ac80710d8eea7158bef8154350163506cc263 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 29 Jan 2003 10:12:06 +0000 Subject: removed weirdo {{{ and }}} comments removed emacs local-variables stuff --- lib/hash.c | 57 ++++----------------------------------------------------- 1 file changed, 4 insertions(+), 53 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index d1251bb86..cd6d5d539 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -35,8 +35,6 @@ #endif -/* {{{ static unsigned long _hash_str (const char *, size_t) - */ static unsigned long _hash_str (const char *key, size_t key_length) { @@ -50,10 +48,7 @@ _hash_str (const char *key, size_t key_length) return h; } -/* }}} */ -/* {{{ static void _hash_element_dtor (void *, void *) - */ static void _hash_element_dtor (void *user, void *element) { @@ -68,10 +63,7 @@ _hash_element_dtor (void *user, void *element) free(e); } -/* }}} */ -/* {{{ void curl_hash_init (curl_hash *, int, curl_hash_dtor) - */ void Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) { @@ -86,10 +78,7 @@ Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); } } -/* }}} */ -/* {{{ curl_hash *curl_hash_alloc (int, curl_hash_dtor) - */ curl_hash * Curl_hash_alloc (int slots, curl_hash_dtor dtor) { @@ -103,10 +92,7 @@ Curl_hash_alloc (int slots, curl_hash_dtor dtor) return h; } -/* }}} */ -/* {{{ static int _hash_key_compare (char *, size_t, char *, size_t) - */ static int _hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) { @@ -118,12 +104,10 @@ _hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) return 0; } -/* }}} */ -/* {{{ static int _mk_hash_element (curl_hash_element **, char *, size_t, const void *) - */ static int -_mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void *p) +_mk_hash_element (curl_hash_element **e, char *key, size_t key_len, + const void *p) { *e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); (*e)->key = strdup(key); @@ -131,16 +115,12 @@ _mk_hash_element (curl_hash_element **e, char *key, size_t key_len, const void * (*e)->ptr = (void *) p; return 0; } -/* }}} */ #define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots) #define FETCH_LIST \ curl_llist *l = h->table[find_slot(h, key, key_len)] - -/* {{{ int curl_hash_add (curl_hash *, char *, size_t, const void *) - */ int Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) { @@ -169,10 +149,7 @@ Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) return 0; } -/* }}} */ -/* {{{ int curl_hash_delete (curl_hash *, char *, size_t) - */ int Curl_hash_delete(curl_hash *h, char *key, size_t key_len) { @@ -193,10 +170,7 @@ Curl_hash_delete(curl_hash *h, char *key, size_t key_len) return 0; } -/* }}} */ -/* {{{ int curl_hash_pick (curl_hash *, char *, size_t, void **) - */ void * Curl_hash_pick(curl_hash *h, char *key, size_t key_len) { @@ -215,10 +189,7 @@ Curl_hash_pick(curl_hash *h, char *key, size_t key_len) return NULL; } -/* }}} */ -/* {{{ void curl_hash_apply (curl_hash *, void *, void (*)(void *, curl_hash_element *)) - */ void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) @@ -235,10 +206,7 @@ Curl_hash_apply(curl_hash *h, void *user, } } } -/* }}} */ -/* {{{ void curl_hash_clean (curl_hash *) - */ void Curl_hash_clean(curl_hash *h) { @@ -250,11 +218,7 @@ Curl_hash_clean(curl_hash *h) free(h->table); } -/* }}} */ -/* {{{ void curl_hash_clean_with_criterium (curl_hash *, void *, - int (*)(void *, void *)) - */ void Curl_hash_clean_with_criterium(curl_hash *h, void *user, int (*comp)(void *, void *)) @@ -277,17 +241,12 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user, } } -/* {{{ int curl_hash_count (curl_hash *) - */ -int +int Curl_hash_count(curl_hash *h) { return h->size; } -/* }}} */ -/* {{{ void curl_hash_destroy (curl_hash *) - */ void Curl_hash_destroy(curl_hash *h) { @@ -297,12 +256,4 @@ Curl_hash_destroy(curl_hash *h) Curl_hash_clean(h); free(h); } -/* }}} */ - -/* - * local variables: - * eval: (load-file "../curl-mode.el") - * end: - * vim600: fdm=marker - * vim: et sw=2 ts=2 sts=2 tw=78 - */ + -- cgit v1.2.1 From 308bc9d919d57388f269c473778ea7f6a331d1c5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 26 Jun 2003 11:22:12 +0000 Subject: use CURLDEBUG instead of MALLOCDEBUG for preprocessor conditions --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index cd6d5d539..7310aba5a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -29,7 +29,7 @@ #include "hash.h" #include "llist.h" -#ifdef MALLOCDEBUG +#ifdef CURLDEBUG /* this must be the last include file */ #include "memdebug.h" #endif -- cgit v1.2.1 From 905b160097be04d44ff23092c2d161e6badcc172 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 14 Aug 2003 15:05:13 +0000 Subject: 1. check allocs 2. don't leave allocated memory behind when returning error --- lib/hash.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 7310aba5a..0d493c58a 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -64,8 +64,9 @@ _hash_element_dtor (void *user, void *element) free(e); } -void -Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) +/* return 1 on error, 0 is fine */ +int +Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) { int i; @@ -74,21 +75,35 @@ Curl_hash_init (curl_hash *h, int slots, curl_hash_dtor dtor) h->slots = slots; h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); - for (i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); + if(h->table) { + for (i = 0; i < slots; ++i) { + h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); + if(!h->table[i]) { + while(i--) + Curl_llist_destroy(h->table[i], NULL); + free(h->table); + return 1; /* failure */ + } + } + return 0; /* fine */ } + else + return 1; /* failure */ } curl_hash * -Curl_hash_alloc (int slots, curl_hash_dtor dtor) +Curl_hash_alloc(int slots, curl_hash_dtor dtor) { curl_hash *h; h = (curl_hash *) malloc(sizeof(curl_hash)); - if (NULL == h) - return NULL; - - Curl_hash_init(h, slots, dtor); + if (h) { + if(Curl_hash_init(h, slots, dtor)) { + /* failure */ + free(h); + h = NULL; + } + } return h; } -- cgit v1.2.1 From adcbe03aeb72e25c2c1509c0ad3fd1d1e620b6db Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Sep 2003 12:44:35 +0000 Subject: Uses less macros. #ifdef'ed out unused functions. Edited slightly to be more in the same style as other curl source code. The only actual code change is an added check after a malloc() call. --- lib/hash.c | 110 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 49 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 0d493c58a..1743db3c7 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -36,7 +36,7 @@ static unsigned long -_hash_str (const char *key, size_t key_length) +hash_str(const char *key, size_t key_length) { char *end = (char *) key + key_length; unsigned long h = 5381; @@ -50,7 +50,7 @@ _hash_str (const char *key, size_t key_length) } static void -_hash_element_dtor (void *user, void *element) +hash_element_dtor(void *user, void *element) { curl_hash *h = (curl_hash *) user; curl_hash_element *e = (curl_hash_element *) element; @@ -77,7 +77,7 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); if(h->table) { for (i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) _hash_element_dtor); + h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); if(!h->table[i]) { while(i--) Curl_llist_destroy(h->table[i], NULL); @@ -109,7 +109,7 @@ Curl_hash_alloc(int slots, curl_hash_dtor dtor) } static int -_hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) +hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len) { if (key1_len == key2_len && *key1 == *key2 && @@ -120,44 +120,47 @@ _hash_key_compare (char *key1, size_t key1_len, char *key2, size_t key2_len) return 0; } -static int -_mk_hash_element (curl_hash_element **e, char *key, size_t key_len, - const void *p) +static curl_hash_element * +mk_hash_element(char *key, size_t key_len, const void *p) { - *e = (curl_hash_element *) malloc(sizeof(curl_hash_element)); - (*e)->key = strdup(key); - (*e)->key_len = key_len; - (*e)->ptr = (void *) p; - return 0; + curl_hash_element *he = + (curl_hash_element *) malloc(sizeof(curl_hash_element)); + + if(he) { + he->key = strdup(key); + he->key_len = key_len; + he->ptr = (void *) p; + } + return he; } -#define find_slot(__h, __k, __k_len) (_hash_str(__k, __k_len) % (__h)->slots) +#define find_slot(__h, __k, __k_len) (hash_str(__k, __k_len) % (__h)->slots) -#define FETCH_LIST \ - curl_llist *l = h->table[find_slot(h, key, key_len)] +#define FETCH_LIST(x,y,z) x->table[find_slot(x, y, z)] int -Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) +Curl_hash_add(curl_hash *h, char *key, size_t key_len, const void *p) { curl_hash_element *he; curl_llist_element *le; - FETCH_LIST; + curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = CURL_LLIST_HEAD(l); - le != NULL; - le = CURL_LLIST_NEXT(le)) { - he = (curl_hash_element *) CURL_LLIST_VALP(le); - if (_hash_key_compare(he->key, he->key_len, key, key_len)) { + for (le = l->head; + le; + le = le->next) { + he = (curl_hash_element *) le->ptr; + if (hash_key_compare(he->key, he->key_len, key, key_len)) { h->dtor(he->ptr); he->ptr = (void *) p; return 1; } } - if (_mk_hash_element(&he, key, key_len, p) != 0) + he = mk_hash_element(key, key_len, p); + if (!he) return 0; - if (Curl_llist_insert_next(l, CURL_LLIST_TAIL(l), he)) { + if (Curl_llist_insert_next(l, l->tail, he)) { ++h->size; return 1; } @@ -165,18 +168,19 @@ Curl_hash_add (curl_hash *h, char *key, size_t key_len, const void *p) return 0; } +#if 0 int Curl_hash_delete(curl_hash *h, char *key, size_t key_len) { curl_hash_element *he; curl_llist_element *le; - FETCH_LIST; + curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = CURL_LLIST_HEAD(l); - le != NULL; - le = CURL_LLIST_NEXT(le)) { - he = CURL_LLIST_VALP(le); - if (_hash_key_compare(he->key, he->key_len, key, key_len)) { + for (le = l->head; + le; + le = le->next) { + he = le->ptr; + if (hash_key_compare(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); --h->size; return 1; @@ -185,19 +189,20 @@ Curl_hash_delete(curl_hash *h, char *key, size_t key_len) return 0; } +#endif void * Curl_hash_pick(curl_hash *h, char *key, size_t key_len) { curl_llist_element *le; curl_hash_element *he; - FETCH_LIST; + curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = CURL_LLIST_HEAD(l); - le != NULL; - le = CURL_LLIST_NEXT(le)) { - he = CURL_LLIST_VALP(le); - if (_hash_key_compare(he->key, he->key_len, key, key_len)) { + for (le = l->head; + le; + le = le->next) { + he = le->ptr; + if (hash_key_compare(he->key, he->key_len, key, key_len)) { return he->ptr; } } @@ -205,6 +210,7 @@ Curl_hash_pick(curl_hash *h, char *key, size_t key_len) return NULL; } +#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) @@ -213,14 +219,15 @@ Curl_hash_apply(curl_hash *h, void *user, int i; for (i = 0; i < h->slots; ++i) { - for (le = CURL_LLIST_HEAD(h->table[i]); - le != NULL; - le = CURL_LLIST_NEXT(le)) { - curl_hash_element *el = CURL_LLIST_VALP(le); + for (le = (h->table[i])->head; + le; + le = le->next) { + curl_hash_element *el = le->ptr; cb(user, el->ptr); } } } +#endif void Curl_hash_clean(curl_hash *h) @@ -240,27 +247,32 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user, { curl_llist_element *le; curl_llist_element *lnext; + curl_llist *list; int i; for (i = 0; i < h->slots; ++i) { - le = CURL_LLIST_HEAD(h->table[i]); - while(le != NULL) - if (comp(user, ((curl_hash_element *) CURL_LLIST_VALP(le))->ptr)) { - lnext = CURL_LLIST_NEXT(le); - Curl_llist_remove(h->table[i], le, (void *) h); - --h->size; - le = lnext; + list = h->table[i]; + le = list->head; /* get first list entry */ + while(le) { + curl_hash_element *he = le->ptr; + lnext = le->next; + /* ask the callback function if we shall remove this entry or not */ + if (comp(user, he->ptr)) { + Curl_llist_remove(list, le, (void *) h); + --h->size; /* one less entry in the hash now */ } - else - le = CURL_LLIST_NEXT(le); + le = lnext; + } } } +#if 0 int Curl_hash_count(curl_hash *h) { return h->size; } +#endif void Curl_hash_destroy(curl_hash *h) -- cgit v1.2.1 From 14597475b19a63ae2fc886a7747802f6d26cfa2f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 14 Sep 2003 21:17:54 +0000 Subject: Jeff Pohlmeyer did some marvelous debugging to track this one down. We MUST NOT free the existing hash entry when we try to add a new one that matches an existing entry. We now instead free the new one, and make the parent function use the old entry's struct instead. --- lib/hash.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 1743db3c7..89078d1f3 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -138,34 +138,33 @@ mk_hash_element(char *key, size_t key_len, const void *p) #define FETCH_LIST(x,y,z) x->table[find_slot(x, y, z)] -int -Curl_hash_add(curl_hash *h, char *key, size_t key_len, const void *p) +/* Return the data in the hash. If there already was a match in the hash, + that data is returned. */ +void * +Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) { curl_hash_element *he; curl_llist_element *le; curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = l->head; - le; - le = le->next) { + for (le = l->head; le; le = le->next) { he = (curl_hash_element *) le->ptr; if (hash_key_compare(he->key, he->key_len, key, key_len)) { - h->dtor(he->ptr); - he->ptr = (void *) p; - return 1; + h->dtor(p); /* remove the NEW entry */ + return he->ptr; /* return the EXISTING entry */ } } he = mk_hash_element(key, key_len, p); if (!he) - return 0; + return NULL; /* failure */ if (Curl_llist_insert_next(l, l->tail, he)) { ++h->size; - return 1; + return p; /* return the new entry */ } - return 0; + return NULL; /* failure */ } #if 0 -- cgit v1.2.1 From 947e6563674b5318b909189168a9640114d8f7ba Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 15 Dec 2003 15:21:13 +0000 Subject: make sure that hash_add() has no allocated resources left in case it returns NULL --- lib/hash.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 89078d1f3..786228f8b 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -156,14 +156,15 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) } he = mk_hash_element(key, key_len, p); - if (!he) - return NULL; /* failure */ - - if (Curl_llist_insert_next(l, l->tail, he)) { - ++h->size; - return p; /* return the new entry */ + if (he) { + if(Curl_llist_insert_next(l, l->tail, he)) { + ++h->size; + return p; /* return the new entry */ + } + /* couldn't insert it, destroy the 'he' element again */ + hash_element_dtor(h, he); } - + h->dtor(p); /* remove the NEW entry */ return NULL; /* failure */ } -- cgit v1.2.1 From 053f6c85efd0bf698f73343989474d672d0563a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Jan 2004 09:19:33 +0000 Subject: updated year in the copyright string --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 786228f8b..6769faacf 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2003, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 4250637e7d39ae8b663251db995d10b1612592ca Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 4 May 2004 13:40:30 +0000 Subject: improved the cleaning up of memory when we fail to resolve names due to out of memory (thanks to 'runtests.pl -t') --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 6769faacf..619f2fb1b 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -164,7 +164,7 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) /* couldn't insert it, destroy the 'he' element again */ hash_element_dtor(h, he); } - h->dtor(p); /* remove the NEW entry */ + return NULL; /* failure */ } -- cgit v1.2.1 From e64dacb40e3a32682a2481bedf83fd5f91cdde71 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 May 2004 08:57:18 +0000 Subject: better checking that strdup() works --- lib/hash.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 619f2fb1b..fcc13ed28 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -127,9 +127,17 @@ mk_hash_element(char *key, size_t key_len, const void *p) (curl_hash_element *) malloc(sizeof(curl_hash_element)); if(he) { - he->key = strdup(key); - he->key_len = key_len; - he->ptr = (void *) p; + char *dup = strdup(key); + if(dup) { + he->key = dup; + he->key_len = key_len; + he->ptr = (void *) p; + } + else { + /* failed to duplicate the key, free memory and fail */ + free(he); + he = NULL; + } } return he; } -- cgit v1.2.1 From 887d78a9ad3d6326fec2894b98d042c9d2e7fcde Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 May 2004 09:17:50 +0000 Subject: Curl_hash_add() was modified to clear up better in case of internal failure. When failing, it should not tamper at all with the data it was supposed to add to the cache. --- lib/hash.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index fcc13ed28..51634e037 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -169,8 +169,14 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) ++h->size; return p; /* return the new entry */ } - /* couldn't insert it, destroy the 'he' element again */ - hash_element_dtor(h, he); + /* + * Couldn't insert it, destroy the 'he' element and the key again. We + * don't call hash_element_dtor() since that would also call the + * "destructor" for the actual data 'p'. When we fail, we shall not touch + * that data. + */ + free(he->key); + free(he); } return NULL; /* failure */ -- cgit v1.2.1 From bbafb2eb27954c34967f91c705e74cc0c186970d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 11 May 2004 11:30:23 +0000 Subject: curl_global_init_mem() allows the memory functions to be replaced. memory.h is included everywhere for this. --- lib/hash.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 51634e037..f33d91dc8 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -28,12 +28,10 @@ #include "hash.h" #include "llist.h" +#include "memory.h" -#ifdef CURLDEBUG /* this must be the last include file */ #include "memdebug.h" -#endif - static unsigned long hash_str(const char *key, size_t key_length) -- cgit v1.2.1 From c39858aac0584716282dcb097ce9d972b43dbcb2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 24 Jun 2004 07:43:48 +0000 Subject: Source cleanups. The major one being that we now _always_ use a Curl_addrinfo linked list for name resolved data, even on hosts/systems with only IPv4 stacks as this simplifies a lot of code. --- lib/hash.c | 53 +++++++++++------------------------------------------ 1 file changed, 11 insertions(+), 42 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index f33d91dc8..be841b3fe 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -1,8 +1,8 @@ /*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. @@ -10,7 +10,7 @@ * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. - * + * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. @@ -47,7 +47,7 @@ hash_str(const char *key, size_t key_length) return h; } -static void +static void hash_element_dtor(void *user, void *element) { curl_hash *h = (curl_hash *) user; @@ -70,7 +70,7 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) h->dtor = dtor; h->size = 0; - h->slots = slots; + h->slots = slots; h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); if(h->table) { @@ -106,10 +106,10 @@ Curl_hash_alloc(int slots, curl_hash_dtor dtor) return h; } -static int +static int hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len) { - if (key1_len == key2_len && + if (key1_len == key2_len && *key1 == *key2 && memcmp(key1, key2, key1_len) == 0) { return 1; @@ -180,29 +180,6 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) return NULL; /* failure */ } -#if 0 -int -Curl_hash_delete(curl_hash *h, char *key, size_t key_len) -{ - curl_hash_element *he; - curl_llist_element *le; - curl_llist *l = FETCH_LIST(h, key, key_len); - - for (le = l->head; - le; - le = le->next) { - he = le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { - Curl_llist_remove(l, le, (void *) h); - --h->size; - return 1; - } - } - - return 0; -} -#endif - void * Curl_hash_pick(curl_hash *h, char *key, size_t key_len) { @@ -223,7 +200,7 @@ Curl_hash_pick(curl_hash *h, char *key, size_t key_len) } #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) -void +void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) { @@ -278,15 +255,7 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user, } } -#if 0 -int -Curl_hash_count(curl_hash *h) -{ - return h->size; -} -#endif - -void +void Curl_hash_destroy(curl_hash *h) { if (!h) -- cgit v1.2.1 From 043d70fcdfa50c93dc826069aa5836206f8e3e2d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Jan 2005 00:06:29 +0000 Subject: Use plain structs and not typedef'ed ones in the hash and linked-list code. --- lib/hash.c | 59 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 30 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index be841b3fe..96ccaa7fb 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2004, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -50,12 +50,11 @@ hash_str(const char *key, size_t key_length) static void hash_element_dtor(void *user, void *element) { - curl_hash *h = (curl_hash *) user; - curl_hash_element *e = (curl_hash_element *) element; + struct curl_hash *h = (struct curl_hash *) user; + struct curl_hash_element *e = (struct curl_hash_element *) element; - if (e->key) { + if (e->key) free(e->key); - } h->dtor(e->ptr); @@ -64,7 +63,7 @@ hash_element_dtor(void *user, void *element) /* return 1 on error, 0 is fine */ int -Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) +Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor) { int i; @@ -72,7 +71,7 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) h->size = 0; h->slots = slots; - h->table = (curl_llist **) malloc(slots * sizeof(curl_llist *)); + h->table = (struct curl_llist **) malloc(slots * sizeof(struct curl_llist *)); if(h->table) { for (i = 0; i < slots; ++i) { h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); @@ -89,12 +88,12 @@ Curl_hash_init(curl_hash *h, int slots, curl_hash_dtor dtor) return 1; /* failure */ } -curl_hash * +struct curl_hash * Curl_hash_alloc(int slots, curl_hash_dtor dtor) { - curl_hash *h; + struct curl_hash *h; - h = (curl_hash *) malloc(sizeof(curl_hash)); + h = (struct curl_hash *) malloc(sizeof(struct curl_hash)); if (h) { if(Curl_hash_init(h, slots, dtor)) { /* failure */ @@ -118,11 +117,11 @@ hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len) return 0; } -static curl_hash_element * +static struct curl_hash_element * mk_hash_element(char *key, size_t key_len, const void *p) { - curl_hash_element *he = - (curl_hash_element *) malloc(sizeof(curl_hash_element)); + struct curl_hash_element *he = + (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); if(he) { char *dup = strdup(key); @@ -147,14 +146,14 @@ mk_hash_element(char *key, size_t key_len, const void *p) /* Return the data in the hash. If there already was a match in the hash, that data is returned. */ void * -Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) +Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p) { - curl_hash_element *he; - curl_llist_element *le; - curl_llist *l = FETCH_LIST(h, key, key_len); + struct curl_hash_element *he; + struct curl_llist_element *le; + struct curl_llist *l = FETCH_LIST(h, key, key_len); for (le = l->head; le; le = le->next) { - he = (curl_hash_element *) le->ptr; + he = (struct curl_hash_element *) le->ptr; if (hash_key_compare(he->key, he->key_len, key, key_len)) { h->dtor(p); /* remove the NEW entry */ return he->ptr; /* return the EXISTING entry */ @@ -181,11 +180,11 @@ Curl_hash_add(curl_hash *h, char *key, size_t key_len, void *p) } void * -Curl_hash_pick(curl_hash *h, char *key, size_t key_len) +Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len) { - curl_llist_element *le; - curl_hash_element *he; - curl_llist *l = FETCH_LIST(h, key, key_len); + struct curl_llist_element *le; + struct curl_hash_element *he; + struct curl_llist *l = FETCH_LIST(h, key, key_len); for (le = l->head; le; @@ -204,7 +203,7 @@ void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) { - curl_llist_element *le; + struct curl_llist_element *le; int i; for (i = 0; i < h->slots; ++i) { @@ -219,7 +218,7 @@ Curl_hash_apply(curl_hash *h, void *user, #endif void -Curl_hash_clean(curl_hash *h) +Curl_hash_clean(struct curl_hash *h) { int i; @@ -231,19 +230,19 @@ Curl_hash_clean(curl_hash *h) } void -Curl_hash_clean_with_criterium(curl_hash *h, void *user, +Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, int (*comp)(void *, void *)) { - curl_llist_element *le; - curl_llist_element *lnext; - curl_llist *list; + struct curl_llist_element *le; + struct curl_llist_element *lnext; + struct curl_llist *list; int i; for (i = 0; i < h->slots; ++i) { list = h->table[i]; le = list->head; /* get first list entry */ while(le) { - curl_hash_element *he = le->ptr; + struct curl_hash_element *he = le->ptr; lnext = le->next; /* ask the callback function if we shall remove this entry or not */ if (comp(user, he->ptr)) { @@ -256,7 +255,7 @@ Curl_hash_clean_with_criterium(curl_hash *h, void *user, } void -Curl_hash_destroy(curl_hash *h) +Curl_hash_destroy(struct curl_hash *h) { if (!h) return; -- cgit v1.2.1 From 686d90745be4417127050ad4b36d0a5403def200 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 10 Apr 2006 15:00:53 +0000 Subject: First curl_multi_socket() commit. Should primarily be considered as an internal code rearrange to fit the future better. --- lib/hash.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 96ccaa7fb..26ea9c475 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -124,8 +124,11 @@ mk_hash_element(char *key, size_t key_len, const void *p) (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); if(he) { - char *dup = strdup(key); + char *dup = malloc(key_len); if(dup) { + /* copy the key */ + memcpy(dup, key, key_len); + he->key = dup; he->key_len = key_len; he->ptr = (void *) p; @@ -179,6 +182,23 @@ Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p) return NULL; /* failure */ } +/* remove the identified hash entry, returns non-zero on failure */ +int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len) +{ + struct curl_llist_element *le; + struct curl_hash_element *he; + struct curl_llist *l = FETCH_LIST(h, key, key_len); + + for (le = l->head; le; le = le->next) { + he = le->ptr; + if (hash_key_compare(he->key, he->key_len, key, key_len)) { + Curl_llist_remove(l, le, (void *) h); + return 0; + } + } + return 1; +} + void * Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len) { @@ -186,9 +206,7 @@ Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len) struct curl_hash_element *he; struct curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = l->head; - le; - le = le->next) { + for (le = l->head; le; le = le->next) { he = le->ptr; if (hash_key_compare(he->key, he->key_len, key, key_len)) { return he->ptr; -- cgit v1.2.1 From f2a33eb372ec958dbb0c5eeeab546eedbaa617c2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 10 Sep 2006 22:12:24 +0000 Subject: Added a useful debug function within #if 0. The function makes it easy to "dump" a hash table which is useful when tracking problems with data stored in one of our hashes. --- lib/hash.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 26ea9c475..e00462778 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -282,3 +282,34 @@ Curl_hash_destroy(struct curl_hash *h) free(h); } +#if 0 /* useful function for debugging hashes and their contents */ +void Curl_hash_print(struct curl_hash *h, + void (*func)(void *)) +{ + int i; + struct curl_llist_element *le; + struct curl_llist *list; + struct curl_hash_element *he; + if (!h) + return; + + fprintf(stderr, "=Hash dump=\n"); + + for (i = 0; i < h->slots; i++) { + list = h->table[i]; + le = list->head; /* get first list entry */ + if(le) { + fprintf(stderr, "index %d:", i); + while(le) { + he = le->ptr; + if(func) + func(he->ptr); + else + fprintf(stderr, " [%p]", he->ptr); + le = le->next; + } + fprintf(stderr, "\n"); + } + } +} +#endif -- cgit v1.2.1 From 62f0f5571da55de683688c8fca8f8acdcbd98bec Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 26 Jun 2007 21:09:28 +0000 Subject: Robert Iakobashvili re-arranged the internal hash code to work with a custom hash function for different hashes, and also expanded the default size for the socket hash table used in multi handles to greatly enhance speed when very many connections are added and the socket API is used. --- lib/hash.c | 99 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index e00462778..ec4a759f8 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -33,20 +33,6 @@ /* this must be the last include file */ #include "memdebug.h" -static unsigned long -hash_str(const char *key, size_t key_length) -{ - char *end = (char *) key + key_length; - unsigned long h = 5381; - - while (key < end) { - h += h << 5; - h ^= (unsigned long) *key++; - } - - return h; -} - static void hash_element_dtor(void *user, void *element) { @@ -63,10 +49,20 @@ hash_element_dtor(void *user, void *element) /* return 1 on error, 0 is fine */ int -Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor) +Curl_hash_init(struct curl_hash *h, + int slots, + hash_function hfunc, + comp_function comparator, + curl_hash_dtor dtor) { int i; + if (!slots || !hfunc || !comparator ||!dtor) { + return 1; /* failure */ + } + + h->hash_func = hfunc; + h->comp_func = comparator; h->dtor = dtor; h->size = 0; h->slots = slots; @@ -89,13 +85,20 @@ Curl_hash_init(struct curl_hash *h, int slots, curl_hash_dtor dtor) } struct curl_hash * -Curl_hash_alloc(int slots, curl_hash_dtor dtor) +Curl_hash_alloc(int slots, + hash_function hfunc, + comp_function comparator, + curl_hash_dtor dtor) { struct curl_hash *h; + if (!slots || !hfunc || !comparator ||!dtor) { + return NULL; /* failure */ + } + h = (struct curl_hash *) malloc(sizeof(struct curl_hash)); if (h) { - if(Curl_hash_init(h, slots, dtor)) { + if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) { /* failure */ free(h); h = NULL; @@ -105,26 +108,16 @@ Curl_hash_alloc(int slots, curl_hash_dtor dtor) return h; } -static int -hash_key_compare(char *key1, size_t key1_len, char *key2, size_t key2_len) -{ - if (key1_len == key2_len && - *key1 == *key2 && - memcmp(key1, key2, key1_len) == 0) { - return 1; - } - return 0; -} static struct curl_hash_element * -mk_hash_element(char *key, size_t key_len, const void *p) +mk_hash_element(void *key, size_t key_len, const void *p) { struct curl_hash_element *he = (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); if(he) { - char *dup = malloc(key_len); + void *dup = malloc(key_len); if(dup) { /* copy the key */ memcpy(dup, key, key_len); @@ -142,22 +135,20 @@ mk_hash_element(char *key, size_t key_len, const void *p) return he; } -#define find_slot(__h, __k, __k_len) (hash_str(__k, __k_len) % (__h)->slots) - -#define FETCH_LIST(x,y,z) x->table[find_slot(x, y, z)] +#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)] /* Return the data in the hash. If there already was a match in the hash, that data is returned. */ void * -Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p) +Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) { struct curl_hash_element *he; struct curl_llist_element *le; - struct curl_llist *l = FETCH_LIST(h, key, key_len); + struct curl_llist *l = FETCH_LIST (h, key, key_len); for (le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { + if (h->comp_func(he->key, he->key_len, key, key_len)) { h->dtor(p); /* remove the NEW entry */ return he->ptr; /* return the EXISTING entry */ } @@ -183,7 +174,7 @@ Curl_hash_add(struct curl_hash *h, char *key, size_t key_len, void *p) } /* remove the identified hash entry, returns non-zero on failure */ -int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len) +int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) { struct curl_llist_element *le; struct curl_hash_element *he; @@ -191,7 +182,7 @@ int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len) for (le = l->head; le; le = le->next) { he = le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { + if (h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); return 0; } @@ -200,7 +191,7 @@ int Curl_hash_delete(struct curl_hash *h, char *key, size_t key_len) } void * -Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len) +Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) { struct curl_llist_element *le; struct curl_hash_element *he; @@ -208,7 +199,7 @@ Curl_hash_pick(struct curl_hash *h, char *key, size_t key_len) for (le = l->head; le; le = le->next) { he = le->ptr; - if (hash_key_compare(he->key, he->key_len, key, key_len)) { + if (h->comp_func(he->key, he->key_len, key, key_len)) { return he->ptr; } } @@ -282,6 +273,34 @@ Curl_hash_destroy(struct curl_hash *h) free(h); } +size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) +{ + char* key_str = (char *) key; + char *end = (char *) key_str + key_length; + unsigned long h = 5381; + + while (key_str < end) { + h += h << 5; + h ^= (unsigned long) *key_str++; + } + + return (h % slots_num); +} + +size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len) +{ + char *key1 = (char *)k1; + char *key2 = (char *)k2; + + if (key1_len == key2_len && + *key1 == *key2 && + memcmp(key1, key2, key1_len) == 0) { + return 1; + } + + return 0; +} + #if 0 /* useful function for debugging hashes and their contents */ void Curl_hash_print(struct curl_hash *h, void (*func)(void *)) -- cgit v1.2.1 From 1b66c1da6c6cf6e33bedbc01c93f5d4c48de4e55 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Wed, 29 Aug 2007 05:36:53 +0000 Subject: Added lots of consts --- lib/hash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index ec4a759f8..c8b5f8b37 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -111,7 +111,7 @@ Curl_hash_alloc(int slots, static struct curl_hash_element * -mk_hash_element(void *key, size_t key_len, const void *p) +mk_hash_element(const void *key, size_t key_len, const void *p) { struct curl_hash_element *he = (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); @@ -275,8 +275,8 @@ Curl_hash_destroy(struct curl_hash *h) size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) { - char* key_str = (char *) key; - char *end = (char *) key_str + key_length; + const char* key_str = (const char *) key; + const char *end = key_str + key_length; unsigned long h = 5381; while (key_str < end) { -- cgit v1.2.1 From ad05b22de350f87f295a09fb6e0745b91216aa21 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 27 Sep 2007 18:12:03 +0000 Subject: Renamed a few variables to avoid shadowing global declarations. --- lib/hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index c8b5f8b37..69437bf48 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -117,12 +117,12 @@ mk_hash_element(const void *key, size_t key_len, const void *p) (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); if(he) { - void *dup = malloc(key_len); - if(dup) { + void *dupkey = malloc(key_len); + if(dupkey) { /* copy the key */ - memcpy(dup, key, key_len); + memcpy(dupkey, key, key_len); - he->key = dup; + he->key = dupkey; he->key_len = key_len; he->ptr = (void *) p; } -- cgit v1.2.1 From cbd1a77ec24e397d05f20c6de106625676343c9d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Nov 2007 09:21:35 +0000 Subject: if () => if() while () => while() and some other minor re-indentings --- lib/hash.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 69437bf48..8496803bb 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -39,7 +39,7 @@ hash_element_dtor(void *user, void *element) struct curl_hash *h = (struct curl_hash *) user; struct curl_hash_element *e = (struct curl_hash_element *) element; - if (e->key) + if(e->key) free(e->key); h->dtor(e->ptr); @@ -57,7 +57,7 @@ Curl_hash_init(struct curl_hash *h, { int i; - if (!slots || !hfunc || !comparator ||!dtor) { + if(!slots || !hfunc || !comparator ||!dtor) { return 1; /* failure */ } @@ -92,12 +92,12 @@ Curl_hash_alloc(int slots, { struct curl_hash *h; - if (!slots || !hfunc || !comparator ||!dtor) { + if(!slots || !hfunc || !comparator ||!dtor) { return NULL; /* failure */ } h = (struct curl_hash *) malloc(sizeof(struct curl_hash)); - if (h) { + if(h) { if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) { /* failure */ free(h); @@ -148,14 +148,14 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) for (le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; - if (h->comp_func(he->key, he->key_len, key, key_len)) { + if(h->comp_func(he->key, he->key_len, key, key_len)) { h->dtor(p); /* remove the NEW entry */ return he->ptr; /* return the EXISTING entry */ } } he = mk_hash_element(key, key_len, p); - if (he) { + if(he) { if(Curl_llist_insert_next(l, l->tail, he)) { ++h->size; return p; /* return the new entry */ @@ -182,7 +182,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) for (le = l->head; le; le = le->next) { he = le->ptr; - if (h->comp_func(he->key, he->key_len, key, key_len)) { + if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); return 0; } @@ -199,7 +199,7 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) for (le = l->head; le; le = le->next) { he = le->ptr; - if (h->comp_func(he->key, he->key_len, key, key_len)) { + if(h->comp_func(he->key, he->key_len, key, key_len)) { return he->ptr; } } @@ -254,7 +254,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, struct curl_hash_element *he = le->ptr; lnext = le->next; /* ask the callback function if we shall remove this entry or not */ - if (comp(user, he->ptr)) { + if(comp(user, he->ptr)) { Curl_llist_remove(list, le, (void *) h); --h->size; /* one less entry in the hash now */ } @@ -266,7 +266,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, void Curl_hash_destroy(struct curl_hash *h) { - if (!h) + if(!h) return; Curl_hash_clean(h); @@ -279,7 +279,7 @@ size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) const char *end = key_str + key_length; unsigned long h = 5381; - while (key_str < end) { + while(key_str < end) { h += h << 5; h ^= (unsigned long) *key_str++; } @@ -292,7 +292,7 @@ size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len) char *key1 = (char *)k1; char *key2 = (char *)k2; - if (key1_len == key2_len && + if(key1_len == key2_len && *key1 == *key2 && memcmp(key1, key2, key1_len) == 0) { return 1; @@ -309,7 +309,7 @@ void Curl_hash_print(struct curl_hash *h, struct curl_llist_element *le; struct curl_llist *list; struct curl_hash_element *he; - if (!h) + if(!h) return; fprintf(stderr, "=Hash dump=\n"); -- cgit v1.2.1 From 59e378f48fed849e8e41f0bc6a10bf7a1732ae8a Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 6 Sep 2008 05:29:05 +0000 Subject: remove unnecessary typecasting of malloc() --- lib/hash.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 8496803bb..095fa7028 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -67,7 +67,7 @@ Curl_hash_init(struct curl_hash *h, h->size = 0; h->slots = slots; - h->table = (struct curl_llist **) malloc(slots * sizeof(struct curl_llist *)); + h->table = malloc(slots * sizeof(struct curl_llist *)); if(h->table) { for (i = 0; i < slots; ++i) { h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); @@ -96,7 +96,7 @@ Curl_hash_alloc(int slots, return NULL; /* failure */ } - h = (struct curl_hash *) malloc(sizeof(struct curl_hash)); + h = malloc(sizeof(struct curl_hash)); if(h) { if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) { /* failure */ @@ -113,8 +113,7 @@ Curl_hash_alloc(int slots, static struct curl_hash_element * mk_hash_element(const void *key, size_t key_len, const void *p) { - struct curl_hash_element *he = - (struct curl_hash_element *) malloc(sizeof(struct curl_hash_element)); + struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element)); if(he) { void *dupkey = malloc(key_len); -- cgit v1.2.1 From 5779283a52a1369cccbe1a1d314e2ec8ac949e0f Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 19 Oct 2008 20:17:16 +0000 Subject: attempt to fix or allow further detection of an elusive icc SIGSEGV --- lib/hash.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 095fa7028..39c7a079d 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -44,6 +44,7 @@ hash_element_dtor(void *user, void *element) h->dtor(e->ptr); + memset(e, 0, sizeof(struct curl_hash_element)); free(e); } @@ -232,6 +233,7 @@ Curl_hash_clean(struct curl_hash *h) for (i = 0; i < h->slots; ++i) { Curl_llist_destroy(h->table[i], (void *) h); + h->table[i] = NULL; } free(h->table); @@ -269,6 +271,8 @@ Curl_hash_destroy(struct curl_hash *h) return; Curl_hash_clean(h); + + memset(h, 0, sizeof(struct struct curl_hash)); free(h); } -- cgit v1.2.1 From b416b87518491ce60f76cbae29888054e6cd2596 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 19 Oct 2008 20:41:03 +0000 Subject: oops --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 39c7a079d..909e3563b 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -272,7 +272,7 @@ Curl_hash_destroy(struct curl_hash *h) Curl_hash_clean(h); - memset(h, 0, sizeof(struct struct curl_hash)); + memset(h, 0, sizeof(struct curl_hash)); free(h); } -- cgit v1.2.1 From 6bd91936ff9d525d3e1dee8f6d97d887072cb480 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 20 Oct 2008 23:24:35 +0000 Subject: remove debug-code which zero-filled some structures before free()ing them --- lib/hash.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 909e3563b..e62a79e03 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -44,7 +44,6 @@ hash_element_dtor(void *user, void *element) h->dtor(e->ptr); - memset(e, 0, sizeof(struct curl_hash_element)); free(e); } @@ -272,7 +271,6 @@ Curl_hash_destroy(struct curl_hash *h) Curl_hash_clean(h); - memset(h, 0, sizeof(struct curl_hash)); free(h); } -- cgit v1.2.1 From b701ea36a723b2d7700e23ae53e2c3145dfe7bda Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 23 Oct 2008 11:49:19 +0000 Subject: moved the Curl_raw_ functions into the new lib/rawstr.c file for easier curlx_ inclusion by the curl tool without colliding with the curl_strequal functions. --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index e62a79e03..3fcb44e4f 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms -- cgit v1.2.1 From 417bac4055ce215d3edb34f33f46e1dedaab48bb Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 25 Oct 2008 16:15:21 +0000 Subject: add missing header inclusions --- lib/hash.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 3fcb44e4f..f7d072482 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -28,9 +28,12 @@ #include "hash.h" #include "llist.h" -#include "memory.h" -/* this must be the last include file */ +#define _MPRINTF_REPLACE /* use our functions only */ +#include + +#include "memory.h" +/* The last #include file should be: */ #include "memdebug.h" static void -- cgit v1.2.1 From e29f62f0a7034a2a42fb43b913e6576e63a03fe5 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 27 Oct 2008 05:29:17 +0000 Subject: add null-pointer check --- lib/hash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index f7d072482..7757d8b64 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -45,7 +45,8 @@ hash_element_dtor(void *user, void *element) if(e->key) free(e->key); - h->dtor(e->ptr); + if(e->ptr) + h->dtor(e->ptr); free(e); } -- cgit v1.2.1 From 33a3753c3f41d546ebf3350685eb7201d25783f4 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 21 Apr 2009 11:46:16 +0000 Subject: libcurl's memory.h renamed to curl_memory.h --- lib/hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 7757d8b64..fed7b9841 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,7 @@ #define _MPRINTF_REPLACE /* use our functions only */ #include -#include "memory.h" +#include "curl_memory.h" /* The last #include file should be: */ #include "memdebug.h" -- cgit v1.2.1 From 2c166812253c28cdfbffdd4de069f5c11db3c7a8 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 10 Jun 2009 02:49:42 +0000 Subject: Adjusted to take in account that... With the curl memory tracking feature decoupled from the debug build feature, CURLDEBUG and DEBUGBUILD preprocessor symbol definitions are used as follows: CURLDEBUG used for curl debug memory tracking specific code (--enable-curldebug) DEBUGBUILD used for debug enabled specific code (--enable-debug) --- lib/hash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index fed7b9841..6ca7431ce 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -210,7 +210,7 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) return NULL; } -#if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) +#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) void Curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *user, void *ptr)) -- cgit v1.2.1 From fb5f332834baeee1c9ec27dee6fc065364d5b7f3 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Nov 2009 09:31:37 +0000 Subject: - Constantine Sapuntzakis posted bug #2891595 (http://curl.haxx.se/bug/view.cgi?id=2891595) which identified how an entry in the DNS cache would linger too long if the request that added it was in use that long. He also provided the patch that now makes libcurl capable of still doing a request while the DNS hash entry may get timed out. --- lib/hash.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 6ca7431ce..bcd144a11 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -140,8 +140,8 @@ mk_hash_element(const void *key, size_t key_len, const void *p) #define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)] -/* Return the data in the hash. If there already was a match in the hash, - that data is returned. */ +/* Insert the data in the hash. If there already was a match in the hash, + that data is replaced. */ void * Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) { @@ -152,8 +152,9 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) for (le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { - h->dtor(p); /* remove the NEW entry */ - return he->ptr; /* return the EXISTING entry */ + Curl_llist_remove(l, le, (void *)h); + --h->size; + break; } } -- cgit v1.2.1 From 2309b4e330b96bc2e1f8e36b6184015e59544037 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 Mar 2010 11:02:54 +0100 Subject: remove the CVSish $Id$ lines --- lib/hash.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index bcd144a11..cdcd26017 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -18,7 +18,6 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * $Id$ ***************************************************************************/ #include "setup.h" -- cgit v1.2.1 From b903186fa0189ff241d756d25d07fdfe9885ae49 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 20 Apr 2011 15:17:42 +0200 Subject: source cleanup: unify look, style and indent levels By the use of a the new lib/checksrc.pl script that checks that our basic source style rules are followed. --- lib/hash.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index cdcd26017..3a3a58e90 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -72,7 +72,7 @@ Curl_hash_init(struct curl_hash *h, h->table = malloc(slots * sizeof(struct curl_llist *)); if(h->table) { - for (i = 0; i < slots; ++i) { + for(i = 0; i < slots; ++i) { h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); if(!h->table[i]) { while(i--) @@ -148,7 +148,7 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) struct curl_llist_element *le; struct curl_llist *l = FETCH_LIST (h, key, key_len); - for (le = l->head; le; le = le->next) { + for(le = l->head; le; le = le->next) { he = (struct curl_hash_element *) le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *)h); @@ -183,7 +183,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) struct curl_hash_element *he; struct curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = l->head; le; le = le->next) { + for(le = l->head; le; le = le->next) { he = le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); @@ -200,7 +200,7 @@ Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) struct curl_hash_element *he; struct curl_llist *l = FETCH_LIST(h, key, key_len); - for (le = l->head; le; le = le->next) { + for(le = l->head; le; le = le->next) { he = le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { return he->ptr; @@ -218,10 +218,10 @@ Curl_hash_apply(curl_hash *h, void *user, struct curl_llist_element *le; int i; - for (i = 0; i < h->slots; ++i) { - for (le = (h->table[i])->head; - le; - le = le->next) { + for(i = 0; i < h->slots; ++i) { + for(le = (h->table[i])->head; + le; + le = le->next) { curl_hash_element *el = le->ptr; cb(user, el->ptr); } @@ -234,7 +234,7 @@ Curl_hash_clean(struct curl_hash *h) { int i; - for (i = 0; i < h->slots; ++i) { + for(i = 0; i < h->slots; ++i) { Curl_llist_destroy(h->table[i], (void *) h); h->table[i] = NULL; } @@ -251,7 +251,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, struct curl_llist *list; int i; - for (i = 0; i < h->slots; ++i) { + for(i = 0; i < h->slots; ++i) { list = h->table[i]; le = list->head; /* get first list entry */ while(le) { @@ -319,7 +319,7 @@ void Curl_hash_print(struct curl_hash *h, fprintf(stderr, "=Hash dump=\n"); - for (i = 0; i < h->slots; i++) { + for(i = 0; i < h->slots; i++) { list = h->table[i]; le = list->head; /* get first list entry */ if(le) { -- cgit v1.2.1 From 0f7bea7c3a6ddb0bf43f890c764322faaa3ba561 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 10 Jun 2011 14:40:46 +0200 Subject: unittest: mark all unit tested functions With "@unittest: [num]" in the header comment for each tested function. Shows we have a log way to go still... --- lib/hash.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 3a3a58e90..6c921e442 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -140,7 +140,10 @@ mk_hash_element(const void *key, size_t key_len, const void *p) #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. */ + * that data is replaced. + * + * @unittest: 1305 + */ void * Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) { -- cgit v1.2.1 From f1586cb4775681810afd8e6626e7842d459f3b85 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 26 Jul 2011 17:23:27 +0200 Subject: stdio.h, stdlib.h, string.h, stdarg.h and ctype.h inclusion done in setup_once.h --- lib/hash.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 6c921e442..3a6e312a3 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -22,9 +22,6 @@ #include "setup.h" -#include -#include - #include "hash.h" #include "llist.h" -- cgit v1.2.1 From 17f48fe87979f159e2d8769d678641c60f4c0eed Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 7 Oct 2011 20:50:57 +0200 Subject: libcurl: some OOM handling fixes --- lib/hash.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 3a6e312a3..15b3efff6 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -72,9 +72,12 @@ Curl_hash_init(struct curl_hash *h, for(i = 0; i < slots; ++i) { h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); if(!h->table[i]) { - while(i--) + while(i--) { Curl_llist_destroy(h->table[i], NULL); + h->table[i] = NULL; + } free(h->table); + h->table = NULL; return 1; /* failure */ } } @@ -240,6 +243,7 @@ Curl_hash_clean(struct curl_hash *h) } free(h->table); + h->table = NULL; } void -- cgit v1.2.1 From 584dc8b8af862f7f47a3a9f02f874ac0bd0076be Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 11 Oct 2011 19:41:30 +0200 Subject: OOM handling/cleanup slight adjustments --- lib/hash.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 15b3efff6..3704eea41 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -38,11 +38,14 @@ hash_element_dtor(void *user, void *element) struct curl_hash *h = (struct curl_hash *) user; struct curl_hash_element *e = (struct curl_hash_element *) element; - if(e->key) - free(e->key); + Curl_safefree(e->key); - if(e->ptr) + if(e->ptr) { h->dtor(e->ptr); + e->ptr = NULL; + } + + e->key_len = 0; free(e); } @@ -78,13 +81,16 @@ Curl_hash_init(struct curl_hash *h, } free(h->table); h->table = NULL; + h->slots = 0; return 1; /* failure */ } } return 0; /* fine */ } - else + else { + h->slots = 0; return 1; /* failure */ + } } struct curl_hash * @@ -190,6 +196,7 @@ int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) he = le->ptr; if(h->comp_func(he->key, he->key_len, key, key_len)) { Curl_llist_remove(l, le, (void *) h); + --h->size; return 0; } } @@ -244,6 +251,8 @@ Curl_hash_clean(struct curl_hash *h) free(h->table); h->table = NULL; + h->size = 0; + h->slots = 0; } void -- cgit v1.2.1 From 996f2454ba0c4368497637e937f8d184d0151c45 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 25 Dec 2011 11:35:45 +0100 Subject: hash.c: fix OOM triggered segfault --- lib/hash.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 3704eea41..4d85188fb 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -264,6 +264,9 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, struct curl_llist *list; int i; + if(!h) + return; + for(i = 0; i < h->slots; ++i) { list = h->table[i]; le = list->head; /* get first list entry */ -- cgit v1.2.1 From d021f2e8a0067fc769652f27afec9024c0d02b3d Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Thu, 6 Dec 2012 12:12:04 +0100 Subject: Introducing a new persistent connection caching system using "bundles". A bundle is a list of all persistent connections to the same host. The connection cache consists of a hash of bundles, with the hostname as the key. The benefits may not be obvious, but they are two: 1) Faster search for connections to reuse, since the hash lookup only finds connections to the host in question. 2) It lays out the groundworks for an upcoming patch, which will introduce multiple HTTP pipelines. This patch also removes the awkward list of "closure handles", which were needed to send QUIT commands to the FTP server when closing a connection. Now we allocate a separate closure handle and use that one to close all connections. This has been tested in a live system for a few weeks, and of course passes the test suite. --- lib/hash.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 17 deletions(-) (limited to 'lib/hash.c') diff --git a/lib/hash.c b/lib/hash.c index 4d85188fb..585285b03 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -322,34 +322,77 @@ size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len) return 0; } +void Curl_hash_start_iterate(struct curl_hash *hash, + struct curl_hash_iterator *iter) +{ + iter->hash = hash; + iter->slot_index = 0; + iter->current_element = NULL; +} + +struct curl_hash_element * +Curl_hash_next_element(struct curl_hash_iterator *iter) +{ + int i; + struct curl_hash *h = iter->hash; + + /* Get the next element in the current list, if any */ + if(iter->current_element) + iter->current_element = iter->current_element->next; + + /* If we have reached the end of the list, find the next one */ + if(!iter->current_element) { + for(i = iter->slot_index;i < h->slots;i++) { + if(h->table[i]->head) { + iter->current_element = h->table[i]->head; + iter->slot_index = i+1; + break; + } + } + } + + if(iter->current_element) { + struct curl_hash_element *he = iter->current_element->ptr; + return he; + } + else { + iter->current_element = NULL; + return NULL; + } +} + #if 0 /* useful function for debugging hashes and their contents */ void Curl_hash_print(struct curl_hash *h, void (*func)(void *)) { - int i; - struct curl_llist_element *le; - struct curl_llist *list; - struct curl_hash_element *he; + struct curl_hash_iterator iter; + struct curl_hash_element *he; + int last_index = -1; + if(!h) return; fprintf(stderr, "=Hash dump=\n"); - for(i = 0; i < h->slots; i++) { - list = h->table[i]; - le = list->head; /* get first list entry */ - if(le) { - fprintf(stderr, "index %d:", i); - while(le) { - he = le->ptr; - if(func) - func(he->ptr); - else - fprintf(stderr, " [%p]", he->ptr); - le = le->next; + Curl_hash_start_iterate(h, &iter); + + he = Curl_hash_next_element(&iter); + while(he) { + if(iter.slot_index != last_index) { + fprintf(stderr, "index %d:", iter.slot_index); + if(last_index >= 0) { + fprintf(stderr, "\n"); } - fprintf(stderr, "\n"); + last_index = iter.slot_index; } + + if(func) + func(he->ptr); + else + fprintf(stderr, " [%p]", he->ptr); + + he = Curl_hash_next_element(&iter); } + fprintf(stderr, "\n"); } #endif -- cgit v1.2.1