diff --git a/src/vector.c b/src/vector.c index 8d09350fc..2fc051f0c 100644 --- a/src/vector.c +++ b/src/vector.c @@ -162,6 +162,26 @@ int git_vector_remove(git_vector *v, unsigned int idx) return GIT_SUCCESS; } +void git_vector_uniq(git_vector *v) +{ + git_vector_cmp cmp; + unsigned int i, j; + + if (v->length <= 1) + return; + + git_vector_sort(v); + cmp = v->_cmp ? v->_cmp : strict_comparison; + + for (i = 0, j = 1 ; j < v->length; ++j) + if (!cmp(v->contents + i, v->contents + j)) + v->contents[i] = v->contents[j]; + else + v->contents[++i] = v->contents[j]; + + v->length -= j - i - 1; +} + void git_vector_clear(git_vector *v) { assert(v); diff --git a/src/vector.h b/src/vector.h index 256452ee5..76778ba4e 100644 --- a/src/vector.h +++ b/src/vector.h @@ -32,5 +32,5 @@ GIT_INLINE(void *) git_vector_get(git_vector *v, unsigned int position) int git_vector_insert(git_vector *v, void *element); int git_vector_remove(git_vector *v, unsigned int idx); - +void git_vector_uniq(git_vector *v); #endif diff --git a/tests/t00-core.c b/tests/t00-core.c index ba5188a43..661f92508 100644 --- a/tests/t00-core.c +++ b/tests/t00-core.c @@ -73,6 +73,28 @@ BEGIN_TEST(vector1, "don't read past array bounds on remove()") git_vector_free(&x); END_TEST +static int test_cmp(const void *a, const void *b) +{ + int n1 = *(int *)a; + int n2 = *(int *)b; + + return n1 - n2; +} + +BEGIN_TEST(vector2, "remove duplicates") + git_vector x; + must_pass(git_vector_init(&x, 5, test_cmp)); + must_pass(git_vector_insert(&x, (void *) 0xdeadbeef)); + must_pass(git_vector_insert(&x, (void *) 0xcafebabe)); + must_pass(git_vector_insert(&x, (void *) 0xcafebabe)); + must_pass(git_vector_insert(&x, (void *) 0xdeadbeef)); + must_pass(git_vector_insert(&x, (void *) 0xcafebabe)); + must_be_true(x.length == 5); + git_vector_uniq(&x); + must_be_true(x.length == 2); + git_vector_free(&x); +END_TEST + BEGIN_TEST(path0, "get the dirname of a path") char dir[64], *dir2; @@ -480,6 +502,7 @@ BEGIN_SUITE(core) ADD_TEST(vector0); ADD_TEST(vector1); + ADD_TEST(vector2); ADD_TEST(path0); ADD_TEST(path1);