From c0f4a0118dd3821447512bf3b404be69c773eaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 19 Dec 2012 16:48:12 +0100 Subject: [PATCH 1/5] pack: introduce a delta base cache Many delta bases are re-used. Cache them to avoid inflating the same data repeatedly. This version doesn't limit the amount of entries to store, so it can end up using a considerable amound of memory. --- src/offmap.h | 65 +++++++++++++++++++++++++++++++++++ src/pack.c | 95 ++++++++++++++++++++++++++++++++++++++++++---------- src/pack.h | 11 ++++++ 3 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 src/offmap.h diff --git a/src/offmap.h b/src/offmap.h new file mode 100644 index 000000000..cd46fd687 --- /dev/null +++ b/src/offmap.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 the libgit2 contributors + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ +#ifndef INCLUDE_offmap_h__ +#define INCLUDE_offmap_h__ + +#include "common.h" +#include "git2/types.h" + +#define kmalloc git__malloc +#define kcalloc git__calloc +#define krealloc git__realloc +#define kfree git__free +#include "khash.h" + +__KHASH_TYPE(off, git_off_t, void *); +typedef khash_t(off) git_offmap; + +#define GIT__USE_OFFMAP \ + __KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal); + +#define git_offmap_alloc() kh_init(off) +#define git_offmap_free(h) kh_destroy(off, h), h = NULL +#define git_offmap_clear(h) kh_clear(off, h) + +#define git_offmap_num_entries(h) kh_size(h) + +#define git_offmap_lookup_index(h, k) kh_get(off, h, k) +#define git_offmap_valid_index(h, idx) (idx != kh_end(h)) + +#define git_offmap_exists(h, k) (kh_get(off, h, k) != kh_end(h)) + +#define git_offmap_value_at(h, idx) kh_val(h, idx) +#define git_offmap_set_value_at(h, idx, v) kh_val(h, idx) = v +#define git_offmap_delete_at(h, idx) kh_del(off, h, idx) + +#define git_offmap_insert(h, key, val, rval) do { \ + khiter_t __pos = kh_put(off, h, key, &rval); \ + if (rval >= 0) { \ + if (rval == 0) kh_key(h, __pos) = key; \ + kh_val(h, __pos) = val; \ + } } while (0) + +#define git_offmap_insert2(h, key, val, oldv, rval) do { \ + khiter_t __pos = kh_put(off, h, key, &rval); \ + if (rval >= 0) { \ + if (rval == 0) { \ + oldv = kh_val(h, __pos); \ + kh_key(h, __pos) = key; \ + } else { oldv = NULL; } \ + kh_val(h, __pos) = val; \ + } } while (0) + +#define git_offmap_delete(h, key) do { \ + khiter_t __pos = git_offmap_lookup_index(h, key); \ + if (git_offmap_valid_index(h, __pos)) \ + git_offmap_delete_at(h, __pos); } while (0) + +#define git_offmap_foreach kh_foreach +#define git_offmap_foreach_value kh_foreach_value + +#endif diff --git a/src/pack.c b/src/pack.c index d4f8d72e7..f7ef42d20 100644 --- a/src/pack.c +++ b/src/pack.c @@ -46,6 +46,29 @@ static int packfile_error(const char *message) return -1; } + +static git_pack_cache_entry *new_cache_object(git_off_t off, git_rawobj *source) +{ + git_pack_cache_entry *e = git__malloc(sizeof(git_pack_cache_entry)); + if (!e) + return NULL; + + e->off = off; + memcpy(&e->raw, source, sizeof(git_rawobj)); + + return e; +} + +static void free_cache_object(void *o) +{ + git_pack_cache_entry *e = (git_pack_cache_entry *)o; + + if (e != NULL) { + git__free(e->raw.data); + git__free(e); + } +} + /*********************************************************** * * PACK INDEX METHODS @@ -336,9 +359,11 @@ static int packfile_unpack_delta( git_otype delta_type, git_off_t obj_offset) { - git_off_t base_offset; + git_off_t base_offset, base_key; git_rawobj base, delta; - int error; + git_pack_cache_entry *cached; + int error, found_base = 0; + khiter_t k; base_offset = get_delta_base(p, w_curs, curpos, delta_type, obj_offset); git_mwindow_close(w_curs); @@ -347,33 +372,56 @@ static int packfile_unpack_delta( if (base_offset < 0) /* must actually be an error code */ return (int)base_offset; - error = git_packfile_unpack(&base, p, &base_offset); + if (!p->bases) { + p->bases = git_offmap_alloc(); + GITERR_CHECK_ALLOC(p->bases); + } - /* - * TODO: git.git tries to load the base from other packfiles - * or loose objects. - * - * We'll need to do this in order to support thin packs. - */ - if (error < 0) - return error; + base_key = base_offset; /* git_packfile_unpack modifies base_offset */ + k = kh_get(off, p->bases, base_offset); + if (k != kh_end(p->bases)) { /* found it */ + cached = kh_value(p->bases, k); + found_base = 1; + memcpy(&base, &cached->raw, sizeof(git_rawobj)); + } else { /* have to inflate it */ + error = git_packfile_unpack(&base, p, &base_offset); + + /* + * TODO: git.git tries to load the base from other packfiles + * or loose objects. + * + * We'll need to do this in order to support thin packs. + */ + if (error < 0) + return error; + } error = packfile_unpack_compressed(&delta, p, w_curs, curpos, delta_size, delta_type); git_mwindow_close(w_curs); + if (error < 0) { - git__free(base.data); + if (!found_base) + git__free(base.data); return error; } obj->type = base.type; error = git__delta_apply(obj, base.data, base.len, delta.data, delta.len); + if (error < 0) + goto on_error; - git__free(base.data); + if (!found_base) { + cached = new_cache_object(base_key, &base); + if (cached) { + k = kh_put(off, p->bases, base_key, &error); + assert(error != 0); + kh_value(p->bases, k) = cached; + } + } + +on_error: git__free(delta.data); - /* TODO: we might want to cache this. eventually */ - //add_delta_base_cache(p, base_offset, base, base_size, *type); - return error; /* error set by git__delta_apply */ } @@ -651,9 +699,19 @@ static struct git_pack_file *packfile_alloc(size_t extra) void packfile_free(struct git_pack_file *p) { + khiter_t k; assert(p); - /* clear_delta_base_cache(); */ + if (p->bases) { + for (k = kh_begin(p->bases); k != kh_end(p->bases); k++) { + if (kh_exist(p->bases, k)) + free_cache_object(kh_value(p->bases, k)); + } + + git_offmap_free(p->bases); + } + + git_mwindow_free_all(&p->mwf); git_mwindow_file_deregister(&p->mwf); @@ -678,6 +736,9 @@ static int packfile_open(struct git_pack_file *p) if (!p->index_map.data && pack_index_open(p) < 0) return git_odb__error_notfound("failed to open packfile", NULL); + p->bases = git_offmap_alloc(); + GITERR_CHECK_ALLOC(p->bases); + /* TODO: open with noatime */ p->mwf.fd = git_futils_open_ro(p->pack_name); if (p->mwf.fd < 0) { diff --git a/src/pack.h b/src/pack.h index bbfcca591..0f795f6f4 100644 --- a/src/pack.h +++ b/src/pack.h @@ -53,6 +53,15 @@ struct git_pack_idx_header { uint32_t idx_version; }; +typedef struct git_pack_cache_entry { + git_off_t off; + git_rawobj raw; +} git_pack_cache_entry; + +#include "offmap.h" + +GIT__USE_OFFMAP; + struct git_pack_file { git_mwindow_file mwf; git_map index_map; @@ -68,6 +77,8 @@ struct git_pack_file { git_vector cache; git_oid **oids; + git_offmap *bases; /* delta base cache */ + /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[GIT_FLEX_ARRAY]; /* more */ }; From 525d961c2442f3947517201113e375375fcf4280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 20 Dec 2012 07:55:51 +0100 Subject: [PATCH 2/5] pack: refcount entries and add a mutex around cache access --- src/pack.c | 42 +++++++++++++++++++++++++++++++++--------- src/pack.h | 3 ++- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/pack.c b/src/pack.c index f7ef42d20..5e08509f8 100644 --- a/src/pack.c +++ b/src/pack.c @@ -47,13 +47,13 @@ static int packfile_error(const char *message) } -static git_pack_cache_entry *new_cache_object(git_off_t off, git_rawobj *source) +static git_pack_cache_entry *new_cache_object(git_rawobj *source) { git_pack_cache_entry *e = git__malloc(sizeof(git_pack_cache_entry)); if (!e) return NULL; - e->off = off; + e->refcount.val = 0; memcpy(&e->raw, source, sizeof(git_rawobj)); return e; @@ -63,6 +63,7 @@ static void free_cache_object(void *o) { git_pack_cache_entry *e = (git_pack_cache_entry *)o; + assert(e->refcount.val == 0); if (e != NULL) { git__free(e->raw.data); git__free(e); @@ -361,7 +362,7 @@ static int packfile_unpack_delta( { git_off_t base_offset, base_key; git_rawobj base, delta; - git_pack_cache_entry *cached; + git_pack_cache_entry *cached = NULL; int error, found_base = 0; khiter_t k; @@ -375,15 +376,21 @@ static int packfile_unpack_delta( if (!p->bases) { p->bases = git_offmap_alloc(); GITERR_CHECK_ALLOC(p->bases); + git_mutex_init(&p->bases_lock); } base_key = base_offset; /* git_packfile_unpack modifies base_offset */ + git_mutex_lock(&p->bases_lock); k = kh_get(off, p->bases, base_offset); if (k != kh_end(p->bases)) { /* found it */ cached = kh_value(p->bases, k); + git_atomic_inc(&cached->refcount); found_base = 1; memcpy(&base, &cached->raw, sizeof(git_rawobj)); - } else { /* have to inflate it */ + } + git_mutex_unlock(&p->bases_lock); + + if (!cached) { /* have to inflate it */ error = git_packfile_unpack(&base, p, &base_offset); /* @@ -410,12 +417,27 @@ static int packfile_unpack_delta( if (error < 0) goto on_error; - if (!found_base) { - cached = new_cache_object(base_key, &base); + if (found_base) { + git_atomic_dec(&cached->refcount); + } else { + cached = new_cache_object(&base); if (cached) { - k = kh_put(off, p->bases, base_key, &error); - assert(error != 0); - kh_value(p->bases, k) = cached; + int exists; + + git_mutex_lock(&p->bases_lock); + /* Add it to the cache if nobody else has */ + exists = kh_exist(p->bases, kh_get(off, p->bases, base_key)); + if (!exists) { + k = kh_put(off, p->bases, base_key, &error); + assert(error != 0); + kh_value(p->bases, k) = cached; + } + git_mutex_unlock(&p->bases_lock); + /* Somebody beat us to adding it into the cache */ + if (exists) { + free_cache_object(cached); + git__free(base.data); + } } } @@ -738,6 +760,8 @@ static int packfile_open(struct git_pack_file *p) p->bases = git_offmap_alloc(); GITERR_CHECK_ALLOC(p->bases); + git_mutex_init(&p->bases_lock); + /* TODO: open with noatime */ p->mwf.fd = git_futils_open_ro(p->pack_name); diff --git a/src/pack.h b/src/pack.h index 0f795f6f4..732bfc3ff 100644 --- a/src/pack.h +++ b/src/pack.h @@ -54,7 +54,7 @@ struct git_pack_idx_header { }; typedef struct git_pack_cache_entry { - git_off_t off; + git_atomic refcount; git_rawobj raw; } git_pack_cache_entry; @@ -77,6 +77,7 @@ struct git_pack_file { git_vector cache; git_oid **oids; + git_mutex bases_lock; git_offmap *bases; /* delta base cache */ /* something like ".git/objects/pack/xxxxx.pack" */ From c8f79c2bdf9dd237d5c407526bcfc20d4eff5e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 21 Dec 2012 10:59:10 +0100 Subject: [PATCH 3/5] pack: abstract out the cache into its own functions --- src/pack.c | 133 ++++++++++++++++++++++++++++++++--------------------- src/pack.h | 13 +++++- 2 files changed, 92 insertions(+), 54 deletions(-) diff --git a/src/pack.c b/src/pack.c index 5e08509f8..a4c3ebdc2 100644 --- a/src/pack.c +++ b/src/pack.c @@ -46,14 +46,16 @@ static int packfile_error(const char *message) return -1; } +/******************** + * Delta base cache + ********************/ static git_pack_cache_entry *new_cache_object(git_rawobj *source) { - git_pack_cache_entry *e = git__malloc(sizeof(git_pack_cache_entry)); + git_pack_cache_entry *e = git__calloc(1, sizeof(git_pack_cache_entry)); if (!e) return NULL; - e->refcount.val = 0; memcpy(&e->raw, source, sizeof(git_rawobj)); return e; @@ -70,6 +72,75 @@ static void free_cache_object(void *o) } } +static void cache_free(git_pack_cache *cache) +{ + khiter_t k; + + if (cache->entries) { + for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) { + if (kh_exist(cache->entries, k)) + free_cache_object(kh_value(cache->entries, k)); + } + + git_offmap_free(cache->entries); + } +} + +static int cache_init(git_pack_cache *cache) +{ + memset(cache, 0, sizeof(git_pack_cache)); + cache->entries = git_offmap_alloc(); + GITERR_CHECK_ALLOC(cache->entries); + cache->memory_limit = GIT_PACK_CACHE_MEMORY_LIMIT; + git_mutex_init(&cache->lock); + + return 0; +} + +static git_pack_cache_entry *cache_get(git_pack_cache *cache, size_t offset) +{ + khiter_t k; + git_pack_cache_entry *entry = NULL; + + git_mutex_lock(&cache->lock); + k = kh_get(off, cache->entries, offset); + if (k != kh_end(cache->entries)) { /* found it */ + entry = kh_value(cache->entries, k); + git_atomic_inc(&entry->refcount); + entry->uses++; + } + git_mutex_unlock(&cache->lock); + + return entry; +} + +static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset) +{ + git_pack_cache_entry *entry; + int error, exists = 0; + khiter_t k; + + entry = new_cache_object(base); + if (entry) { + git_mutex_lock(&cache->lock); + /* Add it to the cache if nobody else has */ + exists = kh_get(off, cache->entries, offset) != kh_end(cache->entries); + if (!exists) { + k = kh_put(off, cache->entries, offset, &error); + assert(error != 0); + kh_value(cache->entries, k) = entry; + } + git_mutex_unlock(&cache->lock); + /* Somebody beat us to adding it into the cache */ + if (exists) { + git__free(entry); + return -1; + } + } + + return 0; +} + /*********************************************************** * * PACK INDEX METHODS @@ -364,7 +435,6 @@ static int packfile_unpack_delta( git_rawobj base, delta; git_pack_cache_entry *cached = NULL; int error, found_base = 0; - khiter_t k; base_offset = get_delta_base(p, w_curs, curpos, delta_type, obj_offset); git_mwindow_close(w_curs); @@ -373,22 +443,14 @@ static int packfile_unpack_delta( if (base_offset < 0) /* must actually be an error code */ return (int)base_offset; - if (!p->bases) { - p->bases = git_offmap_alloc(); - GITERR_CHECK_ALLOC(p->bases); - git_mutex_init(&p->bases_lock); - } + if (!p->bases.entries && (cache_init(&p->bases) < 0)) + return -1; base_key = base_offset; /* git_packfile_unpack modifies base_offset */ - git_mutex_lock(&p->bases_lock); - k = kh_get(off, p->bases, base_offset); - if (k != kh_end(p->bases)) { /* found it */ - cached = kh_value(p->bases, k); - git_atomic_inc(&cached->refcount); - found_base = 1; + if ((cached = cache_get(&p->bases, base_offset)) != NULL) { memcpy(&base, &cached->raw, sizeof(git_rawobj)); + found_base = 1; } - git_mutex_unlock(&p->bases_lock); if (!cached) { /* have to inflate it */ error = git_packfile_unpack(&base, p, &base_offset); @@ -417,29 +479,10 @@ static int packfile_unpack_delta( if (error < 0) goto on_error; - if (found_base) { + if (found_base) git_atomic_dec(&cached->refcount); - } else { - cached = new_cache_object(&base); - if (cached) { - int exists; - - git_mutex_lock(&p->bases_lock); - /* Add it to the cache if nobody else has */ - exists = kh_exist(p->bases, kh_get(off, p->bases, base_key)); - if (!exists) { - k = kh_put(off, p->bases, base_key, &error); - assert(error != 0); - kh_value(p->bases, k) = cached; - } - git_mutex_unlock(&p->bases_lock); - /* Somebody beat us to adding it into the cache */ - if (exists) { - free_cache_object(cached); - git__free(base.data); - } - } - } + else if (cache_add(&p->bases, &base, base_key) < 0) + git__free(base.data); on_error: git__free(delta.data); @@ -721,18 +764,9 @@ static struct git_pack_file *packfile_alloc(size_t extra) void packfile_free(struct git_pack_file *p) { - khiter_t k; assert(p); - if (p->bases) { - for (k = kh_begin(p->bases); k != kh_end(p->bases); k++) { - if (kh_exist(p->bases, k)) - free_cache_object(kh_value(p->bases, k)); - } - - git_offmap_free(p->bases); - } - + cache_free(&p->bases); git_mwindow_free_all(&p->mwf); git_mwindow_file_deregister(&p->mwf); @@ -758,11 +792,6 @@ static int packfile_open(struct git_pack_file *p) if (!p->index_map.data && pack_index_open(p) < 0) return git_odb__error_notfound("failed to open packfile", NULL); - p->bases = git_offmap_alloc(); - GITERR_CHECK_ALLOC(p->bases); - git_mutex_init(&p->bases_lock); - - /* TODO: open with noatime */ p->mwf.fd = git_futils_open_ro(p->pack_name); if (p->mwf.fd < 0) { diff --git a/src/pack.h b/src/pack.h index 732bfc3ff..4e5c12765 100644 --- a/src/pack.h +++ b/src/pack.h @@ -54,6 +54,7 @@ struct git_pack_idx_header { }; typedef struct git_pack_cache_entry { + int uses; /* enough? */ git_atomic refcount; git_rawobj raw; } git_pack_cache_entry; @@ -62,6 +63,15 @@ typedef struct git_pack_cache_entry { GIT__USE_OFFMAP; +#define GIT_PACK_CACHE_MEMORY_LIMIT 2 * 1024 * 1024; + +typedef struct { + size_t memory_used; + size_t memory_limit; + git_mutex lock; + git_offmap *entries; +} git_pack_cache; + struct git_pack_file { git_mwindow_file mwf; git_map index_map; @@ -77,8 +87,7 @@ struct git_pack_file { git_vector cache; git_oid **oids; - git_mutex bases_lock; - git_offmap *bases; /* delta base cache */ + git_pack_cache bases; /* delta base cache */ /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[GIT_FLEX_ARRAY]; /* more */ From 0ed756200693aed93c4c9fb4f8776196fec5a971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 21 Dec 2012 13:46:48 +0100 Subject: [PATCH 4/5] pack: limit the amount of memory the base delta cache can use Currently limited to 16MB (like git) and to objects up to 1MB in size. --- src/pack.c | 36 ++++++++++++++++++++++++++++++++++-- src/pack.h | 6 ++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/pack.c b/src/pack.c index a4c3ebdc2..cc9d07983 100644 --- a/src/pack.c +++ b/src/pack.c @@ -65,8 +65,8 @@ static void free_cache_object(void *o) { git_pack_cache_entry *e = (git_pack_cache_entry *)o; - assert(e->refcount.val == 0); if (e != NULL) { + assert(e->refcount.val == 0); git__free(e->raw.data); git__free(e); } @@ -107,28 +107,60 @@ static git_pack_cache_entry *cache_get(git_pack_cache *cache, size_t offset) if (k != kh_end(cache->entries)) { /* found it */ entry = kh_value(cache->entries, k); git_atomic_inc(&entry->refcount); - entry->uses++; + entry->last_usage = cache->use_ctr++; } git_mutex_unlock(&cache->lock); return entry; } +/* Run with the cache lock held */ +static void free_lowest_entry(git_pack_cache *cache) +{ + git_pack_cache_entry *lowest = NULL, *entry; + khiter_t k, lowest_k; + + for (k = kh_begin(cache->entries); k != kh_end(cache->entries); k++) { + if (!kh_exist(cache->entries, k)) + continue; + + entry = kh_value(cache->entries, k); + if (lowest == NULL || entry->last_usage < lowest->last_usage) { + lowest_k = k; + lowest = entry; + } + } + + if (!lowest) /* there's nothing to free */ + return; + + cache->memory_used -= lowest->raw.len; + kh_del(off, cache->entries, lowest_k); + free_cache_object(lowest); +} + static int cache_add(git_pack_cache *cache, git_rawobj *base, git_off_t offset) { git_pack_cache_entry *entry; int error, exists = 0; khiter_t k; + if (base->len > GIT_PACK_CACHE_SIZE_LIMIT) + return -1; + entry = new_cache_object(base); if (entry) { git_mutex_lock(&cache->lock); /* Add it to the cache if nobody else has */ exists = kh_get(off, cache->entries, offset) != kh_end(cache->entries); if (!exists) { + while (cache->memory_used + base->len > cache->memory_limit) + free_lowest_entry(cache); + k = kh_put(off, cache->entries, offset, &error); assert(error != 0); kh_value(cache->entries, k) = entry; + cache->memory_used += entry->raw.len; } git_mutex_unlock(&cache->lock); /* Somebody beat us to adding it into the cache */ diff --git a/src/pack.h b/src/pack.h index 4e5c12765..db57e57d2 100644 --- a/src/pack.h +++ b/src/pack.h @@ -54,7 +54,7 @@ struct git_pack_idx_header { }; typedef struct git_pack_cache_entry { - int uses; /* enough? */ + size_t last_usage; /* enough? */ git_atomic refcount; git_rawobj raw; } git_pack_cache_entry; @@ -63,11 +63,13 @@ typedef struct git_pack_cache_entry { GIT__USE_OFFMAP; -#define GIT_PACK_CACHE_MEMORY_LIMIT 2 * 1024 * 1024; +#define GIT_PACK_CACHE_MEMORY_LIMIT 16 * 1024 * 1024 +#define GIT_PACK_CACHE_SIZE_LIMIT 1024 * 1024 /* don't bother caching anything over 1MB */ typedef struct { size_t memory_used; size_t memory_limit; + size_t use_ctr; git_mutex lock; git_offmap *entries; } git_pack_cache; From f289f886cb81bb570bed747053d5ebf8aba6bef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 11 Jan 2013 17:24:52 +0100 Subject: [PATCH 5/5] pack: packfile_free -> git_packfile_free and use it in the indexers It turns out the indexers have been ignoring the pack's free function and leaking data. Plug that. --- src/indexer.c | 4 ++-- src/odb_pack.c | 2 +- src/pack.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/indexer.c b/src/indexer.c index 599228f3e..70b2ce031 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -747,7 +747,7 @@ void git_indexer_stream_free(git_indexer_stream *idx) git_vector_foreach(&idx->deltas, i, delta) git__free(delta); git_vector_free(&idx->deltas); - git__free(idx->pack); + git_packfile_free(idx->pack); git__free(idx); } @@ -1059,7 +1059,7 @@ void git_indexer_free(git_indexer *idx) git_vector_foreach(&idx->pack->cache, i, pe) git__free(pe); git_vector_free(&idx->pack->cache); - git__free(idx->pack); + git_packfile_free(idx->pack); git__free(idx); } diff --git a/src/odb_pack.c b/src/odb_pack.c index 9d0c4c0e7..9779ecd25 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -538,7 +538,7 @@ static void pack_backend__free(git_odb_backend *_backend) for (i = 0; i < backend->packs.length; ++i) { struct git_pack_file *p = git_vector_get(&backend->packs, i); - packfile_free(p); + git_packfile_free(p); } git_vector_free(&backend->packs); diff --git a/src/pack.c b/src/pack.c index cc9d07983..608450825 100644 --- a/src/pack.c +++ b/src/pack.c @@ -794,7 +794,7 @@ static struct git_pack_file *packfile_alloc(size_t extra) } -void packfile_free(struct git_pack_file *p) +void git_packfile_free(struct git_pack_file *p) { assert(p);