summaryrefslogtreecommitdiff
path: root/src/tree.c
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlos@cmartin.tk>2011-09-24 17:06:52 +0200
committerVicent Marti <tanoku@gmail.com>2011-09-27 14:33:18 +0200
commit8255c69b102d3a1766fc081590618440ae5a58f8 (patch)
tree555797fffc7986d5322a294216b628462bc02a68 /src/tree.c
parent3ba69ba8a469deee81ab718ecc04551c17b9615d (diff)
downloadlibgit2-8255c69b102d3a1766fc081590618440ae5a58f8.tar.gz
Make use of the tree cache
Taking advantage of the tree cache, git_tree_create_fromindex becomes comparable in speed to git write-tree when the cache is available. Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
Diffstat (limited to 'src/tree.c')
-rw-r--r--src/tree.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/tree.c b/src/tree.c
index 2f9ae2ef1..6ad7139e5 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -204,12 +204,37 @@ int git_tree__parse(git_tree *tree, git_odb_object *obj)
return tree_parse_buffer(tree, (char *)obj->raw.data, (char *)obj->raw.data + obj->raw.len);
}
+static unsigned int find_next_dir(const char *dirname, git_index *index, unsigned int start)
+{
+ unsigned int i, entries = git_index_entrycount(index);
+ size_t dirlen;
+
+ dirlen = strlen(dirname);
+ for (i = start; i < entries; ++i) {
+ git_index_entry *entry = git_index_get(index, i);
+ if (strlen(entry->path) < dirlen ||
+ memcmp(entry->path, dirname, dirlen) ||
+ (dirlen > 0 && entry->path[dirlen] != '/')) {
+ break;
+ }
+ }
+
+ return i;
+}
+
static int write_tree(git_oid *oid, git_index *index, const char *dirname, unsigned int start)
{
git_treebuilder *bld = NULL;
unsigned int i, entries = git_index_entrycount(index);
int error;
size_t dirname_len = strlen(dirname);
+ const git_tree_cache *cache;
+
+ cache = git_tree_cache_get(index->tree, dirname);
+ if (cache != NULL && cache->entries >= 0){
+ git_oid_cpy(oid, &cache->oid);
+ return find_next_dir(dirname, index, start);
+ }
error = git_treebuilder_create(&bld, NULL);
if (bld == NULL) {
@@ -308,6 +333,11 @@ int git_tree_create_fromindex(git_oid *oid, git_index *index)
if (index->repository == NULL)
return git__throw(GIT_EBAREINDEX, "Failed to create tree. The index file is not backed up by an existing repository");
+ if (index->tree != NULL && index->tree->entries >= 0) {
+ git_oid_cpy(oid, &index->tree->oid);
+ return GIT_SUCCESS;
+ }
+
/* The tree cache didn't help us */
error = write_tree(oid, index, "", 0);
return (error < GIT_SUCCESS) ? git__rethrow(error, "Failed to create tree") : GIT_SUCCESS;