X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=rculfhash.c;h=174c11cf7babb4a35a7d533b3dd557ab221ae3dc;hp=1720afb61669e971968fc2cfcd994db3e6b7b8be;hb=5dc45f257a9242fa600dd8a3b245f601cb5b17a0;hpb=8129be4e7b668906bdbb68c4d7c9fcb403ae977a diff --git a/rculfhash.c b/rculfhash.c index 1720afb..174c11c 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -622,7 +622,7 @@ struct cds_lfht *cds_lfht_new(cds_lfht_hash_fct hash_fct, unsigned long order; /* init_size must be power of two */ - if (init_size & (init_size - 1)) + if (init_size && (init_size & (init_size - 1))) return NULL; ht = calloc(1, sizeof(struct cds_lfht)); ht->hash_fct = hash_fct; @@ -678,6 +678,39 @@ struct cds_lfht_node *cds_lfht_lookup(struct cds_lfht *ht, void *key, size_t key return node; } +struct cds_lfht_node *cds_lfht_next(struct cds_lfht *ht, + struct cds_lfht_node *node) +{ + struct cds_lfht_node *next; + unsigned long reverse_hash; + void *key; + size_t key_len; + + reverse_hash = node->p.reverse_hash; + key = node->key; + key_len = node->key_len; + next = rcu_dereference(node->p.next); + node = clear_flag(next); + + for (;;) { + if (unlikely(!node)) + break; + if (unlikely(node->p.reverse_hash > reverse_hash)) { + node = NULL; + break; + } + next = rcu_dereference(node->p.next); + if (likely(!is_removed(next)) + && !is_dummy(next) + && likely(!ht->compare_fct(node->key, node->key_len, key, key_len))) { + break; + } + node = clear_flag(next); + } + assert(!node || !is_dummy(rcu_dereference(node->p.next))); + return node; +} + void cds_lfht_add(struct cds_lfht *ht, struct cds_lfht_node *node) { struct rcu_table *t;