hmap: New function hmap_replace().
authorBen Pfaff <blp@nicira.com>
Sat, 28 Feb 2009 00:55:30 +0000 (16:55 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 2 Mar 2009 20:51:59 +0000 (12:51 -0800)
lib/hmap.h

index 9a35c42c197ccee980741df93f0a3589a767fe02..9010db92e8cf866595306051f1d72f42bc4a66ff 100644 (file)
@@ -80,6 +80,8 @@ static inline void hmap_insert(struct hmap *, struct hmap_node *, size_t hash);
 static inline void hmap_remove(struct hmap *, struct hmap_node *);
 static inline void hmap_moved(struct hmap *,
                               struct hmap_node *, struct hmap_node *);
+static inline void hmap_replace(struct hmap *, const struct hmap_node *old,
+                                struct hmap_node *new);
 
 /* Search. */
 #define HMAP_FOR_EACH_WITH_HASH(NODE, STRUCT, MEMBER, HASH, HMAP)       \
@@ -180,6 +182,25 @@ hmap_moved(struct hmap *hmap,
     *bucket = node;
 }
 
+/* Puts 'new' in the position in 'hmap' currently occupied by 'old'.  The 'new'
+ * node must hash to the same value as 'old'.  The client is responsible for
+ * ensuring that the replacement does not violate any client-imposed
+ * invariants (e.g. uniqueness of keys within a map).
+ *
+ * Afterward, 'old' is not part of 'hmap', and the client is responsible for
+ * freeing it (if this is desirable). */
+static inline void
+hmap_replace(struct hmap *hmap,
+             const struct hmap_node *old, struct hmap_node *new)
+{
+    struct hmap_node **bucket = &hmap->buckets[old->hash & hmap->mask];
+    while (*bucket != old) {
+        bucket = &(*bucket)->next;
+    }
+    *bucket = new;
+    new->hash = old->hash;
+}
+
 static inline struct hmap_node *
 hmap_next_with_hash__(const struct hmap_node *node, size_t hash)
 {