summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/util/set.c23
-rw-r--r--src/util/set.h3
-rw-r--r--src/util/tests/set/set_test.cpp32
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);
+}