logo       

[PATCH 1/1] Add a topological sort procedure to commit.c: msg#01106

Subject: [PATCH 1/1] Add a topological sort procedure to commit.c
This patch introduces an in-place topological sort procedure to commit.c

Given a list of commits, sort_in_topological_order() will perform an in-place
topological sort of that list.

The invariant that applies to the resulting list is:

        a reachable from b => ord(b) < ord(a)

This invariant is weaker than the --merge-order invariant, but is cheaper
to calculate (assuming the list has been identified) and will serve any
purpose where only a minimal topological order guarantee is required.

Signed-off-by: Jon Seymour <jon.seymour@xxxxxxxxx>
---
Note: this patch currently has no observable consequences since nothing
in this patch calls it. A future patch will use this algorithm to provide
an O(n) bisection algorithm as a suggested replacement for the
existing O(n^2) bisection algorithm.
---

 commit.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 commit.h |    5 ++++
 2 files changed, 87 insertions(+), 0 deletions(-)

9beb76a20443b8d5ee6010bf0bd55344e5b39546
diff --git a/commit.c b/commit.c
--- a/commit.c
+++ b/commit.c
@@ -3,6 +3,12 @@
 #include "commit.h"
 #include "cache.h"
 
+struct sort_node
+{
+       unsigned int indegree;
+       struct commit_list * list_item;
+};
+
 const char *commit_type = "commit";
 
 enum cmit_fmt get_commit_format(const char *arg)
@@ -346,3 +352,79 @@ int count_parents(struct commit * commit
         return count;
 }
 
+/*
+ * Performs an in-place topological sort on the list supplied
+ */
+void sort_in_topological_order(struct commit_list ** list)
+{
+       struct commit_list * next = *list;
+       struct commit_list * work = NULL;
+       struct commit_list ** pptr = list;
+       struct sort_node * nodes;
+       struct sort_node * next_nodes;
+       int count = 0;
+
+       /* determine the size of the list */
+       while (next) {
+               next = next->next;
+               count++;
+       }
+       /* allocate an array to help sort the list */
+       nodes = xmalloc(sizeof(*nodes) * count);
+       /* link the list to the array */
+       next_nodes = nodes;
+       next=*list;
+       while (next) {
+               next_nodes->list_item = next;
+               next->item->object.util = next_nodes;
+               next_nodes++;
+               next = next->next;
+       }
+       /* update the indegree */
+       next=*list;
+       while (next) {
+               struct commit_list * parents = next->item->parents;
+               while (parents) {
+                       struct commit * parent=parents->item;
+                       struct sort_node * pn = (struct sort_node 
*)parent->object.util;
+                       
+                       if (pn)
+                               pn->indegree++;
+                       parents=parents->next;
+               }
+               next=next->next;
+       }
+       /* find the roots */
+       next=*list;
+       while (next) {
+               struct sort_node * node = (struct sort_node 
*)next->item->object.util;
+
+               if (node->indegree == 0) {
+                       commit_list_insert(next->item, &work);
+               }
+               next=next->next;
+       }
+       /* process the list in topological order */
+       while (work) {
+               struct commit * work_item = pop_commit(&work);
+               struct sort_node * work_node = (struct sort_node 
*)work_item->object.util;
+               struct commit_list * parents = work_item->parents;
+
+               while (parents) {
+                       struct commit * parent=parents->item;
+                       struct sort_node * pn = (struct sort_node 
*)parent->object.util;
+                       
+                       if (pn) {
+                               pn->indegree--;
+                               if (!pn->indegree) 
+                                       commit_list_insert(parent, &work);
+                       }
+                       parents=parents->next;
+               }
+               *pptr = work_node->list_item;
+               work_node->list_item->next = NULL;
+               pptr = &(*pptr)->next;
+               work_item->object.util = NULL;
+       }
+       free(nodes);
+}
diff --git a/commit.h b/commit.h
--- a/commit.h
+++ b/commit.h
@@ -55,4 +55,9 @@ struct commit *pop_most_recent_commit(st
 struct commit *pop_commit(struct commit_list **stack);
 
 int count_parents(struct commit * commit);
+
+/*
+ * Performs an in-place topological sort of list supplied.
+ */
+void sort_in_topological_order(struct commit_list ** list);
 #endif /* COMMIT_H */
------------


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
boot-loaders.gr...    php.pear.genera...    debugging.valgr...    kde.redhat.user...    text.xml.xsl.ge...    culture.languag...    hardware.microc...    java.servicemix...    redhat.release....    web.zope.plone....    user-groups.lin...    opendarwin.webk...    video.mjpeg.use...    sysutils.bcfg2....    encryption.gpg....    lx-office.devel...    xfree86.forum/2...    mail.mutt.devel...    acpi.devel/2003...    qnx.openqnx.dev...    network.irc.irs...    freebsd.devel.m...   
Home | blog view | USPTO Patent Archive | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe