util/set: add a clone function
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 25 Jun 2018 16:51:20 +0000 (09:51 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Thu, 12 Jul 2018 21:03:51 +0000 (14:03 -0700)
v2: Add unit test. (Eric Anholt)

Reviewed-by: Eric Anholt <eric@anholt.net>
src/util/set.c
src/util/set.h
src/util/tests/set/set_test.cpp

index 2c9b09319ff9abbd4344b3039bb55ea0a3c03502..b2aa5ba13d58e928e48e2f9e49cf407e8c1e89fe 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <stdlib.h>
 #include <assert.h>
+#include <string.h>
 
 #include "macros.h"
 #include "ralloc.h"
@@ -132,6 +133,28 @@ _mesa_set_create(void *mem_ctx,
    return ht;
 }
 
+struct set *
+_mesa_set_clone(struct set *set, void *dst_mem_ctx)
+{
+   struct set *clone;
+
+   clone = ralloc(dst_mem_ctx, struct set);
+   if (clone == NULL)
+      return NULL;
+
+   memcpy(clone, set, sizeof(struct set));
+
+   clone->table = ralloc_array(clone, struct set_entry, clone->size);
+   if (clone->table == NULL) {
+      ralloc_free(clone);
+      return NULL;
+   }
+
+   memcpy(clone->table, set->table, clone->size * sizeof(struct set_entry));
+
+   return clone;
+}
+
 /**
  * Frees the given set.
  *
index 06e79e158677b8077bb1658939682fe7fb88494a..4db070a6f10d88e1baaf1e362dc82f529c01f181 100644 (file)
@@ -58,6 +58,9 @@ _mesa_set_create(void *mem_ctx,
                  uint32_t (*key_hash_function)(const void *key),
                  bool (*key_equals_function)(const void *a,
                                              const void *b));
+struct set *
+_mesa_set_clone(struct set *set, void *dst_mem_ctx);
+
 void
 _mesa_set_destroy(struct set *set,
                   void (*delete_function)(struct set_entry *entry));
index e6a83f17ca2272824a2c6b627e73542df5ad2f29..c0998560b50db21157b9e160349e35f496faae3e 100644 (file)
@@ -53,3 +53,35 @@ TEST(set, basic)
 
    _mesa_set_destroy(s, NULL);
 }
+
+TEST(set, clone)
+{
+   struct set *s = _mesa_set_create(NULL, _mesa_hash_pointer,
+                                    _mesa_key_pointer_equal);
+   struct set_entry *entry;
+
+   const void *a = (const void *)10;
+   const void *b = (const void *)20;
+   const void *c = (const void *)30;
+
+   _mesa_set_add(s, a);
+   _mesa_set_add(s, b);
+   _mesa_set_add(s, c);
+
+   entry = _mesa_set_search(s, c);
+   EXPECT_TRUE(entry);
+   EXPECT_EQ(entry->key, c);
+
+   _mesa_set_remove(s, entry);
+   EXPECT_EQ(s->entries, 2);
+
+   struct set *clone = _mesa_set_clone(s, NULL);
+   EXPECT_EQ(clone->entries, 2);
+
+   EXPECT_TRUE(_mesa_set_search(clone, a));
+   EXPECT_TRUE(_mesa_set_search(clone, b));
+   EXPECT_FALSE(_mesa_set_search(clone, c));
+
+   _mesa_set_destroy(s, NULL);
+   _mesa_set_destroy(clone, NULL);
+}