ovsdb: Fix bug in JSON-RPC server.
[openvswitch] / lib / shash.c
index da33fe8b6fab4b994ffc2c0ee3793c56f171cf7c..c35164bd92e277b98e5599c46f41f92485f909f5 100644 (file)
@@ -58,6 +58,12 @@ shash_is_empty(const struct shash *shash)
     return hmap_is_empty(&shash->map);
 }
 
+size_t
+shash_count(const struct shash *shash)
+{
+    return hmap_count(&shash->map);
+}
+
 /* It is the caller's responsibility to avoid duplicate names, if that is
  * desirable. */
 struct shash_node *
@@ -100,6 +106,19 @@ shash_find_data(const struct shash *sh, const char *name)
     return node ? node->data : NULL;
 }
 
+void *
+shash_find_and_delete(struct shash *sh, const char *name)
+{
+    struct shash_node *node = shash_find(sh, name);
+    if (node) {
+        void *data = node->data;
+        shash_delete(sh, node);
+        return data;
+    } else {
+        return NULL;
+    }
+}
+
 struct shash_node *
 shash_first(const struct shash *shash)
 {
@@ -107,3 +126,34 @@ shash_first(const struct shash *shash)
     return node ? CONTAINER_OF(node, struct shash_node, node) : NULL;
 }
 
+static int
+compare_nodes_by_name(const void *a_, const void *b_)
+{
+    const struct shash_node *const *a = a_;
+    const struct shash_node *const *b = b_;
+    return strcmp((*a)->name, (*b)->name);
+}
+
+const struct shash_node **
+shash_sort(const struct shash *sh)
+{
+    if (shash_is_empty(sh)) {
+        return NULL;
+    } else {
+        const struct shash_node **nodes;
+        struct shash_node *node;
+        size_t i, n;
+
+        n = shash_count(sh);
+        nodes = xmalloc(n * sizeof *nodes);
+        i = 0;
+        SHASH_FOR_EACH (node, sh) {
+            nodes[i++] = node;
+        }
+        assert(i == n);
+
+        qsort(nodes, n, sizeof *nodes, compare_nodes_by_name);
+
+        return nodes;
+    }
+}