X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=rculfhash.c;h=556ec36ddab261625d3c3b412496718c790d0c0b;hb=18117871130163ec2b2fc73fda288b9ba26cd435;hp=11c0077977f327e5437a13d050f8eceb6e7a6a6b;hpb=49c2e2d66ea7a3c0012343d89723fd608e877024;p=urcu.git diff --git a/rculfhash.c b/rculfhash.c index 11c0077..556ec36 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -234,14 +234,16 @@ void _ht_gc_bucket(struct rcu_ht_node *dummy, struct rcu_ht_node *node) } static -int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, - int unique) +struct rcu_ht_node *_ht_add(struct rcu_ht *ht, struct rcu_table *t, + struct rcu_ht_node *node, int unique) { struct rcu_ht_node *iter_prev, *dummy, *iter, *next; unsigned long hash; - if (!t->size) - return 0; + if (!t->size) { + assert(node->dummy); + return node; /* Initial first add (head) */ + } hash = bit_reverse_ulong(node->reverse_hash); for (;;) { uint32_t chain_len = 0; @@ -262,6 +264,12 @@ int _ht_add(struct rcu_ht *ht, struct rcu_table *t, struct rcu_ht_node *node, next = rcu_dereference(clear_flag(iter)->next); if (is_removed(next)) goto gc_node; + if (unique + && !clear_flag(iter)->dummy + && !ht->compare_fct(node->key, node->key_len, + clear_flag(iter)->key, + clear_flag(iter)->key_len)) + return clear_flag(iter); /* Only account for identical reverse hash once */ if (iter_prev->reverse_hash != clear_flag(iter)->reverse_hash) check_resize(ht, t, ++chain_len); @@ -287,7 +295,7 @@ gc_end: /* Garbage collect logically removed nodes in the bucket */ dummy = rcu_dereference(t->tbl[hash & (t->size - 1)]); _ht_gc_bucket(dummy, node); - return 0; + return node; } static @@ -417,7 +425,7 @@ void ht_add(struct rcu_ht *ht, struct rcu_ht_node *node) (void) _ht_add(ht, t, node, 0); } -int ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node) +struct rcu_ht_node *ht_add_unique(struct rcu_ht *ht, struct rcu_ht_node *node) { struct rcu_table *t; unsigned long hash;