Commit 5e15176dac8b0baa6f7950f5f763608c83b29093

Vicent Marti 2010-05-23T02:39:57

Add commit caching on the commit table. Properly initialize the pending commits list. Signed-off-by: Vicent Marti <tanoku@gmail.com> Signed-off-by: Andreas Ericsson <ae@op5.se>

diff --git a/src/commit.c b/src/commit.c
index 226eca4..1763ca8 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 7c25137..2ed6345 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 8ea17a2..8ec696a 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 cbf7144..b24cf42 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 ae692bf..14599df 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__ */