summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commit.c6
-rw-r--r--src/revobject.c8
-rw-r--r--src/revobject.h1
-rw-r--r--src/revwalk.c58
-rw-r--r--src/revwalk.h13
5 files changed, 63 insertions, 23 deletions
diff --git a/src/commit.c b/src/commit.c
index 226eca421..1763ca88b 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -100,6 +100,10 @@ git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
if (pool == NULL || pool->db == NULL)
return NULL;
+ commit = (git_commit *)git_revpool_table_lookup(pool->commits, id);
+ if (commit != NULL)
+ return commit;
+
commit = git__malloc(sizeof(git_commit));
if (commit == NULL)
@@ -111,6 +115,8 @@ git_commit *git_commit_lookup(git_revpool *pool, const git_oid *id)
git_oid_cpy(&commit->object.id, id);
commit->object.pool = pool;
+ git_revpool_table_insert(pool->commits, (git_revpool_object *)commit);
+
return commit;
}
diff --git a/src/revobject.c b/src/revobject.c
index 7c2513775..2ed634540 100644
--- a/src/revobject.c
+++ b/src/revobject.c
@@ -33,7 +33,7 @@ unsigned int git_revpool_table__hash(const git_oid *id)
const unsigned int m = 0x5bd1e995;
const int r = 24;
- unsigned int h = 0xA8A3D5 ^ (unsigned int)id;
+ unsigned int h = 0xA8A3D5;
int i;
for (i = 0; i < GIT_OID_RAWSZ / 4; ++i)
@@ -165,3 +165,9 @@ void git_revpool_table_resize(git_revpool_table *table)
table->size_mask = (new_size - 1);
table->max_count = new_size * max_load_factor;
}
+
+
+void git_revpool_table_free(git_revpool_table *table)
+{
+
+}
diff --git a/src/revobject.h b/src/revobject.h
index 8ea17a2c5..8ec696a47 100644
--- a/src/revobject.h
+++ b/src/revobject.h
@@ -34,6 +34,7 @@ git_revpool_table *git_revpool_table_create(unsigned int min_size);
int git_revpool_table_insert(git_revpool_table *table, git_revpool_object *object);
git_revpool_object *git_revpool_table_lookup(git_revpool_table *table, const git_oid *id);
void git_revpool_table_resize(git_revpool_table *table);
+void git_revpool_table_free(git_revpool_table *table);
#endif
diff --git a/src/revwalk.c b/src/revwalk.c
index cbf7144d8..b24cf42e6 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -27,6 +27,8 @@
#include "commit.h"
#include "revwalk.h"
+static const int default_table_size = 32;
+
git_revpool *gitrp_alloc(git_odb *db)
{
git_revpool *walk = git__malloc(sizeof(*walk));
@@ -35,6 +37,8 @@ git_revpool *gitrp_alloc(git_odb *db)
memset(walk, 0x0, sizeof(git_revpool));
+ walk->commits = git_revpool_table_create(default_table_size);
+
walk->db = db;
return walk;
}
@@ -42,7 +46,10 @@ git_revpool *gitrp_alloc(git_odb *db)
void gitrp_free(git_revpool *walk)
{
git_commit_list_clear(&(walk->iterator), 0);
- git_commit_list_clear(&(walk->roots), 1);
+ git_commit_list_clear(&(walk->roots), 0);
+
+ git_revpool_table_free(walk->commits);
+
free(walk);
}
@@ -69,7 +76,6 @@ void gitrp_push(git_revpool *pool, git_commit *commit)
commit->seen = 1;
git_commit_list_append(&pool->roots, commit);
- git_commit_list_append(&pool->iterator, commit);
}
void gitrp_hide(git_revpool *pool, git_commit *commit)
@@ -80,30 +86,21 @@ void gitrp_hide(git_revpool *pool, git_commit *commit)
void gitrp_prepare_walk(git_revpool *pool)
{
- git_commit_node *roots;
+ git_commit_node *it;
- roots = pool->roots.head;
- while (roots)
+ for (it = pool->roots.head; it != NULL; it = it->next)
{
- git_commit_list_append(&pool->iterator, roots->commit);
- roots = roots->next;
+ git_commit_list_append(&pool->iterator, it->commit);
}
- pool->walking = 1;
-}
-
-git_commit *gitrp_next(git_revpool *pool)
-{
- git_commit *next;
-
- if (!pool->walking)
- gitrp_prepare_walk(pool);
-
- while ((next = git_commit_list_pop_front(&pool->iterator)) != NULL)
+ for (it = pool->iterator.head; it != NULL; it = it->next)
{
+ git_commit *commit;
git_commit_node *parents;
- parents = next->parents.head;
+ commit = it->commit;
+ parents = commit->parents.head;
+
while (parents)
{
git_commit *parent = parents->commit;
@@ -115,10 +112,31 @@ git_commit *gitrp_next(git_revpool *pool)
if (parent->parsed == 0)
git_commit_parse_existing(parent);
+ parent->seen = 1;
git_commit_list_append(&pool->iterator, parent);
}
+ }
+
+ // TODO: topo sort, time sort
+
+ if (pool->sorting & GIT_REVPOOL_SORT_REVERSE)
+ pool->next_commit = &git_commit_list_pop_back;
+ else
+ pool->next_commit = &git_commit_list_pop_front;
+
+ pool->walking = 1;
+}
+
+git_commit *gitrp_next(git_revpool *pool)
+{
+ git_commit *next;
- if (next->uninteresting == 0)
+ if (!pool->walking)
+ gitrp_prepare_walk(pool);
+
+ while ((next = pool->next_commit(&pool->iterator)) != NULL)
+ {
+ if (!next->uninteresting)
return next;
}
diff --git a/src/revwalk.h b/src/revwalk.h
index ae692bf0e..14599df10 100644
--- a/src/revwalk.h
+++ b/src/revwalk.h
@@ -4,13 +4,22 @@
#include "git/common.h"
#include "git/revwalk.h"
+#define GIT_REVPOOL_SORT_NONE (0)
+#define GIT_REVPOOL_SORT_TOPO (1 << 0)
+#define GIT_REVPOOL_SORT_TIME (1 << 1)
+#define GIT_REVPOOL_SORT_REVERSE (1 << 2)
+
struct git_revpool {
git_odb *db;
+
git_commit_list iterator;
+ git_commit *(*next_commit)(git_commit_list *);
+
git_commit_list roots;
+ git_revpool_table *commits;
- unsigned walking:1,
- topological_sort:1;
+ unsigned walking:1;
+ unsigned char sorting;
};
#endif /* INCLUDE_revwalk_h__ */