#include "notes.h"
#include "gpg-interface.h"
#include "mergesort.h"
+#include "commit-slab.h"
static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
return item;
}
-struct commit_slab {
- int *buf;
- int alloc;
-};
-
-static void slab_init(struct commit_slab *s)
-{
- memset(s, 0, sizeof(*s));
-}
-
-static void slab_clear(struct commit_slab *s)
-{
- free(s->buf);
- slab_init(s);
-}
+/*
+ * Topological sort support
+ */
-static inline int *slab_at(struct commit_slab *s, const struct commit *c)
-{
- if (s->alloc <= c->index) {
- int new_alloc = alloc_nr(s->alloc);
- if (new_alloc <= c->index)
- new_alloc = c->index + 1;
-
- s->buf = xrealloc(s->buf, new_alloc * sizeof(*s->buf));
- memset(s->buf + s->alloc, 0, new_alloc - s->alloc);
- s->alloc = new_alloc;
- }
- return s->buf + c->index;
-}
+/* count number of children that have not been emitted */
+define_commit_slab(indegree_slab, int);
/*
* 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, enum rev_sort_order sort_order)
{
struct commit_list *next, *orig = *list;
struct commit_list *work, **insert;
struct commit_list **pptr;
- struct commit_slab indegree;
+ struct indegree_slab indegree;
if (!orig)
return;
*list = NULL;
- slab_init(&indegree);
+ init_indegree_slab(&indegree);
/* Mark them and clear the indegree */
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
- *slab_at(&indegree, commit) = 1;
+ *(indegree_slab_at(&indegree, commit)) = 1;
}
/* update the indegree */
struct commit_list * parents = next->item->parents;
while (parents) {
struct commit *parent = parents->item;
- int *pi = slab_at(&indegree, parent);
+ int *pi = indegree_slab_at(&indegree, parent);
if (*pi)
(*pi)++;
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
- if (*slab_at(&indegree, commit) == 1)
+ if (*(indegree_slab_at(&indegree, commit)) == 1)
insert = &commit_list_insert(commit, insert)->next;
}
/* process the list in topological order */
- if (!lifo)
+ if (sort_order != REV_SORT_IN_GRAPH_ORDER)
commit_list_sort_by_date(&work);
pptr = list;
commit = work_item->item;
for (parents = commit->parents; parents ; parents = parents->next) {
struct commit *parent = parents->item;
- int *pi = slab_at(&indegree, parent);
+ int *pi = indegree_slab_at(&indegree, parent);
if (!*pi)
continue;
* guaranteeing topological order.
*/
if (--(*pi) == 1) {
- if (!lifo)
+ switch (sort_order) {
+ case REV_SORT_BY_COMMIT_DATE:
commit_list_insert_by_date(parent, &work);
- else
+ break;
+ default: /* REV_SORT_IN_GRAPH_ORDER */
commit_list_insert(parent, &work);
+ break;
+ }
}
}
/*
* work_item is a commit all of whose children
* have already been emitted. we can emit it now.
*/
- *slab_at(&indegree, commit) = 0;
+ *(indegree_slab_at(&indegree, commit)) = 0;
*pptr = work_item;
pptr = &work_item->next;
}
- slab_clear(&indegree);
+ clear_indegree_slab(&indegree);
}
/* merge-base stuff */