summaryrefslogtreecommitdiff
path: root/revision.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-02-11 22:26:18 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-03-16 17:41:03 (GMT)
commitf3badaed5106a16499d0fae31a382f9047b272d7 (patch)
tree80deedef9ee6e68ad5ec606c12ed179ec5842143 /revision.c
parent8eee9f9277b6e38ec46c84f4ca3be5d988ca0a33 (diff)
downloadgit-f3badaed5106a16499d0fae31a382f9047b272d7.zip
git-f3badaed5106a16499d0fae31a382f9047b272d7.tar.gz
git-f3badaed5106a16499d0fae31a382f9047b272d7.tar.bz2
list-objects: convert name_path to a strbuf
The "struct name_path" data is examined in only two places: we generate it in process_tree(), and we convert it to a single string in path_name(). Everyone else just passes it through to those functions. We can further note that process_tree() already keeps a single strbuf with the leading tree path, for use with tree_entry_interesting(). Instead of building a separate name_path linked list, let's just use the one we already build in "base". This reduces the amount of code (especially tricky code in path_name() which did not check for integer overflows caused by deep or large pathnames). It is also more efficient in some instances. Any time we were using tree_entry_interesting, we were building up the strbuf anyway, so this is an immediate and obvious win there. In cases where we were not, we trade off storing "pathname/" in a strbuf on the heap for each level of the path, instead of two pointers and an int on the stack (with one pointer into the tree object). On a 64-bit system, the latter is 20 bytes; so if path components are less than that on average, this has lower peak memory usage. In practice it probably doesn't matter either way; we are already holding in memory all of the tree objects leading up to each pathname, and for normal-depth pathnames, we are only talking about hundreds of bytes. This patch leaves "struct name_path" as a thin wrapper around the strbuf, to avoid disrupting callbacks. We should fix them, but leaving it out makes this diff easier to view. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'revision.c')
-rw-r--r--revision.c25
1 files changed, 5 insertions, 20 deletions
diff --git a/revision.c b/revision.c
index cf544b6..f8c3034 100644
--- a/revision.c
+++ b/revision.c
@@ -23,26 +23,11 @@ volatile show_early_output_fn_t show_early_output;
char *path_name(const struct name_path *path, const char *name)
{
- const struct name_path *p;
- char *n, *m;
- int nlen = strlen(name);
- int len = nlen + 1;
-
- for (p = path; p; p = p->up) {
- if (p->elem_len)
- len += p->elem_len + 1;
- }
- n = xmalloc(len);
- m = n + len - (nlen + 1);
- strcpy(m, name);
- for (p = path; p; p = p->up) {
- if (p->elem_len) {
- m -= p->elem_len + 1;
- memcpy(m, p->elem, p->elem_len);
- m[p->elem_len] = '/';
- }
- }
- return n;
+ struct strbuf ret = STRBUF_INIT;
+ if (path)
+ strbuf_addbuf(&ret, path->base);
+ strbuf_addstr(&ret, name);
+ return strbuf_detach(&ret, NULL);
}
void show_object_with_name(FILE *out, struct object *obj,