Skip to content

Commit c158cae

Browse files
committed
Merge branch 'ag/rewrite_one'
* ag/rewrite_one: Fix quadratic performance in rewrite_one.
2 parents 223bb84 + fce87ae commit c158cae

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

revision.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,26 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
413413
commit->object.flags |= TREESAME;
414414
}
415415

416-
static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
416+
static void insert_by_date_cached(struct commit *p, struct commit_list **head,
417+
struct commit_list *cached_base, struct commit_list **cache)
418+
{
419+
struct commit_list *new_entry;
420+
421+
if (cached_base && p->date < cached_base->item->date)
422+
new_entry = insert_by_date(p, &cached_base->next);
423+
else
424+
new_entry = insert_by_date(p, head);
425+
426+
if (cache && (!*cache || p->date < (*cache)->item->date))
427+
*cache = new_entry;
428+
}
429+
430+
static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
431+
struct commit_list **list, struct commit_list **cache_ptr)
417432
{
418433
struct commit_list *parent = commit->parents;
419434
unsigned left_flag;
435+
struct commit_list *cached_base = cache_ptr ? *cache_ptr : NULL;
420436

421437
if (commit->object.flags & ADDED)
422438
return 0;
@@ -446,7 +462,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
446462
if (p->object.flags & SEEN)
447463
continue;
448464
p->object.flags |= SEEN;
449-
insert_by_date(p, list);
465+
insert_by_date_cached(p, list, cached_base, cache_ptr);
450466
}
451467
return 0;
452468
}
@@ -471,7 +487,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
471487
p->object.flags |= left_flag;
472488
if (!(p->object.flags & SEEN)) {
473489
p->object.flags |= SEEN;
474-
insert_by_date(p, list);
490+
insert_by_date_cached(p, list, cached_base, cache_ptr);
475491
}
476492
if(revs->first_parent_only)
477493
break;
@@ -612,7 +628,7 @@ static int limit_list(struct rev_info *revs)
612628

613629
if (revs->max_age != -1 && (commit->date < revs->max_age))
614630
obj->flags |= UNINTERESTING;
615-
if (add_parents_to_list(revs, commit, &list) < 0)
631+
if (add_parents_to_list(revs, commit, &list, NULL) < 0)
616632
return -1;
617633
if (obj->flags & UNINTERESTING) {
618634
mark_parents_uninteresting(commit);
@@ -1415,10 +1431,12 @@ enum rewrite_result {
14151431

14161432
static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
14171433
{
1434+
struct commit_list *cache = NULL;
1435+
14181436
for (;;) {
14191437
struct commit *p = *pp;
14201438
if (!revs->limited)
1421-
if (add_parents_to_list(revs, p, &revs->commits) < 0)
1439+
if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0)
14221440
return rewrite_one_error;
14231441
if (p->parents && p->parents->next)
14241442
return rewrite_one_ok;
@@ -1542,7 +1560,7 @@ static struct commit *get_revision_1(struct rev_info *revs)
15421560
if (revs->max_age != -1 &&
15431561
(commit->date < revs->max_age))
15441562
continue;
1545-
if (add_parents_to_list(revs, commit, &revs->commits) < 0)
1563+
if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0)
15461564
return NULL;
15471565
}
15481566

0 commit comments

Comments
 (0)