Skip to content

Commit 9e0c3c4

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 33d4221 commit 9e0c3c4

File tree

3 files changed

+15
-20
lines changed

3 files changed

+15
-20
lines changed

builtin/grep.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,10 +456,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
456456
}
457457

458458
static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
459-
struct object *obj, const char *name, struct object_context *oc)
459+
struct object *obj, const char *name, const char *path)
460460
{
461461
if (obj->type == OBJ_BLOB)
462-
return grep_sha1(opt, obj->sha1, name, 0, oc ? oc->path : NULL);
462+
return grep_sha1(opt, obj->sha1, name, 0, path);
463463
if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
464464
struct tree_desc tree;
465465
void *data;
@@ -501,7 +501,7 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
501501
for (i = 0; i < nr; i++) {
502502
struct object *real_obj;
503503
real_obj = deref_tag(list->objects[i].item, NULL, 0);
504-
if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].context)) {
504+
if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path)) {
505505
hit = 1;
506506
if (opt->status_only)
507507
break;
@@ -821,7 +821,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
821821
struct object *object = parse_object_or_die(sha1, arg);
822822
if (!seen_dashdash)
823823
verify_non_filename(prefix, arg);
824-
add_object_array_with_context(object, arg, &list, xmemdupz(&oc, sizeof(struct object_context)));
824+
add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
825825
continue;
826826
}
827827
if (!strcmp(arg, "--")) {

object.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -307,10 +307,9 @@ int object_list_contains(struct object_list *list, struct object *obj)
307307
*/
308308
static char object_array_slopbuf[1];
309309

310-
static void add_object_array_with_mode_context(struct object *obj, const char *name,
311-
struct object_array *array,
312-
unsigned mode,
313-
struct object_context *context)
310+
void add_object_array_with_path(struct object *obj, const char *name,
311+
struct object_array *array,
312+
unsigned mode, const char *path)
314313
{
315314
unsigned nr = array->nr;
316315
unsigned alloc = array->alloc;
@@ -333,7 +332,10 @@ static void add_object_array_with_mode_context(struct object *obj, const char *n
333332
else
334333
entry->name = xstrdup(name);
335334
entry->mode = mode;
336-
entry->context = context;
335+
if (path)
336+
entry->path = xstrdup(path);
337+
else
338+
entry->path = NULL;
337339
array->nr = ++nr;
338340
}
339341

@@ -344,15 +346,7 @@ void add_object_array(struct object *obj, const char *name, struct object_array
344346

345347
void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode)
346348
{
347-
add_object_array_with_mode_context(obj, name, array, mode, NULL);
348-
}
349-
350-
void add_object_array_with_context(struct object *obj, const char *name, struct object_array *array, struct object_context *context)
351-
{
352-
if (context)
353-
add_object_array_with_mode_context(obj, name, array, context->mode, context);
354-
else
355-
add_object_array_with_mode_context(obj, name, array, S_IFINVALID, context);
349+
add_object_array_with_path(obj, name, array, mode, NULL);
356350
}
357351

358352
/*
@@ -363,6 +357,7 @@ static void object_array_release_entry(struct object_array_entry *ent)
363357
{
364358
if (ent->name != object_array_slopbuf)
365359
free(ent->name);
360+
free(ent->path);
366361
}
367362

368363
void object_array_filter(struct object_array *array,

object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ struct object_array {
1818
* empty string.
1919
*/
2020
char *name;
21+
char *path;
2122
unsigned mode;
22-
struct object_context *context;
2323
} *objects;
2424
};
2525

@@ -115,7 +115,7 @@ int object_list_contains(struct object_list *list, struct object *obj);
115115
/* Object array handling .. */
116116
void add_object_array(struct object *obj, const char *name, struct object_array *array);
117117
void add_object_array_with_mode(struct object *obj, const char *name, struct object_array *array, unsigned mode);
118-
void add_object_array_with_context(struct object *obj, const char *name, struct object_array *array, struct object_context *context);
118+
void add_object_array_with_path(struct object *obj, const char *name, struct object_array *array, unsigned mode, const char *path);
119119

120120
typedef int (*object_array_each_func_t)(struct object_array_entry *, void *);
121121

0 commit comments

Comments
 (0)