Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/vector.c')
-rw-r--r--src/vector.c80
1 files changed, 66 insertions, 14 deletions
diff --git a/src/vector.c b/src/vector.c
index 362e7b0c0..c769b696a 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -6,7 +6,6 @@
*/
#include "common.h"
-#include "repository.h"
#include "vector.h"
/* In elements, not bytes */
@@ -55,9 +54,11 @@ int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp)
bytes = src->length * sizeof(void *);
v->_alloc_size = src->length;
- v->_cmp = cmp;
+ v->_cmp = cmp ? cmp : src->_cmp;
v->length = src->length;
- v->sorted = src->sorted && cmp == src->_cmp;
+ v->flags = src->flags;
+ if (cmp != src->_cmp)
+ git_vector_set_sorted(v, 0);
v->contents = git__malloc(bytes);
GITERR_CHECK_ALLOC(v->contents);
@@ -77,6 +78,20 @@ void git_vector_free(git_vector *v)
v->_alloc_size = 0;
}
+void git_vector_free_deep(git_vector *v)
+{
+ size_t i;
+
+ assert(v);
+
+ for (i = 0; i < v->length; ++i) {
+ git__free(v->contents[i]);
+ v->contents[i] = NULL;
+ }
+
+ git_vector_free(v);
+}
+
int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp)
{
assert(v);
@@ -84,12 +99,28 @@ int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp)
v->_alloc_size = 0;
v->_cmp = cmp;
v->length = 0;
- v->sorted = 1;
+ v->flags = GIT_VECTOR_SORTED;
v->contents = NULL;
return resize_vector(v, max(initial_size, MIN_ALLOCSIZE));
}
+void **git_vector_detach(size_t *size, size_t *asize, git_vector *v)
+{
+ void **data = v->contents;
+
+ if (size)
+ *size = v->length;
+ if (asize)
+ *asize = v->_alloc_size;
+
+ v->_alloc_size = 0;
+ v->length = 0;
+ v->contents = NULL;
+
+ return data;
+}
+
int git_vector_insert(git_vector *v, void *element)
{
assert(v);
@@ -99,7 +130,8 @@ int git_vector_insert(git_vector *v, void *element)
return -1;
v->contents[v->length++] = element;
- v->sorted = 0;
+
+ git_vector_set_sorted(v, v->length <= 1);
return 0;
}
@@ -112,7 +144,7 @@ int git_vector_insert_sorted(
assert(v && v->_cmp);
- if (!v->sorted)
+ if (!git_vector_is_sorted(v))
git_vector_sort(v);
if (v->length >= v->_alloc_size &&
@@ -142,11 +174,12 @@ void git_vector_sort(git_vector *v)
{
assert(v);
- if (v->sorted || !v->_cmp)
+ if (git_vector_is_sorted(v) || !v->_cmp)
return;
- git__tsort(v->contents, v->length, v->_cmp);
- v->sorted = 1;
+ if (v->length > 1)
+ git__tsort(v->contents, v->length, v->_cmp);
+ git_vector_set_sorted(v, 1);
}
int git_vector_bsearch2(
@@ -244,14 +277,16 @@ void git_vector_uniq(git_vector *v, void (*git_free_cb)(void *))
}
void git_vector_remove_matching(
- git_vector *v, int (*match)(const git_vector *v, size_t idx))
+ git_vector *v,
+ int (*match)(const git_vector *v, size_t idx, void *payload),
+ void *payload)
{
size_t i, j;
for (i = 0, j = 0; j < v->length; ++j) {
v->contents[i] = v->contents[j];
- if (!match(v, i))
+ if (!match(v, i, payload))
i++;
}
@@ -262,7 +297,7 @@ void git_vector_clear(git_vector *v)
{
assert(v);
v->length = 0;
- v->sorted = 1;
+ git_vector_set_sorted(v, 1);
}
void git_vector_swap(git_vector *a, git_vector *b)
@@ -295,8 +330,10 @@ int git_vector_resize_to(git_vector *v, size_t new_length)
int git_vector_set(void **old, git_vector *v, size_t position, void *value)
{
- if (git_vector_resize_to(v, position + 1) < 0)
- return -1;
+ if (position + 1 > v->length) {
+ if (git_vector_resize_to(v, position + 1) < 0)
+ return -1;
+ }
if (old != NULL)
*old = v->contents[position];
@@ -305,3 +342,18 @@ int git_vector_set(void **old, git_vector *v, size_t position, void *value)
return 0;
}
+
+int git_vector_verify_sorted(const git_vector *v)
+{
+ size_t i;
+
+ if (!git_vector_is_sorted(v))
+ return -1;
+
+ for (i = 1; i < v->length; ++i) {
+ if (v->_cmp(v->contents[i - 1], v->contents[i]) > 0)
+ return -1;
+ }
+
+ return 0;
+}