X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=rculfhash.c;h=807a22d177ed85b6d853dbfe71757342104e33a5;hb=a481e5ffa28452175e9d70467a07fd131c957728;hp=9aeb3e76598071c0b450a4287c2fe8c615bc9a29;hpb=14044b37bb7ba51676f1c3f139facae9b06dbc51;p=urcu.git diff --git a/rculfhash.c b/rculfhash.c index 9aeb3e7..807a22d 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -621,6 +621,9 @@ struct cds_lfht *cds_lfht_new(cds_lfht_hash_fct hash_fct, struct cds_lfht *ht; unsigned long order; + /* init_size must be power of two */ + if (init_size & (init_size - 1)) + return NULL; ht = calloc(1, sizeof(struct cds_lfht)); ht->hash_fct = hash_fct; ht->compare_fct = compare_fct; @@ -675,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;