From a481e5ffa28452175e9d70467a07fd131c957728 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sat, 3 Sep 2011 12:20:31 -0400 Subject: [PATCH] rculfhash: implement cds_lfht_next Useful for walk traversal of all nodes sharing the same key (lookup + next until NULL is returned). Signed-off-by: Mathieu Desnoyers --- rculfhash.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/rculfhash.c b/rculfhash.c index 1720afb..807a22d 100644 --- a/rculfhash.c +++ b/rculfhash.c @@ -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; -- 2.34.1