From 8255c69b102d3a1766fc081590618440ae5a58f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sat, 24 Sep 2011 17:06:52 +0200 Subject: [PATCH] Make use of the tree cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/tree.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) 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;