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>
This commit is contained in:

committed by
Junio C Hamano

parent
33d4221c79
commit
9e0c3c4fcd
23
object.c
23
object.c
@ -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,
|
||||
|
Reference in New Issue
Block a user