rculfhash: implement cds_lfht_next
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 3 Sep 2011 16:20:31 +0000 (12:20 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sat, 3 Sep 2011 16:20:31 +0000 (12:20 -0400)
Useful for walk traversal of all nodes sharing the same key (lookup +
next until NULL is returned).

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
rculfhash.c

index 1720afb61669e971968fc2cfcd994db3e6b7b8be..807a22d177ed85b6d853dbfe71757342104e33a5 100644 (file)
@@ -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;
This page took 0.027807 seconds and 4 git commands to generate.