diff options
author | Jeff King <peff@peff.net> | 2014-10-15 18:42:57 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-10-16 10:10:44 -0700 |
commit | 9e0c3c4fcdf3775a9e0256ee231efa4698297a0e (patch) | |
tree | 8ca6ac1f3597dc6e2cf193fa69bf956eed217c54 /object.c | |
parent | 33d4221c79c89844bed6b9558cc2bc497251ef70 (diff) | |
download | git-9e0c3c4fcdf3775a9e0256ee231efa4698297a0e.tar.gz |
make add_object_array_with_context interface more sane
When you resolve a sha1, you can optionally keep any context
found during the resolution, including the path and mode of
a tree entry (e.g., when looking up "HEAD:subdir/file.c").
The add_object_array_with_context function lets you then
attach that context to an entry in a list. Unfortunately,
the interface for doing so is horrible. The object_context
structure is large and most object_array users do not use
it. Therefore we keep a pointer to the structure to avoid
burdening other users too much. But that means when we do
use it that we must allocate the struct ourselves. And the
struct contains a fixed PATH_MAX-sized buffer, which makes
this wholly unsuitable for any large arrays.
We can observe that there is only a single user of the
"with_context" variant: builtin/grep.c. And in that use
case, the only element we care about is the path. We can
therefore store only the path as a pointer (the context's
mode field was redundant with the object_array_entry itself,
and nobody actually cared about the surrounding tree). This
still requires a strdup of the pathname, but at least we are
only consuming the minimum amount of memory for each string.
We can also handle the copying ourselves in
add_object_array_*, and free it as appropriate in
object_array_release_entry.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 23 |
1 files changed, 9 insertions, 14 deletions
@@ -307,10 +307,9 @@ int object_list_contains(struct object_list *list, struct object *obj) */ static char object_array_slopbuf[1]; -static void add_object_array_with_mode_context(struct object *obj, const char *name, - struct object_array *array, - unsigned mode, - struct object_context *context) +void add_object_array_with_path(struct object *obj, const char *name, + struct object_array *array, + unsigned mode, const char *path) { unsigned nr = array->nr; unsigned alloc = array->alloc; @@ -333,7 +332,10 @@ static void add_object_array_with_mode_context(struct object *obj, const char *n else entry->name = xstrdup(name); entry->mode = mode; - entry->context = context; + if (path) + entry->path = xstrdup(path); + else + entry->path = NULL; array->nr = ++nr; } @@ -344,15 +346,7 @@ void add_object_array(struct object *obj, const char *name, struct object_array void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode) { - add_object_array_with_mode_context(obj, name, array, mode, NULL); -} - -void add_object_array_with_context(struct object *obj, const char *name, struct object_array *array, struct object_context *context) -{ - if (context) - add_object_array_with_mode_context(obj, name, array, context->mode, context); - else - add_object_array_with_mode_context(obj, name, array, S_IFINVALID, context); + add_object_array_with_path(obj, name, array, mode, NULL); } /* @@ -363,6 +357,7 @@ static void object_array_release_entry(struct object_array_entry *ent) { if (ent->name != object_array_slopbuf) free(ent->name); + free(ent->path); } void object_array_filter(struct object_array *array, |