]> git.proxmox.com Git - mirror_ovs.git/blobdiff - lib/sset.c
sset: New function sset_from_delimited_string().
[mirror_ovs.git] / lib / sset.c
index 443538d6475dee77dab561b86d9eeda584cdda4c..be29cc71ef2e38920404a8b1078690f1290b6342 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -99,6 +99,25 @@ sset_moved(struct sset *set)
     hmap_moved(&set->map);
 }
 
+/* Initializes 'set' with substrings of 's' that are delimited by any of the
+ * characters in 'delimiters'.  For example,
+ *     sset_from_delimited_string(&set, "a b,c", " ,");
+ * initializes 'set' with three strings "a", "b", and "c". */
+void
+sset_from_delimited_string(struct sset *set, const char *s_,
+                           const char *delimiters)
+{
+    sset_init(set);
+
+    char *s = xstrdup(s_);
+    char *token, *save_ptr = NULL;
+    for (token = strtok_r(s, delimiters, &save_ptr); token != NULL;
+         token = strtok_r(NULL, delimiters, &save_ptr)) {
+        sset_add(set, token);
+    }
+    free(s);
+}
+
 /* Returns true if 'set' contains no strings, false if it contains at least one
  * string. */
 bool
@@ -251,39 +270,42 @@ sset_equals(const struct sset *a, const struct sset *b)
 }
 
 /* Returns the next node in 'set' in hash order, or NULL if no nodes remain in
- * 'set'.  Uses '*bucketp' and '*offsetp' to determine where to begin
- * iteration, and stores new values to pass on the next iteration into them
- * before returning.
+ * 'set'.  Uses '*pos' to determine where to begin iteration, and updates
+ * '*pos' to pass on the next iteration into them before returning.
  *
  * It's better to use plain SSET_FOR_EACH and related functions, since they are
  * faster and better at dealing with ssets that change during iteration.
  *
- * Before beginning iteration, store 0 into '*bucketp' and '*offsetp'.
- */
+ * Before beginning iteration, set '*pos' to all zeros. */
 struct sset_node *
-sset_at_position(const struct sset *set, uint32_t *bucketp, uint32_t *offsetp)
+sset_at_position(const struct sset *set, struct sset_position *pos)
 {
     struct hmap_node *hmap_node;
 
-    hmap_node = hmap_at_position(&set->map, bucketp, offsetp);
+    hmap_node = hmap_at_position(&set->map, &pos->pos);
     return SSET_NODE_FROM_HMAP_NODE(hmap_node);
 }
 
-static int
-compare_string_pointers(const void *a_, const void *b_)
+/* Replaces 'a' by the intersection of 'a' and 'b'.  That is, removes from 'a'
+ * all of the strings that are not also in 'b'. */
+void
+sset_intersect(struct sset *a, const struct sset *b)
 {
-    const char *const *a = a_;
-    const char *const *b = b_;
+    const char *name, *next;
 
-    return strcmp(*a, *b);
+    SSET_FOR_EACH_SAFE (name, next, a) {
+        if (!sset_contains(b, name)) {
+            sset_delete(a, SSET_NODE_FROM_NAME(name));
+        }
+    }
 }
 
-/* Returns a null-terminated array of pointers to the strings in 'set', sorted
- * alphabetically.  The caller must free the returned array when it is no
+/* Returns a null-terminated array of pointers to the strings in 'set', in no
+ * particular order.  The caller must free the returned array when it is no
  * longer needed, but the strings in the array belong to 'set' and thus must
  * not be modified or freed. */
 const char **
-sset_sort(const struct sset *set)
+sset_array(const struct sset *set)
 {
     size_t n = sset_count(set);
     const char **array;
@@ -298,7 +320,26 @@ sset_sort(const struct sset *set)
     ovs_assert(i == n);
     array[n] = NULL;
 
-    qsort(array, n, sizeof *array, compare_string_pointers);
+    return array;
+}
+
+static int
+compare_string_pointers(const void *a_, const void *b_)
+{
+    const char *const *a = a_;
+    const char *const *b = b_;
 
+    return strcmp(*a, *b);
+}
+
+/* Returns a null-terminated array of pointers to the strings in 'set', sorted
+ * alphabetically.  The caller must free the returned array when it is no
+ * longer needed, but the strings in the array belong to 'set' and thus must
+ * not be modified or freed. */
+const char **
+sset_sort(const struct sset *set)
+{
+    const char **array = sset_array(set);
+    qsort(array, sset_count(set), sizeof *array, compare_string_pointers);
     return array;
 }