Skip to content

Commit 855bfc5

Browse files
committed
Merge branch 'kk/limit-list-optim' into jch
The limit_list() function that is one of the core part of the revision traversal infrastructure has been optimized by replacing its use of linear list with priority queue. * kk/limit-list-optim: revision: use priority queue in limit_list()
2 parents 943b427 + ef8d51a commit 855bfc5

1 file changed

Lines changed: 21 additions & 17 deletions

File tree

revision.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,19 @@ static struct commit *handle_commit(struct rev_info *revs,
473473
die("%s is unknown object", name);
474474
}
475475

476-
static int everybody_uninteresting(struct commit_list *orig,
476+
static int everybody_uninteresting(struct prio_queue *orig,
477477
struct commit **interesting_cache)
478478
{
479-
struct commit_list *list = orig;
479+
size_t i;
480480

481481
if (*interesting_cache) {
482482
struct commit *commit = *interesting_cache;
483483
if (!(commit->object.flags & UNINTERESTING))
484484
return 0;
485485
}
486486

487-
while (list) {
488-
struct commit *commit = list->item;
489-
list = list->next;
487+
for (i = 0; i < orig->nr; i++) {
488+
struct commit *commit = orig->array[i].data;
490489
if (commit->object.flags & UNINTERESTING)
491490
continue;
492491

@@ -1300,20 +1299,17 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
13001299
/* How many extra uninteresting commits we want to see.. */
13011300
#define SLOP 5
13021301

1303-
static int still_interesting(struct commit_list *src, timestamp_t date, int slop,
1302+
static int still_interesting(struct prio_queue *src, timestamp_t date, int slop,
13041303
struct commit **interesting_cache)
13051304
{
13061305
/*
1307-
* No source list at all? We're definitely done..
1306+
* Since src is sorted by date, it is enough to peek at the
1307+
* first entry to compare dates. No entry at all means done.
13081308
*/
1309-
if (!src)
1309+
struct commit *commit = prio_queue_peek(src);
1310+
if (!commit)
13101311
return 0;
1311-
1312-
/*
1313-
* Does the destination list contain entries with a date
1314-
* before the source list? Definitely _not_ done.
1315-
*/
1316-
if (date <= src->item->date)
1312+
if (date <= commit->date)
13171313
return SLOP;
13181314

13191315
/*
@@ -1451,6 +1447,7 @@ static int limit_list(struct rev_info *revs)
14511447
struct commit_list *newlist = NULL;
14521448
struct commit_list **p = &newlist;
14531449
struct commit *interesting_cache = NULL;
1450+
struct prio_queue queue = { .compare = compare_commits_by_commit_date };
14541451

14551452
if (revs->ancestry_path_implicit_bottoms) {
14561453
collect_bottom_commits(original_list,
@@ -1461,18 +1458,25 @@ static int limit_list(struct rev_info *revs)
14611458

14621459
while (original_list) {
14631460
struct commit *commit = pop_commit(&original_list);
1461+
prio_queue_put(&queue, commit);
1462+
}
1463+
1464+
while (queue.nr) {
1465+
struct commit *commit = prio_queue_get(&queue);
14641466
struct object *obj = &commit->object;
14651467

14661468
if (commit == interesting_cache)
14671469
interesting_cache = NULL;
14681470

14691471
if (revs->max_age != -1 && (commit->date < revs->max_age))
14701472
obj->flags |= UNINTERESTING;
1471-
if (process_parents(revs, commit, &original_list, NULL) < 0)
1473+
if (process_parents(revs, commit, NULL, &queue) < 0) {
1474+
clear_prio_queue(&queue);
14721475
return -1;
1476+
}
14731477
if (obj->flags & UNINTERESTING) {
14741478
mark_parents_uninteresting(revs, commit);
1475-
slop = still_interesting(original_list, date, slop, &interesting_cache);
1479+
slop = still_interesting(&queue, date, slop, &interesting_cache);
14761480
if (slop)
14771481
continue;
14781482
break;
@@ -1509,7 +1513,7 @@ static int limit_list(struct rev_info *revs)
15091513
}
15101514
}
15111515

1512-
commit_list_free(original_list);
1516+
clear_prio_queue(&queue);
15131517
revs->commits = newlist;
15141518
return 0;
15151519
}

0 commit comments

Comments
 (0)