From: Junio C Hamano Date: Thu, 7 Aug 2008 01:48:32 +0000 (-0700) Subject: Merge branch 'ag/rewrite_one' into maint X-Git-Tag: v1.6.0-rc3~15^2~3 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/1e040c0b0577b3de0006f43daa71bfe7ad7532c0?ds=inline;hp=-c Merge branch 'ag/rewrite_one' into maint * ag/rewrite_one: Fix quadratic performance in rewrite_one. --- 1e040c0b0577b3de0006f43daa71bfe7ad7532c0 diff --combined revision.c index 8dc3ca7bf6,d464f14d50..a68abec3f2 --- a/revision.c +++ b/revision.c @@@ -259,7 -259,7 +259,7 @@@ static int tree_difference = REV_TREE_S static void file_add_remove(struct diff_options *options, int addremove, unsigned mode, const unsigned char *sha1, - const char *base, const char *path) + const char *fullpath) { int diff = REV_TREE_DIFFERENT; @@@ -285,7 -285,7 +285,7 @@@ static void file_change(struct diff_opt unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *fullpath) { tree_difference = REV_TREE_DIFFERENT; DIFF_OPT_SET(options, HAS_CHANGES); @@@ -412,10 -412,26 +412,26 @@@ static void try_to_simplify_commit(stru commit->object.flags |= TREESAME; } - static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list) + static void insert_by_date_cached(struct commit *p, struct commit_list **head, + struct commit_list *cached_base, struct commit_list **cache) + { + struct commit_list *new_entry; + + if (cached_base && p->date < cached_base->item->date) + new_entry = insert_by_date(p, &cached_base->next); + else + new_entry = insert_by_date(p, head); + + if (cache && (!*cache || p->date < (*cache)->item->date)) + *cache = new_entry; + } + + static int add_parents_to_list(struct rev_info *revs, struct commit *commit, + struct commit_list **list, struct commit_list **cache_ptr) { struct commit_list *parent = commit->parents; unsigned left_flag; + struct commit_list *cached_base = cache_ptr ? *cache_ptr : NULL; if (commit->object.flags & ADDED) return 0; @@@ -445,7 -461,7 +461,7 @@@ if (p->object.flags & SEEN) continue; p->object.flags |= SEEN; - insert_by_date(p, list); + insert_by_date_cached(p, list, cached_base, cache_ptr); } return 0; } @@@ -470,7 -486,7 +486,7 @@@ p->object.flags |= left_flag; if (!(p->object.flags & SEEN)) { p->object.flags |= SEEN; - insert_by_date(p, list); + insert_by_date_cached(p, list, cached_base, cache_ptr); } if(revs->first_parent_only) break; @@@ -611,7 -627,7 +627,7 @@@ static int limit_list(struct rev_info * if (revs->max_age != -1 && (commit->date < revs->max_age)) obj->flags |= UNINTERESTING; - if (add_parents_to_list(revs, commit, &list) < 0) + if (add_parents_to_list(revs, commit, &list, NULL) < 0) return -1; if (obj->flags & UNINTERESTING) { mark_parents_uninteresting(commit); @@@ -1458,10 -1474,12 +1474,12 @@@ enum rewrite_result static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp) { + struct commit_list *cache = NULL; + for (;;) { struct commit *p = *pp; if (!revs->limited) - if (add_parents_to_list(revs, p, &revs->commits) < 0) + if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0) return rewrite_one_error; if (p->parents && p->parents->next) return rewrite_one_ok; @@@ -1580,7 -1598,7 +1598,7 @@@ static struct commit *get_revision_1(st if (revs->max_age != -1 && (commit->date < revs->max_age)) continue; - if (add_parents_to_list(revs, commit, &revs->commits) < 0) + if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0) return NULL; }