X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=rculfhash.c;h=b67acc820a078011f81963608f7c366fc1a3d2ec;hb=238cc06e5728e3a642d4d22bd4fc199cfd265110;hp=18a3cb89c8b273b81757fd763f4b472d8301e6d6;hpb=93d46c395ff595372827983e9e84bd1e49eb6fab;p=urcu.git diff --git a/rculfhash.c b/rculfhash.c index 18a3cb8..b67acc8 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -894,22 +894,38 @@ void _cds_lfht_add(struct cds_lfht *ht, goto insert; if (likely(clear_flag(iter)->p.reverse_hash > node->p.reverse_hash)) goto insert; + /* dummy node is the first node of the identical-hash-value chain */ if (dummy && clear_flag(iter)->p.reverse_hash == node->p.reverse_hash) goto insert; + next = rcu_dereference(clear_flag(iter)->p.next); if (unlikely(is_removed(next))) goto gc_node; + + /* uniquely add */ if (unique_ret && !is_dummy(next) - && clear_flag(iter)->p.reverse_hash == node->p.reverse_hash - && !ht->compare_fct(node->key, node->key_len, - clear_flag(iter)->key, - clear_flag(iter)->key_len)) { - unique_ret->node = clear_flag(iter); - unique_ret->next = next; + && clear_flag(iter)->p.reverse_hash == node->p.reverse_hash) { + struct cds_lfht_iter d_iter = { .node = node, .next = iter, }; + + /* + * uniquely adding inserts the node as the first + * node of the identical-hash-value node chain. + * + * This semantic ensures no duplicated keys + * should ever be observable in the table + * (including observe one node by one node + * by forward iterations) + */ + cds_lfht_next_duplicate(ht, &d_iter); + if (!d_iter.node) + goto insert; + + *unique_ret = d_iter; return; } + /* Only account for identical reverse hash once */ if (iter_prev->p.reverse_hash != clear_flag(iter)->p.reverse_hash && !is_dummy(next))