Commit 36b7cdb6 by Vicent Marti Committed by Andreas Ericsson

Changed 'git_commit_list' from a linked list to a doubly-linked list.

Changed 'git_commit' to use bit fields instead of flags.

Signed-off-by: Vicent Marti <tanoku@gmail.com>
Signed-off-by: Andreas Ericsson <ae@op5.se>
parent 89039682
...@@ -40,12 +40,13 @@ void git_commit__mark_uninteresting(git_commit *commit) ...@@ -40,12 +40,13 @@ void git_commit__mark_uninteresting(git_commit *commit)
if (commit == NULL) if (commit == NULL)
return; return;
git_commit_list *parents = commit->parents; git_commit_node *parents = commit->parents.head;
commit->flags |= GIT_COMMIT_HIDE; commit->uninteresting = 1;
while (parents) { while (parents)
parents->commit->flags |= GIT_COMMIT_HIDE; {
parents->commit->uninteresting = 1;
parents = parents->next; parents = parents->next;
} }
} }
...@@ -185,10 +186,10 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len) ...@@ -185,10 +186,10 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len)
return -1; return -1;
// Inherit uninteresting flag // Inherit uninteresting flag
if (commit->flags & GIT_COMMIT_HIDE) if (commit->uninteresting)
parent->flags |= GIT_COMMIT_HIDE; parent->uninteresting = 1;
git_commit_list_insert(&commit->parents, parent); git_commit_list_append(&commit->parents, parent);
} }
if (git_commit__parse_time(&commit->commit_time, buffer, buffer_end) < 0) if (git_commit__parse_time(&commit->commit_time, buffer, buffer_end) < 0)
...@@ -199,30 +200,90 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len) ...@@ -199,30 +200,90 @@ int git_commit__parse_buffer(git_commit *commit, void *data, size_t len)
return 0; return 0;
} }
void git_commit_list_insert(git_commit_list **list, git_commit *commit) void git_commit_list_append(git_commit_list *list, git_commit *commit)
{ {
if (*list == NULL) git_commit_node *node = NULL;
{
*list = git__malloc(sizeof(git_commit_list)); node = git__malloc(sizeof(git_commit_list));
if (node == NULL)
return;
if (*list == NULL) node->commit = commit;
return; node->next = NULL;
node->prev = list->tail;
(*list)->commit = commit; if (list->tail == NULL)
(*list)->next = NULL; {
list->head = list->tail = node;
} }
else else
{ {
git_commit_list *new_list = NULL; list->tail->next = node;
list->tail = node;
}
list->size++;
}
git_commit *git_commit_list_pop_back(git_commit_list *list)
{
git_commit_node *node;
git_commit *commit;
if (list->tail == NULL)
return NULL;
node = list->tail;
list->tail = list->tail->prev;
if (list->tail == NULL)
list->head = NULL;
commit = node->commit;
free(node);
list->size--;
new_list = git__malloc(sizeof(git_commit_list)); return commit;
}
git_commit *git_commit_list_pop_front(git_commit_list *list)
{
git_commit_node *node;
git_commit *commit;
if (list->head == NULL)
return NULL;
node = list->head;
list->head = list->head->next;
if (list->head == NULL)
list->tail = NULL;
commit = node->commit;
free(node);
if (new_list == NULL) list->size--;
return;
new_list->commit = commit; return commit;
new_list->next = *list; }
void git_commit_list_clear(git_commit_list *list, int free_commits)
{
git_commit_node *node, *next_node;
*list = new_list; node = list->head;
while (node)
{
if (free_commits)
free(node->commit);
next_node = node->next;
free(node);
node = next_node;
} }
list->head = list->tail = NULL;
list->size = 0;
} }
...@@ -5,24 +5,33 @@ ...@@ -5,24 +5,33 @@
#include <time.h> #include <time.h>
#define GIT_COMMIT_SEEN (1 << 0) struct git_commit_node {
#define GIT_COMMIT_HIDE (1 << 1) struct git_commit *commit;
#define GIT_COMMIT_DELAY (1 << 2)
struct git_commit_node *next;
struct git_commit_node *prev;
};
struct git_commit_list { struct git_commit_list {
struct git_commit *commit; struct git_commit_node *head;
struct git_commit_list *next; struct git_commit_node *tail;
size_t size;
}; };
typedef struct git_commit_list git_commit_list; typedef struct git_commit_list git_commit_list;
typedef struct git_commit_node git_commit_node;
struct git_commit { struct git_commit {
git_oid id; git_oid id;
time_t commit_time; time_t commit_time;
git_revpool *pool; git_revpool *pool;
git_commit_list *parents; git_commit_list parents;
unsigned short in_degree;
unsigned parsed:1, unsigned parsed:1,
seen:1,
uninteresting:1,
topo_delay:1,
flags:26; flags:26;
}; };
...@@ -33,6 +42,9 @@ void git_commit__mark_uninteresting(git_commit *commit); ...@@ -33,6 +42,9 @@ void git_commit__mark_uninteresting(git_commit *commit);
int git_commit_parse_existing(git_commit *commit); int git_commit_parse_existing(git_commit *commit);
void git_commit_list_insert(git_commit_list **list, git_commit *commit); void git_commit_list_clear(git_commit_list *list, int free_commits);
void git_commit_list_append(git_commit_list *list, git_commit *commit);
git_commit *git_commit_list_pop_back(git_commit_list *list);
git_commit *git_commit_list_pop_front(git_commit_list *list);
#endif #endif
...@@ -41,17 +41,8 @@ git_revpool *gitrp_alloc(git_odb *db) ...@@ -41,17 +41,8 @@ git_revpool *gitrp_alloc(git_odb *db)
void gitrp_free(git_revpool *walk) void gitrp_free(git_revpool *walk)
{ {
git_commit_list *list; git_commit_list_clear(&(walk->iterator), 0);
git_commit_list_clear(&(walk->roots), 1);
list = walk->roots;
while (list)
{
free(list->commit);
free(list);
list = list->next;
}
free(walk); free(walk);
} }
...@@ -60,7 +51,7 @@ void gitrp_push(git_revpool *pool, git_commit *commit) ...@@ -60,7 +51,7 @@ void gitrp_push(git_revpool *pool, git_commit *commit)
if (commit->pool != pool) if (commit->pool != pool)
return; return;
if ((commit->flags & GIT_COMMIT_SEEN) != 0) if (commit->seen)
return; return;
if (!commit->parsed) if (!commit->parsed)
...@@ -72,30 +63,30 @@ void gitrp_push(git_revpool *pool, git_commit *commit) ...@@ -72,30 +63,30 @@ void gitrp_push(git_revpool *pool, git_commit *commit)
// Sanity check: make sure that if the commit // Sanity check: make sure that if the commit
// has been manually marked as uninteresting, // has been manually marked as uninteresting,
// all the parent commits are too. // all the parent commits are too.
if ((commit->flags & GIT_COMMIT_HIDE) != 0) if (commit->uninteresting)
git_commit__mark_uninteresting(commit); git_commit__mark_uninteresting(commit);
commit->flags |= GIT_COMMIT_SEEN; commit->seen = 1;
git_commit_list_insert(&pool->roots, commit); git_commit_list_append(&pool->roots, commit);
git_commit_list_insert(&pool->iterator, commit); git_commit_list_append(&pool->iterator, commit);
} }
void gitrp_hide(git_revpool *pool, git_commit *commit) void gitrp_hide(git_revpool *pool, git_commit *commit)
{ {
git_commit_mark_uninteresting(commit); git_commit__mark_uninteresting(commit);
gitrp_push(pool, commit); gitrp_push(pool, commit);
} }
void gitrp_prepare_walk(git_revpool *pool) void gitrp_prepare_walk(git_revpool *pool)
{ {
git_commit_list *list; git_commit_node *roots;
list = pool->roots; roots = pool->roots.head;
while (list) while (roots)
{ {
git_commit_list_insert(&pool->iterator, list->commit); git_commit_list_append(&pool->iterator, roots->commit);
list = list->next; roots = roots->next;
} }
pool->walking = 1; pool->walking = 1;
...@@ -108,30 +99,26 @@ git_commit *gitrp_next(git_revpool *pool) ...@@ -108,30 +99,26 @@ git_commit *gitrp_next(git_revpool *pool)
if (!pool->walking) if (!pool->walking)
gitrp_prepare_walk(pool); gitrp_prepare_walk(pool);
while (pool->iterator != NULL) while ((next = git_commit_list_pop_front(&pool->iterator)) != NULL)
{ {
git_commit_list *list; git_commit_node *parents;
next = pool->iterator->commit;
free(pool->iterator);
pool->iterator = pool->iterator->next;
list = next->parents; parents = next->parents.head;
while (list) while (parents)
{ {
git_commit *parent = list->commit; git_commit *parent = parents->commit;
list = list->next; parents = parents->next;
if ((parent->flags & GIT_COMMIT_SEEN) != 0) if (parent->seen)
continue; continue;
if (parent->parsed == 0) if (parent->parsed == 0)
git_commit_parse_existing(parent); git_commit_parse_existing(parent);
git_commit_list_insert(&pool->iterator, list->commit); git_commit_list_append(&pool->iterator, parent);
} }
if ((next->flags & GIT_COMMIT_HIDE) != 0) if (next->uninteresting == 0)
return next; return next;
} }
...@@ -142,6 +129,7 @@ git_commit *gitrp_next(git_revpool *pool) ...@@ -142,6 +129,7 @@ git_commit *gitrp_next(git_revpool *pool)
void gitrp_reset(git_revpool *pool) void gitrp_reset(git_revpool *pool)
{ {
pool->iterator = NULL; git_commit_list_clear(&pool->iterator, 0);
pool->walking = 0; pool->walking = 0;
} }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
struct git_revpool { struct git_revpool {
git_odb *db; git_odb *db;
git_commit_list *iterator; git_commit_list iterator;
git_commit_list *roots; git_commit_list roots;
unsigned walking:1, unsigned walking:1,
topological_sort:1; topological_sort:1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment