From b662e0b89238cd53934d6bbef99c294bbd877121 Mon Sep 17 00:00:00 2001 From: Jameson Miller Date: Wed, 14 Mar 2018 16:54:06 -0400 Subject: [PATCH] Enable the creation of transient cache entries Signed-off-by: Jameson Miller --- builtin/checkout.c | 4 ++-- builtin/difftool.c | 22 ++------------------ cache.h | 14 ++++++++++++- read-cache.c | 51 ++++++++++++++++++++++++++++++++++++++-------- unpack-trees.c | 12 +++++++---- 5 files changed, 68 insertions(+), 35 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index dbe3202477d75b..9a3dd2ed489a38 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -236,11 +236,11 @@ static int checkout_merged(int pos, const struct checkout *state) blob_type, oid.hash)) die(_("Unable to add merge result for '%s'"), path); free(result_buf.ptr); - ce = make_cache_entry_from_index(state->istate, mode, oid.hash, path, 2, 0); + ce = make_transient_cache_entry(mode, oid.hash, path, 2); if (!ce) die(_("make_cache_entry failed for path '%s'"), path); status = checkout_entry(ce, state, NULL); - cache_entry_free(ce); + transient_cache_entry_free(ce); return status; } diff --git a/builtin/difftool.c b/builtin/difftool.c index 828b2529607d32..c29be7b9fa60fa 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -321,28 +321,10 @@ static int checkout_path(unsigned mode, struct object_id *oid, struct cache_entry *ce; int ret; - /* - * REVIEW: This is a transient cache entry - it is freed - * a couple lines below. - * - * We have worked to remove the ability to - * allocate individual cache entries - - * but if we know it is going to be freed, - * then maybe there is no need to allocate - * from a memory pool. - * - * For now, allocate from the_index. - * - * Options: - * 1) expect an istate to be passed in (via state) - * 2) (re)enable us to allocate an individual cache entry - * 3) work against the_index - * 4) Can we use stack allocated memory? - */ - ce = make_cache_entry_from_index(&the_index, mode, oid->hash, path, 0, 0); + ce = make_transient_cache_entry(mode, oid->hash, path, 0); ret = checkout_entry(ce, state, NULL); - cache_entry_free(ce); + transient_cache_entry_free(ce); return ret; } diff --git a/cache.h b/cache.h index 1eef949c4e4294..04de11c7b3ad47 100644 --- a/cache.h +++ b/cache.h @@ -716,14 +716,24 @@ extern int add_to_index(struct index_state *, const char *path, struct stat *, i extern int add_file_to_index(struct index_state *, const char *path, int flags); extern struct cache_entry *make_cache_entry_from_index(struct index_state *, unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options); +extern struct cache_entry *make_transient_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage); /* - * Create an empty cache entry struct. + * Create an empty cache entry struct. This is intended for use with + * cache_entries that could be added to the associated index. * * istate: The index whose memory pool this cache entry should be allocated from. * len: The length to reserve for the path field of the cache entry. */ extern struct cache_entry *make_empty_cache_entry_from_index(struct index_state *istate, size_t len); + +/* + * Create an empty cache entry struct. This is intended for use with + * cache_entries that will not be added to an index. + * + * len: The length to reserve for the path field of the cache entry. + */ +extern struct cache_entry *make_empty_transient_cache_entry(size_t len); extern int chmod_index_entry(struct index_state *, struct cache_entry *ce, char flip); extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b); extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce); @@ -2000,6 +2010,8 @@ void safe_create_dir(const char *dir, int share); extern int print_sha1_ellipsis(void); void cache_entry_free(struct cache_entry *ce); +void transient_cache_entry_free(struct cache_entry *ce); + void validate_cache_entries(const struct index_state *istate); #endif /* CACHE_H */ diff --git a/read-cache.c b/read-cache.c index cbc8b4c930e0d3..7ddf9b6b2f00e7 100644 --- a/read-cache.c +++ b/read-cache.c @@ -781,10 +781,15 @@ struct cache_entry *make_empty_cache_entry_from_index(struct index_state *istate return mem_pool__ce_calloc(find_mem_pool(istate), len); } -struct cache_entry *make_cache_entry_from_index(struct index_state *istate, - unsigned int mode, - const unsigned char *sha1, const char *path, int stage, - unsigned int refresh_options) +struct cache_entry *make_empty_transient_cache_entry(size_t len) +{ + return xcalloc(1, cache_entry_size(len)); +} + +struct cache_entry *make_cache_entry(struct index_state *istate, + unsigned int mode, + const unsigned char *sha1, const char *path, int stage, + unsigned int refresh_options, int is_transient) { int len; struct cache_entry *ce, *ret; @@ -795,7 +800,8 @@ struct cache_entry *make_cache_entry_from_index(struct index_state *istate, } len = strlen(path); - ce = make_empty_cache_entry_from_index(istate, len); + ce = is_transient ? make_empty_transient_cache_entry(len) : + make_empty_cache_entry_from_index(istate, len); hashcpy(ce->oid.hash, sha1); memcpy(ce->name, path, len); @@ -803,12 +809,36 @@ struct cache_entry *make_cache_entry_from_index(struct index_state *istate, ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); - ret = refresh_cache_entry(istate, ce, refresh_options); - if (ret != ce) - cache_entry_free(ce); + /* + * Transient cache entries cannot be refreshed - they are not associated + * with the index. + */ + if (!is_transient) { + ret = refresh_cache_entry(istate, ce, refresh_options); + + if (ret != ce) + cache_entry_free(ce); + } else { + ret = ce; + } + return ret; } +struct cache_entry *make_cache_entry_from_index(struct index_state *istate, unsigned int mode, + const unsigned char *sha1, const char *path, + int stage, unsigned int refresh_options) +{ + return make_cache_entry(istate, mode, sha1, path, stage, + refresh_options, 0); +} + +struct cache_entry *make_transient_cache_entry(unsigned int mode, const unsigned char *sha1, + const char *path, int stage) +{ + return make_cache_entry(NULL, mode, sha1, path, stage, 0, 1); +} + /* * Chmod an index entry with either +x or -x. * @@ -2830,3 +2860,8 @@ void cache_entry_free(struct cache_entry *ce) if (ce && invalidate_cache_entry) memset(ce, 0xCD, cache_entry_size(ce->ce_namelen)); } + +void transient_cache_entry_free(struct cache_entry *ce) +{ + free(ce); +} diff --git a/unpack-trees.c b/unpack-trees.c index eaef3bdeb94a62..bdb4c4423ba1ac 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -781,10 +781,14 @@ static int ce_in_traverse_path(const struct cache_entry *ce, static struct cache_entry *create_ce_entry(const struct traverse_info *info, const struct name_entry *n, int stage, - struct index_state *istate) + struct index_state *istate, + int is_transient) { int len = traverse_path_len(info, n); - struct cache_entry *ce = make_empty_cache_entry_from_index(istate, len); + struct cache_entry *ce = + is_transient ? + make_empty_transient_cache_entry(len) : + make_empty_cache_entry_from_index(istate, len); ce->ce_mode = create_ce_mode(n->mode); ce->ce_flags = create_ce_flags(stage); @@ -830,7 +834,7 @@ static int unpack_nondirectories(int n, unsigned long mask, stage = 3; else stage = 2; - src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result); + src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result, o->merge); } if (o->merge) { @@ -839,7 +843,7 @@ static int unpack_nondirectories(int n, unsigned long mask, for (i = 0; i < n; i++) { struct cache_entry *ce = src[i + o->merge]; if (ce != o->df_conflict_entry) - cache_entry_free(ce); + transient_cache_entry_free(ce); } return rc; }