mirror of
https://git.proxmox.com/git/libgit2
synced 2025-12-30 22:59:52 +00:00
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.)
This commit is contained in:
parent
277c85eb1c
commit
be30387e8b
1222
src/iterator.c
1222
src/iterator.c
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,8 @@ struct git_iterator {
|
||||
git_repository *repo;
|
||||
char *start;
|
||||
char *end;
|
||||
bool started;
|
||||
bool ended;
|
||||
git_vector pathlist;
|
||||
size_t pathlist_walk_idx;
|
||||
int (*strcomp)(const char *a, const char *b);
|
||||
@ -254,7 +256,7 @@ extern int git_iterator_current_tree_entry(
|
||||
const git_tree_entry **entry_out, git_iterator *iter);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@ -264,37 +264,30 @@ static void check_tree_entry(
|
||||
const git_index_entry *ie;
|
||||
const git_tree_entry *te;
|
||||
const git_tree *tree;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
cl_git_pass(git_iterator_current_tree_entry(&te, i));
|
||||
cl_assert(te);
|
||||
cl_assert(git_oid_streq(te->oid, oid) == 0);
|
||||
|
||||
cl_git_pass(git_iterator_current(&ie, i));
|
||||
cl_git_pass(git_buf_sets(&path, ie->path));
|
||||
|
||||
if (oid_p) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, 0));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_p) == 0);
|
||||
}
|
||||
|
||||
if (oid_pp) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, 1));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_pp) == 0);
|
||||
}
|
||||
|
||||
if (oid_ppp) {
|
||||
git_buf_rtruncate_at_char(&path, '/');
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, path.ptr));
|
||||
cl_git_pass(git_iterator_current_parent_tree(&tree, i, 2));
|
||||
cl_assert(tree);
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), oid_ppp) == 0);
|
||||
}
|
||||
|
||||
git_buf_free(&path);
|
||||
}
|
||||
|
||||
void test_diff_iterator__tree_special_functions(void)
|
||||
|
||||
@ -1455,7 +1455,7 @@ void test_repo_iterator__treefilelist(void)
|
||||
git_repository_head_tree(&tree, g_repo);
|
||||
|
||||
/* 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.count = filelist.length;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user