Commit be30387e by Edward Thomson

iterators: refactored tree iterator

Refactored the tree iterator to never recurse; simply process the
next entry in order in `advance`.  Additionally, reduce the number of
allocations and sorting as much as possible to provide a ~30% speedup
on case-sensitive iteration.  (The gains for case-insensitive iteration
are less majestic.)
parent 277c85eb
...@@ -69,6 +69,8 @@ struct git_iterator { ...@@ -69,6 +69,8 @@ struct git_iterator {
git_repository *repo; git_repository *repo;
char *start; char *start;
char *end; char *end;
bool started;
bool ended;
git_vector pathlist; git_vector pathlist;
size_t pathlist_walk_idx; size_t pathlist_walk_idx;
int (*strcomp)(const char *a, const char *b); int (*strcomp)(const char *a, const char *b);
...@@ -254,7 +256,7 @@ extern int git_iterator_current_tree_entry( ...@@ -254,7 +256,7 @@ extern int git_iterator_current_tree_entry(
const git_tree_entry **entry_out, git_iterator *iter); const git_tree_entry **entry_out, git_iterator *iter);
extern int git_iterator_current_parent_tree( extern int git_iterator_current_parent_tree(
const git_tree **tree_out, git_iterator *iter, const char *parent_path); const git_tree **tree_out, git_iterator *iter, size_t depth);
extern bool git_iterator_current_is_ignored(git_iterator *iter); extern bool git_iterator_current_is_ignored(git_iterator *iter);
......
...@@ -264,37 +264,30 @@ static void check_tree_entry( ...@@ -264,37 +264,30 @@ static void check_tree_entry(
const git_index_entry *ie; const git_index_entry *ie;
const git_tree_entry *te; const git_tree_entry *te;
const git_tree *tree; const git_tree *tree;
git_buf path = GIT_BUF_INIT;
cl_git_pass(git_iterator_current_tree_entry(&te, i)); cl_git_pass(git_iterator_current_tree_entry(&te, i));
cl_assert(te); cl_assert(te);
cl_assert(git_oid_streq(te->oid, oid) == 0); cl_assert(git_oid_streq(te->oid, oid) == 0);
cl_git_pass(git_iterator_current(&ie, i)); cl_git_pass(git_iterator_current(&ie, i));
cl_git_pass(git_buf_sets(&path, ie->path));
if (oid_p) { if (oid_p) {
git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, 0));
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
cl_assert(tree); cl_assert(tree);
cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0); cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0);
} }
if (oid_pp) { if (oid_pp) {
git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, 1));
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
cl_assert(tree); cl_assert(tree);
cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0); cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0);
} }
if (oid_ppp) { if (oid_ppp) {
git_buf_rtruncate_at_char(&path, '/'); cl_git_pass(git_iterator_current_parent_tree(&tree, i, 2));
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
cl_assert(tree); cl_assert(tree);
cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0); cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0);
} }
git_buf_free(&path);
} }
void test_diff_iterator__tree_special_functions(void) void test_diff_iterator__tree_special_functions(void)
......
...@@ -1455,7 +1455,7 @@ void test_repo_iterator__treefilelist(void) ...@@ -1455,7 +1455,7 @@ void test_repo_iterator__treefilelist(void)
git_repository_head_tree(&tree, g_repo); git_repository_head_tree(&tree, g_repo);
/* All indexfilelist iterator tests are "autoexpand with no tree entries" */ /* All indexfilelist iterator tests are "autoexpand with no tree entries" */
/* In this test we DO NOT force a case on the iteratords and verify default behavior. */ /* In this test we DO NOT force a case on the iterators and verify default behavior. */
i_opts.pathlist.strings = (char **)filelist.contents; i_opts.pathlist.strings = (char **)filelist.contents;
i_opts.pathlist.count = filelist.length; i_opts.pathlist.count = filelist.length;
......
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