tree.c: update read_tree_recursive callback to pass strbuf as base
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sun, 30 Nov 2014 09:05:00 +0000 (16:05 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 1 Dec 2014 19:32:29 +0000 (11:32 -0800)
This allows the callback to use 'base' as a temporary buffer to
quickly assemble full path "without" extra allocation. The callback
has to restore it afterwards of course.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
archive.c
builtin/checkout.c
builtin/log.c
builtin/ls-tree.c
merge-recursive.c
tree.c
tree.h
index 94a9981adf72c437f8660c66b67506b50ed8d3a9..9e30246b6402454e8d92fb6aa24a1a07c534b0ef 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
        return write_entry(args, sha1, path.buf, path.len, mode);
 }
 
+static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base,
+               const char *filename, unsigned mode, int stage,
+               void *context)
+{
+       return write_archive_entry(sha1, base->buf, base->len,
+                                    filename, mode, stage, context);
+}
+
 static void queue_directory(const unsigned char *sha1,
-               const char *base, int baselen, const char *filename,
+               struct strbuf *base, const char *filename,
                unsigned mode, int stage, struct archiver_context *c)
 {
        struct directory *d;
-       d = xmallocz(sizeof(*d) + baselen + 1 + strlen(filename));
+       d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
        d->up      = c->bottom;
-       d->baselen = baselen;
+       d->baselen = base->len;
        d->mode    = mode;
        d->stage   = stage;
        c->bottom  = d;
-       d->len = sprintf(d->path, "%.*s%s/", baselen, base, filename);
+       d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
        hashcpy(d->sha1, sha1);
 }
 
@@ -191,28 +199,28 @@ static int write_directory(struct archiver_context *c)
 }
 
 static int queue_or_write_archive_entry(const unsigned char *sha1,
-               const char *base, int baselen, const char *filename,
+               struct strbuf *base, const char *filename,
                unsigned mode, int stage, void *context)
 {
        struct archiver_context *c = context;
 
        while (c->bottom &&
-              !(baselen >= c->bottom->len &&
-                !strncmp(base, c->bottom->path, c->bottom->len))) {
+              !(base->len >= c->bottom->len &&
+                !strncmp(base->buf, c->bottom->path, c->bottom->len))) {
                struct directory *next = c->bottom->up;
                free(c->bottom);
                c->bottom = next;
        }
 
        if (S_ISDIR(mode)) {
-               queue_directory(sha1, base, baselen, filename,
+               queue_directory(sha1, base, filename,
                                mode, stage, c);
                return READ_TREE_RECURSIVE;
        }
 
        if (write_directory(c))
                return -1;
-       return write_archive_entry(sha1, base, baselen, filename, mode,
+       return write_archive_entry(sha1, base->buf, base->len, filename, mode,
                                   stage, context);
 }
 
@@ -260,7 +268,7 @@ int write_archive_entries(struct archiver_args *args,
        err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
                                  args->pathspec.has_wildcard ?
                                  queue_or_write_archive_entry :
-                                 write_archive_entry,
+                                 write_archive_entry_buf,
                                  &context);
        if (err == READ_TREE_RECURSIVE)
                err = 0;
@@ -286,14 +294,14 @@ static const struct archiver *lookup_archiver(const char *name)
        return NULL;
 }
 
-static int reject_entry(const unsigned char *sha1, const char *base,
-                       int baselen, const char *filename, unsigned mode,
+static int reject_entry(const unsigned char *sha1, struct strbuf *base,
+                       const char *filename, unsigned mode,
                        int stage, void *context)
 {
        int ret = -1;
        if (S_ISDIR(mode)) {
                struct strbuf sb = STRBUF_INIT;
-               strbuf_addstr(&sb, base);
+               strbuf_addbuf(&sb, base);
                strbuf_addstr(&sb, filename);
                if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))
                        ret = READ_TREE_RECURSIVE;
index 5410dacea0699f70cd942837394c06eac99873d1..8adf48de74517f6c4c41db6894d9707e93cc29a8 100644 (file)
@@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
 
 }
 
-static int update_some(const unsigned char *sha1, const char *base, int baselen,
+static int update_some(const unsigned char *sha1, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int len;
@@ -71,11 +71,11 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
        if (S_ISDIR(mode))
                return READ_TREE_RECURSIVE;
 
-       len = baselen + strlen(pathname);
+       len = base->len + strlen(pathname);
        ce = xcalloc(1, cache_entry_size(len));
        hashcpy(ce->sha1, sha1);
-       memcpy(ce->name, base, baselen);
-       memcpy(ce->name + baselen, pathname, len - baselen);
+       memcpy(ce->name, base->buf, base->len);
+       memcpy(ce->name + base->len, pathname, len - base->len);
        ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
        ce->ce_namelen = len;
        ce->ce_mode = create_ce_mode(mode);
index 734aab3a73185964d18c82fe5eb31008bbc409b7..f2a9f0156d8a8b15c7c879355b137b669dea8cf2 100644 (file)
@@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
 }
 
 static int show_tree_object(const unsigned char *sha1,
-               const char *base, int baselen,
+               struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
index 51184dfa2efa46323e79c4504121bf5fe948a6d2..1ab03812453970ecdaafccb2b4c24a06bb12651a 100644 (file)
@@ -61,7 +61,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
        }
 }
 
-static int show_tree(const unsigned char *sha1, const char *base, int baselen,
+static int show_tree(const unsigned char *sha1, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int retval = 0;
@@ -79,7 +79,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
                 */
                type = commit_type;
        } else if (S_ISDIR(mode)) {
-               if (show_recursive(base, baselen, pathname)) {
+               if (show_recursive(base->buf, base->len, pathname)) {
                        retval = READ_TREE_RECURSIVE;
                        if (!(ls_options & LS_SHOW_TREES))
                                return retval;
@@ -90,7 +90,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
                return 0;
 
        if (chomp_prefix &&
-           (baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
+           (base->len < chomp_prefix ||
+            memcmp(ls_tree_prefix, base->buf, chomp_prefix)))
                return 0;
 
        if (!(ls_options & LS_NAME_ONLY)) {
@@ -112,7 +113,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
                        printf("%06o %s %s\t", mode, type,
                               find_unique_abbrev(sha1, abbrev));
        }
-       write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
+       write_name_quotedpfx(base->buf + chomp_prefix, base->len - chomp_prefix,
                          pathname, stdout, line_termination);
        return retval;
 }
index fdb7d0f10ba471bcdff26dc87851d7df34fdc971..25c067e4a71f1ed2c5d4971d41ab6b4e1108e9e4 100644 (file)
@@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o)
 }
 
 static int save_files_dirs(const unsigned char *sha1,
-               const char *base, int baselen, const char *path,
+               struct strbuf *base, const char *path,
                unsigned int mode, int stage, void *context)
 {
-       int len = strlen(path);
-       char *newpath = xmalloc(baselen + len + 1);
+       int baselen = base->len;
        struct merge_options *o = context;
 
-       memcpy(newpath, base, baselen);
-       memcpy(newpath + baselen, path, len);
-       newpath[baselen + len] = '\0';
+       strbuf_addstr(base, path);
 
        if (S_ISDIR(mode))
-               string_list_insert(&o->current_directory_set, newpath);
+               string_list_insert(&o->current_directory_set, base->buf);
        else
-               string_list_insert(&o->current_file_set, newpath);
-       free(newpath);
+               string_list_insert(&o->current_file_set, base->buf);
 
+       strbuf_setlen(base, baselen);
        return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
 }
 
diff --git a/tree.c b/tree.c
index bb02c1caa4ff6a8af40b89498de3af3381272999..58ebfce1bca609b0f7119eb210345c2065d02f40 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -30,9 +30,12 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b
        return add_cache_entry(ce, opt);
 }
 
-static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
+static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
+                         const char *pathname, unsigned mode, int stage,
+                         void *context)
 {
-       return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
+       return read_one_entry_opt(sha1, base->buf, base->len, pathname,
+                                 mode, stage,
                                  ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
 }
 
@@ -40,9 +43,12 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel
  * This is used when the caller knows there is no existing entries at
  * the stage that will conflict with the entry being added.
  */
-static int read_one_entry_quick(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
+static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
+                               const char *pathname, unsigned mode, int stage,
+                               void *context)
 {
-       return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
+       return read_one_entry_opt(sha1, base->buf, base->len, pathname,
+                                 mode, stage,
                                  ADD_CACHE_JUST_APPEND);
 }
 
@@ -70,7 +76,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
                                continue;
                }
 
-               switch (fn(entry.sha1, base->buf, base->len,
+               switch (fn(entry.sha1, base,
                           entry.path, entry.mode, stage, context)) {
                case 0:
                        continue;
diff --git a/tree.h b/tree.h
index d84ac63e511c30ae4e1c8ee2b9719d67fd9424da..d24125f84f01cddaecbd047b24e3a710014560a4 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -4,6 +4,7 @@
 #include "object.h"
 
 extern const char *tree_type;
+struct strbuf;
 
 struct tree {
        struct object object;
@@ -22,7 +23,7 @@ void free_tree_buffer(struct tree *tree);
 struct tree *parse_tree_indirect(const unsigned char *sha1);
 
 #define READ_TREE_RECURSIVE 1
-typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int, void *);
+typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);
 
 extern int read_tree_recursive(struct tree *tree,
                               const char *base, int baselen,