Skip to content

Commit

Permalink
revision.c: update show_object_with_name() without using malloc()
Browse files Browse the repository at this point in the history
Allocating and then immediately freeing temporary memory a million times
when listing a million objects is distasteful.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
gitster committed Aug 22, 2011
1 parent 91f1751 commit beba25a
Showing 1 changed file with 36 additions and 14 deletions.
50 changes: 36 additions & 14 deletions revision.c
Expand Up @@ -40,23 +40,45 @@ char *path_name(const struct name_path *path, const char *name)
return n;
}

static int show_path_component_truncated(FILE *out, const char *name, int len)
{
int cnt;
for (cnt = 0; cnt < len; cnt++) {
int ch = name[cnt];
if (!ch || ch == '\n')
return -1;
fputc(ch, out);
}
return len;
}

static int show_path_truncated(FILE *out, const struct name_path *path)
{
int emitted, ours;

if (!path)
return 0;
emitted = show_path_truncated(out, path->up);
if (emitted < 0)
return emitted;
if (emitted)
fputc('/', out);
ours = show_path_component_truncated(out, path->elem, path->elem_len);
if (ours < 0)
return ours;
return ours || emitted;
}

void show_object_with_name(FILE *out, struct object *obj, const struct name_path *path, const char *component)
{
char *name = path_name(path, component);
const char *ep = strchr(name, '\n');
struct name_path leaf;
leaf.up = (struct name_path *)path;
leaf.elem = component;
leaf.elem_len = strlen(component);

/*
* An object with name "foo\n0000000..." can be used to
* confuse downstream "git pack-objects" very badly.
*/
if (ep) {
fprintf(out, "%s %.*s\n", sha1_to_hex(obj->sha1),
(int) (ep - name),
name);
}
else
fprintf(out, "%s %s\n", sha1_to_hex(obj->sha1), name);
free(name);
fprintf(out, "%s ", sha1_to_hex(obj->sha1));
show_path_truncated(out, &leaf);
fputc('\n', out);
}

void add_object(struct object *obj,
Expand Down

0 comments on commit beba25a

Please sign in to comment.