Unverified Commit cc9c9522 by Edward Thomson Committed by GitHub

Merge pull request #4606 from libgit2/cmn/revwalk-iteration

revwalk: avoid walking the entire history when output is unsorted
parents 96882f20 ff98fec0
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "merge.h" #include "merge.h"
#include "vector.h" #include "vector.h"
static int get_revision(git_commit_list_node **out, git_revwalk *walk, git_commit_list **list);
git_commit_list_node *git_revwalk__commit_lookup( git_commit_list_node *git_revwalk__commit_lookup(
git_revwalk *walk, const git_oid *oid) git_revwalk *walk, const git_oid *oid)
{ {
...@@ -76,10 +78,12 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting, ...@@ -76,10 +78,12 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting,
if (commit->uninteresting) if (commit->uninteresting)
return 0; return 0;
if (uninteresting) if (uninteresting) {
walk->limited = 1;
walk->did_hide = 1; walk->did_hide = 1;
else } else {
walk->did_push = 1; walk->did_push = 1;
}
commit->uninteresting = uninteresting; commit->uninteresting = uninteresting;
list = walk->user_input; list = walk->user_input;
...@@ -245,9 +249,10 @@ static int revwalk_next_timesort(git_commit_list_node **object_out, git_revwalk ...@@ -245,9 +249,10 @@ static int revwalk_next_timesort(git_commit_list_node **object_out, git_revwalk
static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk *walk) static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk *walk)
{ {
int error;
git_commit_list_node *next; git_commit_list_node *next;
while ((next = git_commit_list_pop(&walk->iterator_rand)) != NULL) { while (!(error = get_revision(&next, walk, &walk->iterator_rand))) {
/* Some commits might become uninteresting after being added to the list */ /* Some commits might become uninteresting after being added to the list */
if (!next->uninteresting) { if (!next->uninteresting) {
*object_out = next; *object_out = next;
...@@ -255,15 +260,15 @@ static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk ...@@ -255,15 +260,15 @@ static int revwalk_next_unsorted(git_commit_list_node **object_out, git_revwalk
} }
} }
giterr_clear(); return error;
return GIT_ITEROVER;
} }
static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk *walk) static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk *walk)
{ {
int error;
git_commit_list_node *next; git_commit_list_node *next;
while ((next = git_commit_list_pop(&walk->iterator_topo)) != NULL) { while (!(error = get_revision(&next, walk, &walk->iterator_topo))) {
/* Some commits might become uninteresting after being added to the list */ /* Some commits might become uninteresting after being added to the list */
if (!next->uninteresting) { if (!next->uninteresting) {
*object_out = next; *object_out = next;
...@@ -271,8 +276,7 @@ static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk ...@@ -271,8 +276,7 @@ static int revwalk_next_toposort(git_commit_list_node **object_out, git_revwalk
} }
} }
giterr_clear(); return error;
return GIT_ITEROVER;
} }
static int revwalk_next_reverse(git_commit_list_node **object_out, git_revwalk *walk) static int revwalk_next_reverse(git_commit_list_node **object_out, git_revwalk *walk)
...@@ -434,6 +438,30 @@ static int limit_list(git_commit_list **out, git_revwalk *walk, git_commit_list ...@@ -434,6 +438,30 @@ static int limit_list(git_commit_list **out, git_revwalk *walk, git_commit_list
return 0; return 0;
} }
static int get_revision(git_commit_list_node **out, git_revwalk *walk, git_commit_list **list)
{
int error;
git_commit_list_node *commit;
commit = git_commit_list_pop(list);
if (!commit) {
giterr_clear();
return GIT_ITEROVER;
}
/*
* If we did not run limit_list and we must add parents to the
* list ourselves.
*/
if (!walk->limited) {
if ((error = add_parents_to_list(walk, commit, list)) < 0)
return error;
}
*out = commit;
return 0;
}
static int sort_in_topological_order(git_commit_list **out, git_revwalk *walk, git_commit_list *list) static int sort_in_topological_order(git_commit_list **out, git_revwalk *walk, git_commit_list *list)
{ {
git_commit_list *ll = NULL, *newlist, **pptr; git_commit_list *ll = NULL, *newlist, **pptr;
...@@ -546,7 +574,7 @@ static int prepare_walk(git_revwalk *walk) ...@@ -546,7 +574,7 @@ static int prepare_walk(git_revwalk *walk)
} }
} }
if ((error = limit_list(&commits, walk, commits)) < 0) if (walk->limited && (error = limit_list(&commits, walk, commits)) < 0)
return error; return error;
if (walk->sorting & GIT_SORT_TOPOLOGICAL) { if (walk->sorting & GIT_SORT_TOPOLOGICAL) {
...@@ -649,6 +677,9 @@ void git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode) ...@@ -649,6 +677,9 @@ void git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode)
walk->get_next = &revwalk_next_unsorted; walk->get_next = &revwalk_next_unsorted;
walk->enqueue = &revwalk_enqueue_unsorted; walk->enqueue = &revwalk_enqueue_unsorted;
} }
if (sort_mode != GIT_SORT_NONE)
walk->limited = 1;
} }
void git_revwalk_simplify_first_parent(git_revwalk *walk) void git_revwalk_simplify_first_parent(git_revwalk *walk)
...@@ -704,6 +735,7 @@ void git_revwalk_reset(git_revwalk *walk) ...@@ -704,6 +735,7 @@ void git_revwalk_reset(git_revwalk *walk)
git_commit_list_free(&walk->user_input); git_commit_list_free(&walk->user_input);
walk->first_parent = 0; walk->first_parent = 0;
walk->walking = 0; walk->walking = 0;
walk->limited = 0;
walk->did_push = walk->did_hide = 0; walk->did_push = walk->did_hide = 0;
} }
...@@ -725,6 +757,7 @@ int git_revwalk_add_hide_cb( ...@@ -725,6 +757,7 @@ int git_revwalk_add_hide_cb(
walk->hide_cb = hide_cb; walk->hide_cb = hide_cb;
walk->hide_cb_payload = payload; walk->hide_cb_payload = payload;
walk->limited = 1;
return 0; return 0;
} }
......
...@@ -36,7 +36,8 @@ struct git_revwalk { ...@@ -36,7 +36,8 @@ struct git_revwalk {
unsigned walking:1, unsigned walking:1,
first_parent: 1, first_parent: 1,
did_hide: 1, did_hide: 1,
did_push: 1; did_push: 1,
limited: 1;
unsigned int sorting; unsigned int sorting;
/* the pushes and hides */ /* the pushes and hides */
......
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