99#include "gpg-interface.h"
1010#include "mergesort.h"
1111#include "commit-slab.h"
12+ #include "prio-queue.h"
1213
1314static struct commit_extra_header * read_commit_extra_header_lines (const char * buf , size_t len , const char * * );
1415
@@ -509,21 +510,42 @@ struct commit *pop_commit(struct commit_list **stack)
509510/* count number of children that have not been emitted */
510511define_commit_slab (indegree_slab , int );
511512
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+
512524/*
513525 * Performs an in-place topological sort on the list supplied.
514526 */
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 )
516528{
517529 struct commit_list * next , * orig = * list ;
518- struct commit_list * work , * * insert ;
519530 struct commit_list * * pptr ;
520531 struct indegree_slab indegree ;
532+ struct prio_queue queue ;
533+ struct commit * commit ;
521534
522535 if (!orig )
523536 return ;
524537 * list = NULL ;
525538
526539 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+ }
527549
528550 /* Mark them and clear the indegree */
529551 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
533555
534556 /* update the indegree */
535557 for (next = orig ; next ; next = next -> next ) {
536- struct commit_list * parents = next -> item -> parents ;
558+ struct commit_list * parents = next -> item -> parents ;
537559 while (parents ) {
538560 struct commit * parent = parents -> item ;
539561 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
551573 *
552574 * the tips serve as a starting set for the work queue.
553575 */
554- work = NULL ;
555- insert = & work ;
556576 for (next = orig ; next ; next = next -> next ) {
557577 struct commit * commit = next -> item ;
558578
559579 if (* (indegree_slab_at (& indegree , commit )) == 1 )
560- insert = & commit_list_insert ( commit , insert ) -> next ;
580+ prio_queue_put ( & queue , commit ) ;
561581 }
562582
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 );
566592
567593 pptr = list ;
568594 * 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 ;
576597
577- commit = work_item -> item ;
578598 for (parents = commit -> parents ; parents ; parents = parents -> next ) {
579599 struct commit * parent = parents -> item ;
580600 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
587607 * when all their children have been emitted thereby
588608 * guaranteeing topological order.
589609 */
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 );
600612 }
601613 /*
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.
604616 */
605617 * (indegree_slab_at (& indegree , commit )) = 0 ;
606- * pptr = work_item ;
607- pptr = & work_item -> next ;
618+
619+ pptr = & commit_list_insert ( commit , pptr ) -> next ;
608620 }
609621
610622 clear_indegree_slab (& indegree );
623+ clear_prio_queue (& queue );
611624}
612625
613626/* merge-base stuff */
0 commit comments