Skip to content

Commit

Permalink
Make it possible to not clobber object.util in sort_in_topological_or…
Browse files Browse the repository at this point in the history
…der (take 2)

Signed-off-by: Fredrik Kuivinen <freku045@student.liu.se>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Fredrik Kuivinen authored and Junio C Hamano committed Mar 11, 2006
1 parent f2561fd commit 6b6dcfc
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
36 changes: 27 additions & 9 deletions commit.c
Expand Up @@ -569,10 +569,28 @@ int count_parents(struct commit * commit)
return count; return count;
} }


void topo_sort_default_setter(struct commit *c, void *data)
{
c->object.util = data;
}

void *topo_sort_default_getter(struct commit *c)
{
return c->object.util;
}

/* /*
* Performs an in-place topological sort on the list supplied. * Performs an in-place topological sort on the list supplied.
*/ */
void sort_in_topological_order(struct commit_list ** list, int lifo) void sort_in_topological_order(struct commit_list ** list, int lifo)
{
sort_in_topological_order_fn(list, lifo, topo_sort_default_setter,
topo_sort_default_getter);
}

void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
topo_sort_set_fn_t setter,
topo_sort_get_fn_t getter)
{ {
struct commit_list * next = *list; struct commit_list * next = *list;
struct commit_list * work = NULL, **insert; struct commit_list * work = NULL, **insert;
Expand All @@ -596,7 +614,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
next=*list; next=*list;
while (next) { while (next) {
next_nodes->list_item = next; next_nodes->list_item = next;
next->item->object.util = next_nodes; setter(next->item, next_nodes);
next_nodes++; next_nodes++;
next = next->next; next = next->next;
} }
Expand All @@ -606,8 +624,8 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
struct commit_list * parents = next->item->parents; struct commit_list * parents = next->item->parents;
while (parents) { while (parents) {
struct commit * parent=parents->item; struct commit * parent=parents->item;
struct sort_node * pn = (struct sort_node *)parent->object.util; struct sort_node * pn = (struct sort_node *) getter(parent);

if (pn) if (pn)
pn->indegree++; pn->indegree++;
parents=parents->next; parents=parents->next;
Expand All @@ -624,7 +642,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
next=*list; next=*list;
insert = &work; insert = &work;
while (next) { while (next) {
struct sort_node * node = (struct sort_node *)next->item->object.util; struct sort_node * node = (struct sort_node *) getter(next->item);


if (node->indegree == 0) { if (node->indegree == 0) {
insert = &commit_list_insert(next->item, insert)->next; insert = &commit_list_insert(next->item, insert)->next;
Expand All @@ -637,15 +655,15 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
sort_by_date(&work); sort_by_date(&work);
while (work) { while (work) {
struct commit * work_item = pop_commit(&work); struct commit * work_item = pop_commit(&work);
struct sort_node * work_node = (struct sort_node *)work_item->object.util; struct sort_node * work_node = (struct sort_node *) getter(work_item);
struct commit_list * parents = work_item->parents; struct commit_list * parents = work_item->parents;


while (parents) { while (parents) {
struct commit * parent=parents->item; struct commit * parent=parents->item;
struct sort_node * pn = (struct sort_node *)parent->object.util; struct sort_node * pn = (struct sort_node *) getter(parent);

if (pn) { if (pn) {
/* /*
* parents are only enqueued for emission * parents are only enqueued for emission
* when all their children have been emitted thereby * when all their children have been emitted thereby
* guaranteeing topological order. * guaranteeing topological order.
Expand All @@ -667,7 +685,7 @@ void sort_in_topological_order(struct commit_list ** list, int lifo)
*pptr = work_node->list_item; *pptr = work_node->list_item;
pptr = &(*pptr)->next; pptr = &(*pptr)->next;
*pptr = NULL; *pptr = NULL;
work_item->object.util = NULL; setter(work_item, NULL);
} }
free(nodes); free(nodes);
} }
20 changes: 17 additions & 3 deletions commit.h
Expand Up @@ -65,15 +65,29 @@ int count_parents(struct commit * commit);
/* /*
* Performs an in-place topological sort of list supplied. * Performs an in-place topological sort of list supplied.
* *
* Pre-conditions: * Pre-conditions for sort_in_topological_order:
* all commits in input list and all parents of those * all commits in input list and all parents of those
* commits must have object.util == NULL * commits must have object.util == NULL
* *
* Post-conditions: * Pre-conditions for sort_in_topological_order_fn:
* all commits in input list and all parents of those
* commits must have getter(commit) == NULL
*
* Post-conditions:
* invariant of resulting list is: * invariant of resulting list is:
* a reachable from b => ord(b) < ord(a) * a reachable from b => ord(b) < ord(a)
* in addition, when lifo == 0, commits on parallel tracks are * in addition, when lifo == 0, commits on parallel tracks are
* sorted in the dates order. * sorted in the dates order.
*/ */

typedef void (*topo_sort_set_fn_t)(struct commit*, void *data);
typedef void* (*topo_sort_get_fn_t)(struct commit*);

void topo_sort_default_setter(struct commit *c, void *data);
void *topo_sort_default_getter(struct commit *c);

void sort_in_topological_order(struct commit_list ** list, int lifo); void sort_in_topological_order(struct commit_list ** list, int lifo);
void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
topo_sort_set_fn_t setter,
topo_sort_get_fn_t getter);
#endif /* COMMIT_H */ #endif /* COMMIT_H */

0 comments on commit 6b6dcfc

Please sign in to comment.