diff options
-rw-r--r-- | src/util/set.c | 23 | ||||
-rw-r--r-- | src/util/set.h | 3 | ||||
-rw-r--r-- | src/util/tests/set/set_test.cpp | 32 |
3 files changed, 58 insertions, 0 deletions
diff --git a/src/util/set.c b/src/util/set.c index 2c9b09319ff..b2aa5ba13d5 100644 --- a/src/util/set.c +++ b/src/util/set.c @@ -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. * diff --git a/src/util/set.h b/src/util/set.h index 06e79e15867..4db070a6f10 100644 --- a/src/util/set.h +++ b/src/util/set.h @@ -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)); diff --git a/src/util/tests/set/set_test.cpp b/src/util/tests/set/set_test.cpp index e6a83f17ca2..c0998560b50 100644 --- a/src/util/tests/set/set_test.cpp +++ b/src/util/tests/set/set_test.cpp @@ -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); +} |