Commit bb0757d5 by Carlos Martín Nieto

tree-cache: correct the entry_count calculation

The entry_count field is the amount of index entries covered by a
particular cache entry, that is how many files are there (recursively)
under a particular directory.

The current code that attemps to do this is severely defincient and is
trying to count the amount of children, which always comes up to zero.

We don't even need to recount, since we have the information during the
cache creation. We can take that number and keep it, as we only ever
invalidate or replace.
parent 12e18031
...@@ -191,8 +191,10 @@ static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_ ...@@ -191,8 +191,10 @@ static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_
git_tree *subtree; git_tree *subtree;
entry = git_tree_entry_byindex(tree, i); entry = git_tree_entry_byindex(tree, i);
if (git_tree_entry_filemode(entry) != GIT_FILEMODE_TREE) if (git_tree_entry_filemode(entry) != GIT_FILEMODE_TREE) {
cache->entry_count++;
continue; continue;
}
if ((error = git_tree_cache_new(&cache->children[j], git_tree_entry_name(entry), pool)) < 0) if ((error = git_tree_cache_new(&cache->children[j], git_tree_entry_name(entry), pool)) < 0)
return error; return error;
...@@ -202,6 +204,7 @@ static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_ ...@@ -202,6 +204,7 @@ static int read_tree_recursive(git_tree_cache *cache, const git_tree *tree, git_
error = read_tree_recursive(cache->children[j], subtree, pool); error = read_tree_recursive(cache->children[j], subtree, pool);
git_tree_free(subtree); git_tree_free(subtree);
cache->entry_count += cache->children[j]->entry_count;
j++; j++;
if (error < 0) if (error < 0)
...@@ -245,35 +248,6 @@ int git_tree_cache_new(git_tree_cache **out, const char *name, git_pool *pool) ...@@ -245,35 +248,6 @@ int git_tree_cache_new(git_tree_cache **out, const char *name, git_pool *pool)
return 0; return 0;
} }
/**
* Recursively recalculate the total entry count, which we need to
* write out to the index
*/
static void recount_entries(git_tree_cache *tree)
{
size_t i;
ssize_t entry_count;
git_tree_cache *child;
for (i = 0; i < tree->children_count; i++)
recount_entries(tree->children[i]);
if (tree->entry_count == -1)
return;
entry_count = 0;
for (i = 0; i < tree->children_count; i++) {
child = tree->children[i];
if (child->entry_count == -1)
continue;
entry_count += tree->children[i]->children_count;
}
tree->entry_count = entry_count;
}
static void write_tree(git_buf *out, git_tree_cache *tree) static void write_tree(git_buf *out, git_tree_cache *tree)
{ {
size_t i; size_t i;
...@@ -289,7 +263,6 @@ static void write_tree(git_buf *out, git_tree_cache *tree) ...@@ -289,7 +263,6 @@ static void write_tree(git_buf *out, git_tree_cache *tree)
int git_tree_cache_write(git_buf *out, git_tree_cache *tree) int git_tree_cache_write(git_buf *out, git_tree_cache *tree)
{ {
recount_entries(tree);
write_tree(out, tree); write_tree(out, tree);
return git_buf_oom(out) ? -1 : 0; return git_buf_oom(out) ? -1 : 0;
......
...@@ -38,7 +38,7 @@ void test_index_cache__write_extension_at_root(void) ...@@ -38,7 +38,7 @@ void test_index_cache__write_extension_at_root(void)
cl_git_pass(git_index_open(&index, index_file)); cl_git_pass(git_index_open(&index, index_file));
cl_assert(index->tree); cl_assert(index->tree);
cl_assert_equal_i(0, index->tree->entry_count); cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count);
cl_assert_equal_i(0, index->tree->children_count); cl_assert_equal_i(0, index->tree->children_count);
cl_assert(git_oid_equal(&id, &index->tree->oid)); cl_assert(git_oid_equal(&id, &index->tree->oid));
...@@ -106,7 +106,7 @@ void test_index_cache__read_tree_no_children(void) ...@@ -106,7 +106,7 @@ void test_index_cache__read_tree_no_children(void)
cl_assert(index->tree); cl_assert(index->tree);
cl_assert(git_oid_equal(&id, &index->tree->oid)); cl_assert(git_oid_equal(&id, &index->tree->oid));
cl_assert_equal_i(0, index->tree->children_count); cl_assert_equal_i(0, index->tree->children_count);
cl_assert_equal_i(0, index->tree->entry_count); /* 0 is a placeholder here */ cl_assert_equal_i(git_index_entrycount(index), index->tree->entry_count);
memset(&entry, 0x0, sizeof(git_index_entry)); memset(&entry, 0x0, sizeof(git_index_entry));
entry.path = "new.txt"; entry.path = "new.txt";
...@@ -169,7 +169,7 @@ void test_index_cache__two_levels(void) ...@@ -169,7 +169,7 @@ void test_index_cache__two_levels(void)
cl_assert_equal_i(1, index->tree->children_count); cl_assert_equal_i(1, index->tree->children_count);
tree_cache = git_tree_cache_get(index->tree, "subdir"); tree_cache = git_tree_cache_get(index->tree, "subdir");
cl_assert(tree_cache); cl_assert(tree_cache);
cl_assert_equal_i(0, tree_cache->entry_count); cl_assert_equal_i(1, tree_cache->entry_count);
} }
void test_index_cache__read_tree_children(void) void test_index_cache__read_tree_children(void)
...@@ -226,11 +226,11 @@ void test_index_cache__read_tree_children(void) ...@@ -226,11 +226,11 @@ void test_index_cache__read_tree_children(void)
cache = git_tree_cache_get(index->tree, "subdir/even-deeper"); cache = git_tree_cache_get(index->tree, "subdir/even-deeper");
cl_assert(cache); cl_assert(cache);
cl_assert_equal_i(0, cache->entry_count); cl_assert_equal_i(1, cache->entry_count);
cache = git_tree_cache_get(index->tree, "subdir2"); cache = git_tree_cache_get(index->tree, "subdir2");
cl_assert(cache); cl_assert(cache);
cl_assert_equal_i(0, cache->entry_count); cl_assert_equal_i(1, cache->entry_count);
git_index_free(index); git_index_free(index);
} }
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