path: root/split-index.c
diff options
authorJameson Miller <>2018-07-02 19:49:31 (GMT)
committerJunio C Hamano <>2018-07-03 17:58:27 (GMT)
commita849735bfbf159b98ead9ef4c843dc8acfd372f0 (patch)
tree87f3feb6196924ee4522e076eedaff9037efafd2 /split-index.c
parent825ed4d9a044380ac093563e6bd74311ea4488ef (diff)
block alloc: add lifecycle APIs for cache_entry structs
It has been observed that the time spent loading an index with a large number of entries is partly dominated by malloc() calls. This change is in preparation for using memory pools to reduce the number of malloc() calls made to allocate cahce entries when loading an index. Add an API to allocate and discard cache entries, abstracting the details of managing the memory backing the cache entries. This commit does actually change how memory is managed - this will be done in a later commit in the series. This change makes the distinction between cache entries that are associated with an index and cache entries that are not associated with an index. A main use of cache entries is with an index, and we can optimize the memory management around this. We still have other cases where a cache entry is not persisted with an index, and so we need to handle the "transient" use case as well. To keep the congnitive overhead of managing the cache entries, there will only be a single discard function. This means there must be enough information kept with the cache entry so that we know how to discard them. A summary of the main functions in the API is: make_cache_entry: create cache entry for use in an index. Uses specified parameters to populate cache_entry fields. make_empty_cache_entry: Create an empty cache entry for use in an index. Returns cache entry with empty fields. make_transient_cache_entry: create cache entry that is not used in an index. Uses specified parameters to populate cache_entry fields. make_empty_transient_cache_entry: create cache entry that is not used in an index. Returns cache entry with empty fields. discard_cache_entry: A single function that knows how to discard a cache entry regardless of how it was allocated. Signed-off-by: Jameson Miller <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'split-index.c')
1 files changed, 4 insertions, 4 deletions
diff --git a/split-index.c b/split-index.c
index 660c75f..317900d 100644
--- a/split-index.c
+++ b/split-index.c
@@ -123,7 +123,7 @@ static void replace_entry(size_t pos, void *data)
src->ce_flags |= CE_UPDATE_IN_BASE;
src->ce_namelen = dst->ce_namelen;
copy_cache_entry(dst, src);
- free(src);
+ discard_cache_entry(src);
@@ -224,7 +224,7 @@ void prepare_to_write_split_index(struct index_state *istate)
base->ce_flags = base_flags;
if (ret)
ce->ce_flags |= CE_UPDATE_IN_BASE;
- free(base);
+ discard_cache_entry(base);
si->base->cache[ce->index - 1] = ce;
for (i = 0; i < si->base->cache_nr; i++) {
@@ -301,7 +301,7 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce
ce == istate->split_index->base->cache[ce->index - 1])
ce->ce_flags |= CE_REMOVE;
- free(ce);
+ discard_cache_entry(ce);
void replace_index_entry_in_base(struct index_state *istate,
@@ -314,7 +314,7 @@ void replace_index_entry_in_base(struct index_state *istate,
old_entry->index <= istate->split_index->base->cache_nr) {
new_entry->index = old_entry->index;
if (old_entry != istate->split_index->base->cache[new_entry->index - 1])
- free(istate->split_index->base->cache[new_entry->index - 1]);
+ discard_cache_entry(istate->split_index->base->cache[new_entry->index - 1]);
istate->split_index->base->cache[new_entry->index - 1] = new_entry;