9
9
#include "gpg-interface.h"
10
10
#include "mergesort.h"
11
11
#include "commit-slab.h"
12
+ #include "prio-queue.h"
12
13
13
14
static struct commit_extra_header * read_commit_extra_header_lines (const char * buf , size_t len , const char * * );
14
15
@@ -509,21 +510,42 @@ struct commit *pop_commit(struct commit_list **stack)
509
510
/* count number of children that have not been emitted */
510
511
define_commit_slab (indegree_slab , int );
511
512
513
+ static int compare_commits_by_commit_date (const void * a_ , const void * b_ , void * unused )
514
+ {
515
+ const struct commit * a = a_ , * b = b_ ;
516
+ /* newer commits with larger date first */
517
+ if (a -> date < b -> date )
518
+ return 1 ;
519
+ else if (a -> date > b -> date )
520
+ return -1 ;
521
+ return 0 ;
522
+ }
523
+
512
524
/*
513
525
* Performs an in-place topological sort on the list supplied.
514
526
*/
515
- void sort_in_topological_order (struct commit_list * * list , enum rev_sort_order sort_order )
527
+ void sort_in_topological_order (struct commit_list * * list , enum rev_sort_order sort_order )
516
528
{
517
529
struct commit_list * next , * orig = * list ;
518
- struct commit_list * work , * * insert ;
519
530
struct commit_list * * pptr ;
520
531
struct indegree_slab indegree ;
532
+ struct prio_queue queue ;
533
+ struct commit * commit ;
521
534
522
535
if (!orig )
523
536
return ;
524
537
* list = NULL ;
525
538
526
539
init_indegree_slab (& indegree );
540
+ memset (& queue , '\0' , sizeof (queue ));
541
+ switch (sort_order ) {
542
+ default : /* REV_SORT_IN_GRAPH_ORDER */
543
+ queue .compare = NULL ;
544
+ break ;
545
+ case REV_SORT_BY_COMMIT_DATE :
546
+ queue .compare = compare_commits_by_commit_date ;
547
+ break ;
548
+ }
527
549
528
550
/* Mark them and clear the indegree */
529
551
for (next = orig ; next ; next = next -> next ) {
@@ -533,7 +555,7 @@ void sort_in_topological_order(struct commit_list ** list, enum rev_sort_order s
533
555
534
556
/* update the indegree */
535
557
for (next = orig ; next ; next = next -> next ) {
536
- struct commit_list * parents = next -> item -> parents ;
558
+ struct commit_list * parents = next -> item -> parents ;
537
559
while (parents ) {
538
560
struct commit * parent = parents -> item ;
539
561
int * pi = indegree_slab_at (& indegree , parent );
@@ -551,30 +573,28 @@ void sort_in_topological_order(struct commit_list ** list, enum rev_sort_order s
551
573
*
552
574
* the tips serve as a starting set for the work queue.
553
575
*/
554
- work = NULL ;
555
- insert = & work ;
556
576
for (next = orig ; next ; next = next -> next ) {
557
577
struct commit * commit = next -> item ;
558
578
559
579
if (* (indegree_slab_at (& indegree , commit )) == 1 )
560
- insert = & commit_list_insert ( commit , insert ) -> next ;
580
+ prio_queue_put ( & queue , commit ) ;
561
581
}
562
582
563
- /* process the list in topological order */
564
- if (sort_order != REV_SORT_IN_GRAPH_ORDER )
565
- commit_list_sort_by_date (& work );
583
+ /*
584
+ * This is unfortunate; the initial tips need to be shown
585
+ * in the order given from the revision traversal machinery.
586
+ */
587
+ if (sort_order == REV_SORT_IN_GRAPH_ORDER )
588
+ prio_queue_reverse (& queue );
589
+
590
+ /* We no longer need the commit list */
591
+ free_commit_list (orig );
566
592
567
593
pptr = list ;
568
594
* list = NULL ;
569
- while (work ) {
570
- struct commit * commit ;
571
- struct commit_list * parents , * work_item ;
572
-
573
- work_item = work ;
574
- work = work_item -> next ;
575
- work_item -> next = NULL ;
595
+ while ((commit = prio_queue_get (& queue )) != NULL ) {
596
+ struct commit_list * parents ;
576
597
577
- commit = work_item -> item ;
578
598
for (parents = commit -> parents ; parents ; parents = parents -> next ) {
579
599
struct commit * parent = parents -> item ;
580
600
int * pi = indegree_slab_at (& indegree , parent );
@@ -587,27 +607,20 @@ void sort_in_topological_order(struct commit_list ** list, enum rev_sort_order s
587
607
* when all their children have been emitted thereby
588
608
* guaranteeing topological order.
589
609
*/
590
- if (-- (* pi ) == 1 ) {
591
- switch (sort_order ) {
592
- case REV_SORT_BY_COMMIT_DATE :
593
- commit_list_insert_by_date (parent , & work );
594
- break ;
595
- default : /* REV_SORT_IN_GRAPH_ORDER */
596
- commit_list_insert (parent , & work );
597
- break ;
598
- }
599
- }
610
+ if (-- (* pi ) == 1 )
611
+ prio_queue_put (& queue , parent );
600
612
}
601
613
/*
602
- * work_item is a commit all of whose children
603
- * have already been emitted. we can emit it now.
614
+ * all children of commit have already been
615
+ * emitted. we can emit it now.
604
616
*/
605
617
* (indegree_slab_at (& indegree , commit )) = 0 ;
606
- * pptr = work_item ;
607
- pptr = & work_item -> next ;
618
+
619
+ pptr = & commit_list_insert ( commit , pptr ) -> next ;
608
620
}
609
621
610
622
clear_indegree_slab (& indegree );
623
+ clear_prio_queue (& queue );
611
624
}
612
625
613
626
/* merge-base stuff */
0 commit comments