Skip to content

Commit 1e040c0

Browse files
committed
Merge branch 'ag/rewrite_one' into maint
* ag/rewrite_one: Fix quadratic performance in rewrite_one.
2 parents fd35e42 + fce87ae commit 1e040c0

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
@@ -412,10 +412,26 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
412412
commit->object.flags |= TREESAME;
413413
}
414414

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

420436
if (commit->object.flags & ADDED)
421437
return 0;
@@ -445,7 +461,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
445461
if (p->object.flags & SEEN)
446462
continue;
447463
p->object.flags |= SEEN;
448-
insert_by_date(p, list);
464+
insert_by_date_cached(p, list, cached_base, cache_ptr);
449465
}
450466
return 0;
451467
}
@@ -470,7 +486,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
470486
p->object.flags |= left_flag;
471487
if (!(p->object.flags & SEEN)) {
472488
p->object.flags |= SEEN;
473-
insert_by_date(p, list);
489+
insert_by_date_cached(p, list, cached_base, cache_ptr);
474490
}
475491
if(revs->first_parent_only)
476492
break;
@@ -611,7 +627,7 @@ static int limit_list(struct rev_info *revs)
611627

612628
if (revs->max_age != -1 && (commit->date < revs->max_age))
613629
obj->flags |= UNINTERESTING;
614-
if (add_parents_to_list(revs, commit, &list) < 0)
630+
if (add_parents_to_list(revs, commit, &list, NULL) < 0)
615631
return -1;
616632
if (obj->flags & UNINTERESTING) {
617633
mark_parents_uninteresting(commit);
@@ -1458,10 +1474,12 @@ enum rewrite_result {
14581474

14591475
static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
14601476
{
1477+
struct commit_list *cache = NULL;
1478+
14611479
for (;;) {
14621480
struct commit *p = *pp;
14631481
if (!revs->limited)
1464-
if (add_parents_to_list(revs, p, &revs->commits) < 0)
1482+
if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0)
14651483
return rewrite_one_error;
14661484
if (p->parents && p->parents->next)
14671485
return rewrite_one_ok;
@@ -1580,7 +1598,7 @@ static struct commit *get_revision_1(struct rev_info *revs)
15801598
if (revs->max_age != -1 &&
15811599
(commit->date < revs->max_age))
15821600
continue;
1583-
if (add_parents_to_list(revs, commit, &revs->commits) < 0)
1601+
if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0)
15841602
return NULL;
15851603
}
15861604

0 commit comments

Comments
 (0)