[ovs-dev] [netlink v3 04/16] hmap: New function hmap_at_position().

Ben Pfaff blp at nicira.com
Thu Dec 30 00:56:25 UTC 2010


This function offers a way to iterate through an hmap in situations where
it is not safe to retain a node pointer.

Acked-by: Jesse Gross <jesse at nicira.com>
---
 lib/hmap.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 lib/hmap.h |    3 +++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/lib/hmap.c b/lib/hmap.c
index 6b850fd..9f27744 100644
--- a/lib/hmap.c
+++ b/lib/hmap.c
@@ -218,3 +218,46 @@ hmap_random_node(const struct hmap *hmap)
     }
     return node;
 }
+
+/* Returns the next node in 'hmap' in hash order, or NULL if no nodes remain in
+ * 'hmap'.  Uses '*bucketp' and '*offsetp' to determine where to begin
+ * iteration, and stores new values to pass on the next iteration into them
+ * before returning.
+ *
+ * It's better to use plain HMAP_FOR_EACH and related functions, since they are
+ * faster and better at dealing with hmaps that change during iteration.
+ *
+ * Before beginning iteration, store 0 into '*bucketp' and '*offsetp'.
+ */
+struct hmap_node *
+hmap_at_position(const struct hmap *hmap,
+                 uint32_t *bucketp, uint32_t *offsetp)
+{
+    size_t offset;
+    size_t b_idx;
+
+    offset = *offsetp;
+    for (b_idx = *bucketp; b_idx <= hmap->mask; b_idx++) {
+        struct hmap_node *node;
+        size_t n_idx;
+
+        for (n_idx = 0, node = hmap->buckets[b_idx]; node != NULL;
+             n_idx++, node = node->next) {
+            if (n_idx == offset) {
+                if (node->next) {
+                    *bucketp = node->hash & hmap->mask;
+                    *offsetp = offset + 1;
+                } else {
+                    *bucketp = (node->hash & hmap->mask) + 1;
+                    *offsetp = 0;
+                }
+                return node;
+            }
+        }
+        offset = 0;
+    }
+
+    *bucketp = 0;
+    *offsetp = 0;
+    return NULL;
+}
diff --git a/lib/hmap.h b/lib/hmap.h
index f6d2827..a987fa4 100644
--- a/lib/hmap.h
+++ b/lib/hmap.h
@@ -157,6 +157,9 @@ static inline struct hmap_node *hmap_first(const struct hmap *);
 static inline struct hmap_node *hmap_next(const struct hmap *,
                                           const struct hmap_node *);
 
+struct hmap_node *hmap_at_position(const struct hmap *,
+                                   uint32_t *bucket, uint32_t *offset);
+
 /* Returns the number of nodes currently in 'hmap'. */
 static inline size_t
 hmap_count(const struct hmap *hmap)
-- 
1.7.1





More information about the dev mailing list