aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/curl/lib/hash.c
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-10-16 12:11:24 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-10-16 12:11:24 +0000
commit40811e93f3fdf9342a9295369994012420fac548 (patch)
treea8d85e094a9c21e10aa250f537c101fc2016a049 /contrib/libs/curl/lib/hash.c
parent30ebe5357bb143648c6be4d151ecd4944af81ada (diff)
parent28a0c4a9f297064538a018c512cd9bbd00a1a35d (diff)
downloadydb-40811e93f3fdf9342a9295369994012420fac548.tar.gz
Merge branch 'rightlib' into mergelibs-241016-1210
Diffstat (limited to 'contrib/libs/curl/lib/hash.c')
-rw-r--r--contrib/libs/curl/lib/hash.c175
1 files changed, 71 insertions, 104 deletions
diff --git a/contrib/libs/curl/lib/hash.c b/contrib/libs/curl/lib/hash.c
index 1910ac5dc4..30f28e2352 100644
--- a/contrib/libs/curl/lib/hash.c
+++ b/contrib/libs/curl/lib/hash.c
@@ -33,10 +33,6 @@
/* The last #include file should be: */
#include "memdebug.h"
-/* random patterns for API verification */
-#define HASHINIT 0x7017e781
-#define ITERINIT 0x5FEDCBA9
-
static void
hash_element_dtor(void *user, void *element)
{
@@ -44,10 +40,7 @@ hash_element_dtor(void *user, void *element)
struct Curl_hash_element *e = (struct Curl_hash_element *) element;
if(e->ptr) {
- if(e->dtor)
- e->dtor(e->key, e->key_len, e->ptr);
- else
- h->dtor(e->ptr);
+ h->dtor(e->ptr);
e->ptr = NULL;
}
@@ -64,7 +57,7 @@ hash_element_dtor(void *user, void *element)
*/
void
Curl_hash_init(struct Curl_hash *h,
- size_t slots,
+ int slots,
hash_function hfunc,
comp_function comparator,
Curl_hash_dtor dtor)
@@ -81,14 +74,10 @@ Curl_hash_init(struct Curl_hash *h,
h->dtor = dtor;
h->size = 0;
h->slots = slots;
-#ifdef DEBUGBUILD
- h->init = HASHINIT;
-#endif
}
static struct Curl_hash_element *
-mk_hash_element(const void *key, size_t key_len, const void *p,
- Curl_hash_elem_dtor dtor)
+mk_hash_element(const void *key, size_t key_len, const void *p)
{
/* allocate the struct plus memory after it to store the key */
struct Curl_hash_element *he = malloc(sizeof(struct Curl_hash_element) +
@@ -98,25 +87,31 @@ mk_hash_element(const void *key, size_t key_len, const void *p,
memcpy(he->key, key, key_len);
he->key_len = key_len;
he->ptr = (void *) p;
- he->dtor = dtor;
}
return he;
}
#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
-void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p,
- Curl_hash_elem_dtor dtor)
+/* Insert the data in the hash. If there already was a match in the hash, that
+ * data is replaced. This function also "lazily" allocates the table if
+ * needed, as it isn't done in the _init function (anymore).
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void *
+Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
{
struct Curl_hash_element *he;
- struct Curl_llist_node *le;
+ struct Curl_llist_element *le;
struct Curl_llist *l;
DEBUGASSERT(h);
DEBUGASSERT(h->slots);
- DEBUGASSERT(h->init == HASHINIT);
if(!h->table) {
- size_t i;
+ int i;
h->table = malloc(h->slots * sizeof(struct Curl_llist));
if(!h->table)
return NULL; /* OOM */
@@ -126,18 +121,18 @@ void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p,
l = FETCH_LIST(h, key, key_len);
- for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) {
- he = (struct Curl_hash_element *) Curl_node_elem(le);
+ 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_node_uremove(le, (void *)h);
+ Curl_llist_remove(l, le, (void *)h);
--h->size;
break;
}
}
- he = mk_hash_element(key, key_len, p, dtor);
+ he = mk_hash_element(key, key_len, p);
if(he) {
- Curl_llist_append(l, he, &he->list);
+ Curl_llist_insert_next(l, l->tail, he, &he->list);
++h->size;
return p; /* return the new entry */
}
@@ -145,20 +140,6 @@ void *Curl_hash_add2(struct Curl_hash *h, void *key, size_t key_len, void *p,
return NULL; /* failure */
}
-/* Insert the data in the hash. If there already was a match in the hash, that
- * data is replaced. This function also "lazily" allocates the table if
- * needed, as it is not done in the _init function (anymore).
- *
- * @unittest: 1305
- * @unittest: 1602
- * @unittest: 1603
- */
-void *
-Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
-{
- return Curl_hash_add2(h, key, key_len, p, NULL);
-}
-
/* Remove the identified hash entry.
* Returns non-zero on failure.
*
@@ -166,17 +147,18 @@ Curl_hash_add(struct Curl_hash *h, void *key, size_t key_len, void *p)
*/
int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len)
{
+ struct Curl_llist_element *le;
+ struct Curl_llist *l;
+
DEBUGASSERT(h);
DEBUGASSERT(h->slots);
- DEBUGASSERT(h->init == HASHINIT);
if(h->table) {
- struct Curl_llist_node *le;
- struct Curl_llist *l = FETCH_LIST(h, key, key_len);
+ l = FETCH_LIST(h, key, key_len);
- for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) {
- struct Curl_hash_element *he = Curl_node_elem(le);
+ for(le = l->head; le; le = le->next) {
+ struct Curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
- Curl_node_uremove(le, (void *) h);
+ Curl_llist_remove(l, le, (void *) h);
--h->size;
return 0;
}
@@ -192,15 +174,15 @@ int Curl_hash_delete(struct Curl_hash *h, void *key, size_t key_len)
void *
Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
{
+ struct Curl_llist_element *le;
+ struct Curl_llist *l;
+
DEBUGASSERT(h);
- DEBUGASSERT(h->init == HASHINIT);
if(h->table) {
- struct Curl_llist_node *le;
- struct Curl_llist *l;
DEBUGASSERT(h->slots);
l = FETCH_LIST(h, key, key_len);
- for(le = Curl_llist_head(l); le; le = Curl_node_next(le)) {
- struct Curl_hash_element *he = Curl_node_elem(le);
+ for(le = l->head; le; le = le->next) {
+ struct Curl_hash_element *he = le->ptr;
if(h->comp_func(he->key, he->key_len, key, key_len)) {
return he->ptr;
}
@@ -210,6 +192,25 @@ Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
return NULL;
}
+#if defined(DEBUGBUILD) && defined(AGGRESSIVE_TEST)
+void
+Curl_hash_apply(Curl_hash *h, void *user,
+ void (*cb)(void *user, void *ptr))
+{
+ struct Curl_llist_element *le;
+ int i;
+
+ 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);
+ }
+ }
+}
+#endif
+
/* Destroys all the entries in the given hash and resets its attributes,
* prepping the given hash for [static|dynamic] deallocation.
*
@@ -220,9 +221,8 @@ Curl_hash_pick(struct Curl_hash *h, void *key, size_t key_len)
void
Curl_hash_destroy(struct Curl_hash *h)
{
- DEBUGASSERT(h->init == HASHINIT);
if(h->table) {
- size_t i;
+ int i;
for(i = 0; i < h->slots; ++i) {
Curl_llist_destroy(&h->table[i], (void *) h);
}
@@ -242,33 +242,28 @@ Curl_hash_clean(struct Curl_hash *h)
Curl_hash_clean_with_criterium(h, NULL, NULL);
}
-size_t Curl_hash_count(struct Curl_hash *h)
-{
- DEBUGASSERT(h->init == HASHINIT);
- return h->size;
-}
-
/* Cleans all entries that pass the comp function criteria. */
void
Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user,
int (*comp)(void *, void *))
{
- size_t i;
+ struct Curl_llist_element *le;
+ struct Curl_llist_element *lnext;
+ struct Curl_llist *list;
+ int i;
if(!h || !h->table)
return;
- DEBUGASSERT(h->init == HASHINIT);
for(i = 0; i < h->slots; ++i) {
- struct Curl_llist *list = &h->table[i];
- struct Curl_llist_node *le =
- Curl_llist_head(list); /* get first list entry */
+ list = &h->table[i];
+ le = list->head; /* get first list entry */
while(le) {
- struct Curl_hash_element *he = Curl_node_elem(le);
- struct Curl_llist_node *lnext = Curl_node_next(le);
+ struct Curl_hash_element *he = le->ptr;
+ lnext = le->next;
/* ask the callback function if we shall remove this entry or not */
if(!comp || comp(user, he->ptr)) {
- Curl_node_uremove(le, (void *) h);
+ Curl_llist_remove(list, le, (void *) h);
--h->size; /* one less entry in the hash now */
}
le = lnext;
@@ -283,9 +278,8 @@ size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num)
size_t h = 5381;
while(key_str < end) {
- size_t j = (size_t)*key_str++;
h += h << 5;
- h ^= j;
+ h ^= *key_str++;
}
return (h % slots_num);
@@ -303,34 +297,29 @@ size_t Curl_str_key_compare(void *k1, size_t key1_len,
void Curl_hash_start_iterate(struct Curl_hash *hash,
struct Curl_hash_iterator *iter)
{
- DEBUGASSERT(hash->init == HASHINIT);
iter->hash = hash;
iter->slot_index = 0;
iter->current_element = NULL;
-#ifdef DEBUGBUILD
- iter->init = ITERINIT;
-#endif
}
struct Curl_hash_element *
Curl_hash_next_element(struct Curl_hash_iterator *iter)
{
- struct Curl_hash *h;
- DEBUGASSERT(iter->init == ITERINIT);
- h = iter->hash;
+ struct Curl_hash *h = iter->hash;
+
if(!h->table)
return NULL; /* empty hash, nothing to return */
/* Get the next element in the current list, if any */
if(iter->current_element)
- iter->current_element = Curl_node_next(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) {
- size_t i;
+ int i;
for(i = iter->slot_index; i < h->slots; i++) {
- if(Curl_llist_head(&h->table[i])) {
- iter->current_element = Curl_llist_head(&h->table[i]);
+ if(h->table[i].head) {
+ iter->current_element = h->table[i].head;
iter->slot_index = i + 1;
break;
}
@@ -338,7 +327,7 @@ Curl_hash_next_element(struct Curl_hash_iterator *iter)
}
if(iter->current_element) {
- struct Curl_hash_element *he = Curl_node_elem(iter->current_element);
+ struct Curl_hash_element *he = iter->current_element->ptr;
return he;
}
return NULL;
@@ -350,7 +339,7 @@ void Curl_hash_print(struct Curl_hash *h,
{
struct Curl_hash_iterator iter;
struct Curl_hash_element *he;
- size_t last_index = ~0;
+ int last_index = -1;
if(!h)
return;
@@ -363,7 +352,7 @@ void Curl_hash_print(struct Curl_hash *h,
while(he) {
if(iter.slot_index != last_index) {
fprintf(stderr, "index %d:", iter.slot_index);
- if(last_index != ~0) {
+ if(last_index >= 0) {
fprintf(stderr, "\n");
}
last_index = iter.slot_index;
@@ -379,25 +368,3 @@ void Curl_hash_print(struct Curl_hash *h,
fprintf(stderr, "\n");
}
#endif
-
-void Curl_hash_offt_init(struct Curl_hash *h,
- size_t slots,
- Curl_hash_dtor dtor)
-{
- Curl_hash_init(h, slots, Curl_hash_str, Curl_str_key_compare, dtor);
-}
-
-void *Curl_hash_offt_set(struct Curl_hash *h, curl_off_t id, void *elem)
-{
- return Curl_hash_add(h, &id, sizeof(id), elem);
-}
-
-int Curl_hash_offt_remove(struct Curl_hash *h, curl_off_t id)
-{
- return Curl_hash_delete(h, &id, sizeof(id));
-}
-
-void *Curl_hash_offt_get(struct Curl_hash *h, curl_off_t id)
-{
- return Curl_hash_pick(h, &id, sizeof(id));
-}