Commit 4569bfa5 by Vicent Marti

Keep the tree entries always internally sorted

Don't allow access to any tree entries whilst the entries array is
unsorted. We keep track on when the array is unsorted, and any methods
that access the array while it is unsorted now sort the array before
accessing it.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
parent 5d773a6e
...@@ -87,6 +87,7 @@ void git_tree_clear_entries(git_tree *tree) ...@@ -87,6 +87,7 @@ void git_tree_clear_entries(git_tree *tree)
git_vector_clear(&tree->entries); git_vector_clear(&tree->entries);
tree->object.modified = 1; tree->object.modified = 1;
tree->sorted = 1;
} }
...@@ -108,6 +109,7 @@ git_tree *git_tree__new(void) ...@@ -108,6 +109,7 @@ git_tree *git_tree__new(void)
return NULL; return NULL;
} }
tree->sorted = 1;
return tree; return tree;
} }
...@@ -178,6 +180,9 @@ git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename) ...@@ -178,6 +180,9 @@ git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
assert(tree && filename); assert(tree && filename);
if (!tree->sorted)
git_tree_sort_entries(tree);
idx = git_vector_search(&tree->entries, filename); idx = git_vector_search(&tree->entries, filename);
if (idx == GIT_ENOTFOUND) if (idx == GIT_ENOTFOUND)
return NULL; return NULL;
...@@ -188,6 +193,10 @@ git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename) ...@@ -188,6 +193,10 @@ git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
git_tree_entry *git_tree_entry_byindex(git_tree *tree, int idx) git_tree_entry *git_tree_entry_byindex(git_tree *tree, int idx)
{ {
assert(tree); assert(tree);
if (!tree->sorted)
git_tree_sort_entries(tree);
return git_vector_get(&tree->entries, (unsigned int)idx); return git_vector_get(&tree->entries, (unsigned int)idx);
} }
...@@ -219,22 +228,23 @@ int git_tree_add_entry_unsorted(git_tree_entry **entry_out, git_tree *tree, cons ...@@ -219,22 +228,23 @@ int git_tree_add_entry_unsorted(git_tree_entry **entry_out, git_tree *tree, cons
*entry_out = entry; *entry_out = entry;
tree->object.modified = 1; tree->object.modified = 1;
tree->sorted = 0;
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_tree_add_entry(git_tree_entry **entry_out, git_tree *tree, const git_oid *id, const char *filename, int attributes) int git_tree_add_entry(git_tree_entry **entry_out, git_tree *tree, const git_oid *id, const char *filename, int attributes)
{ {
int result = git_tree_add_entry_unsorted(entry_out, tree, id, filename, attributes); int result = git_tree_add_entry_unsorted(entry_out, tree, id, filename, attributes);
if (result == GIT_SUCCESS) { if (result == GIT_SUCCESS)
git_vector_sort(&tree->entries); git_tree_sort_entries(tree);
return GIT_SUCCESS;
}
return result; return result;
} }
int git_tree_sort_entries(git_tree *tree) int git_tree_sort_entries(git_tree *tree)
{ {
git_vector_sort(&tree->entries); git_vector_sort(&tree->entries);
tree->sorted = 1;
return GIT_SUCCESS; return GIT_SUCCESS;
} }
...@@ -244,6 +254,9 @@ int git_tree_remove_entry_byindex(git_tree *tree, int idx) ...@@ -244,6 +254,9 @@ int git_tree_remove_entry_byindex(git_tree *tree, int idx)
assert(tree); assert(tree);
if (!tree->sorted)
git_tree_sort_entries(tree);
remove_ptr = git_vector_get(&tree->entries, (unsigned int)idx); remove_ptr = git_vector_get(&tree->entries, (unsigned int)idx);
if (remove_ptr == NULL) if (remove_ptr == NULL)
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
...@@ -262,6 +275,9 @@ int git_tree_remove_entry_byname(git_tree *tree, const char *filename) ...@@ -262,6 +275,9 @@ int git_tree_remove_entry_byname(git_tree *tree, const char *filename)
assert(tree && filename); assert(tree && filename);
if (!tree->sorted)
git_tree_sort_entries(tree);
idx = git_vector_search(&tree->entries, filename); idx = git_vector_search(&tree->entries, filename);
if (idx == GIT_ENOTFOUND) if (idx == GIT_ENOTFOUND)
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
...@@ -279,7 +295,8 @@ int git_tree__writeback(git_tree *tree, git_odb_source *src) ...@@ -279,7 +295,8 @@ int git_tree__writeback(git_tree *tree, git_odb_source *src)
if (tree->entries.length == 0) if (tree->entries.length == 0)
return GIT_EMISSINGOBJDATA; return GIT_EMISSINGOBJDATA;
git_vector_sort(&tree->entries); if (!tree->sorted)
git_tree_sort_entries(tree);
for (i = 0; i < tree->entries.length; ++i) { for (i = 0; i < tree->entries.length; ++i) {
git_tree_entry *entry; git_tree_entry *entry;
......
...@@ -16,6 +16,7 @@ struct git_tree_entry { ...@@ -16,6 +16,7 @@ struct git_tree_entry {
struct git_tree { struct git_tree {
git_object object; git_object object;
git_vector entries; git_vector entries;
unsigned sorted:1;
}; };
void git_tree__free(git_tree *tree); void git_tree__free(git_tree *tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment