tree.c: update read_tree_recursive callback to pass strbuf as base
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>
Nguyễn Thái Ngọc Duy committed
Nov 30, 2014 at 16:05 UTC
6a0b0b6de996e2ac7eeb951e3d08f577c11c7e54
7 files changed
+50
-37
archive.c
+21
-13
@@ -157,18 +157,26 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
157
return write_entry(args, sha1, path.buf, path.len, mode);
158
}
159
160
+static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base,
161
+ const char *filename, unsigned mode, int stage,
162
+ void *context)
163
+{
164
+ return write_archive_entry(sha1, base->buf, base->len,
165
+ filename, mode, stage, context);
166
+}
167
+
168
static void queue_directory(const unsigned char *sha1,
161
- const char *base, int baselen, const char *filename,
169
+ struct strbuf *base, const char *filename,
170
unsigned mode, int stage, struct archiver_context *c)
171
{
172
struct directory *d;
165
- d = xmallocz(sizeof(*d) + baselen + 1 + strlen(filename));
173
+ d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
174
d->up = c->bottom;
167
- d->baselen = baselen;
175
+ d->baselen = base->len;
176
d->mode = mode;
177
d->stage = stage;
178
c->bottom = d;
171
- d->len = sprintf(d->path, "%.*s%s/", baselen, base, filename);
179
+ d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
180
hashcpy(d->sha1, sha1);
181
}
182
@@ -191,28 +199,28 @@ static int write_directory(struct archiver_context *c)
199
}
200
201
static int queue_or_write_archive_entry(const unsigned char *sha1,
194
- const char *base, int baselen, const char *filename,
202
+ struct strbuf *base, const char *filename,
203
unsigned mode, int stage, void *context)
204
{
205
struct archiver_context *c = context;
206
207
while (c->bottom &&
200
- !(baselen >= c->bottom->len &&
201
- !strncmp(base, c->bottom->path, c->bottom->len))) {
208
+ !(base->len >= c->bottom->len &&
209
+ !strncmp(base->buf, c->bottom->path, c->bottom->len))) {
210
struct directory *next = c->bottom->up;
211
free(c->bottom);
212
c->bottom = next;
213
}
214
215
if (S_ISDIR(mode)) {
208
- queue_directory(sha1, base, baselen, filename,
216
+ queue_directory(sha1, base, filename,
217
mode, stage, c);
218
return READ_TREE_RECURSIVE;
219
}
220
221
if (write_directory(c))
222
return -1;
215
- return write_archive_entry(sha1, base, baselen, filename, mode,
223
+ return write_archive_entry(sha1, base->buf, base->len, filename, mode,
224
stage, context);
225
}
226
@@ -260,7 +268,7 @@ int write_archive_entries(struct archiver_args *args,
268
err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
269
args->pathspec.has_wildcard ?
270
queue_or_write_archive_entry :
263
- write_archive_entry,
271
+ write_archive_entry_buf,
272
&context);
273
if (err == READ_TREE_RECURSIVE)
274
err = 0;
@@ -286,14 +294,14 @@ static const struct archiver *lookup_archiver(const char *name)
294
return NULL;
295
}
296
289
-static int reject_entry(const unsigned char *sha1, const char *base,
290
- int baselen, const char *filename, unsigned mode,
297
+static int reject_entry(const unsigned char *sha1, struct strbuf *base,
298
+ const char *filename, unsigned mode,
299
int stage, void *context)
300
{
301
int ret = -1;
302
if (S_ISDIR(mode)) {
303
struct strbuf sb = STRBUF_INIT;
296
- strbuf_addstr(&sb, base);
304
+ strbuf_addbuf(&sb, base);
305
strbuf_addstr(&sb, filename);
306
if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))
307
ret = READ_TREE_RECURSIVE;
builtin/checkout.c
+4
-4
@@ -62,7 +62,7 @@ static int post_checkout_hook(struct commit *old, struct commit *new,
62
63
}
64
65
-static int update_some(const unsigned char *sha1, const char *base, int baselen,
65
+static int update_some(const unsigned char *sha1, struct strbuf *base,
66
const char *pathname, unsigned mode, int stage, void *context)
67
{
68
int len;
@@ -71,11 +71,11 @@ static int update_some(const unsigned char *sha1, const char *base, int baselen,
71
if (S_ISDIR(mode))
72
return READ_TREE_RECURSIVE;
73
74
- len = baselen + strlen(pathname);
74
+ len = base->len + strlen(pathname);
75
ce = xcalloc(1, cache_entry_size(len));
76
hashcpy(ce->sha1, sha1);
77
- memcpy(ce->name, base, baselen);
78
- memcpy(ce->name + baselen, pathname, len - baselen);
77
+ memcpy(ce->name, base->buf, base->len);
78
+ memcpy(ce->name + base->len, pathname, len - base->len);
79
ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
80
ce->ce_namelen = len;
81
ce->ce_mode = create_ce_mode(mode);
builtin/log.c
+1
-1
@@ -489,7 +489,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
489
}
490
491
static int show_tree_object(const unsigned char *sha1,
492
- const char *base, int baselen,
492
+ struct strbuf *base,
493
const char *pathname, unsigned mode, int stage, void *context)
494
{
495
printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
builtin/ls-tree.c
+5
-4
@@ -61,7 +61,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
61
}
62
}
63
64
-static int show_tree(const unsigned char *sha1, const char *base, int baselen,
64
+static int show_tree(const unsigned char *sha1, struct strbuf *base,
65
const char *pathname, unsigned mode, int stage, void *context)
66
{
67
int retval = 0;
@@ -79,7 +79,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
79
*/
80
type = commit_type;
81
} else if (S_ISDIR(mode)) {
82
- if (show_recursive(base, baselen, pathname)) {
82
+ if (show_recursive(base->buf, base->len, pathname)) {
83
retval = READ_TREE_RECURSIVE;
84
if (!(ls_options & LS_SHOW_TREES))
85
return retval;
@@ -90,7 +90,8 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
90
return 0;
91
92
if (chomp_prefix &&
93
- (baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
93
+ (base->len < chomp_prefix ||
94
+ memcmp(ls_tree_prefix, base->buf, chomp_prefix)))
95
return 0;
96
97
if (!(ls_options & LS_NAME_ONLY)) {
@@ -112,7 +113,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
113
printf("%06o %s %s\t", mode, type,
114
find_unique_abbrev(sha1, abbrev));
115
}
115
- write_name_quotedpfx(base + chomp_prefix, baselen - chomp_prefix,
116
+ write_name_quotedpfx(base->buf + chomp_prefix, base->len - chomp_prefix,
117
pathname, stdout, line_termination);
118
return retval;
119
}
merge-recursive.c
+6
-9
@@ -275,23 +275,20 @@ struct tree *write_tree_from_memory(struct merge_options *o)
275
}
276
277
static int save_files_dirs(const unsigned char *sha1,
278
- const char *base, int baselen, const char *path,
278
+ struct strbuf *base, const char *path,
279
unsigned int mode, int stage, void *context)
280
{
281
- int len = strlen(path);
282
- char *newpath = xmalloc(baselen + len + 1);
281
+ int baselen = base->len;
282
struct merge_options *o = context;
283
285
- memcpy(newpath, base, baselen);
286
- memcpy(newpath + baselen, path, len);
287
- newpath[baselen + len] = '\0';
284
+ strbuf_addstr(base, path);
285
286
if (S_ISDIR(mode))
290
- string_list_insert(&o->current_directory_set, newpath);
287
+ string_list_insert(&o->current_directory_set, base->buf);
288
else
292
- string_list_insert(&o->current_file_set, newpath);
293
- free(newpath);
289
+ string_list_insert(&o->current_file_set, base->buf);
290
291
+ strbuf_setlen(base, baselen);
292
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
293
}
294
tree.c
+11
-5
@@ -30,9 +30,12 @@ static int read_one_entry_opt(const unsigned char *sha1, const char *base, int b
30
return add_cache_entry(ce, opt);
31
}
32
33
-static int read_one_entry(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
33
+static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
34
+ const char *pathname, unsigned mode, int stage,
35
+ void *context)
36
{
35
- return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
37
+ return read_one_entry_opt(sha1, base->buf, base->len, pathname,
38
+ mode, stage,
39
ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
40
}
41
@@ -40,9 +43,12 @@ static int read_one_entry(const unsigned char *sha1, const char *base, int basel
43
* This is used when the caller knows there is no existing entries at
44
* the stage that will conflict with the entry being added.
45
*/
43
-static int read_one_entry_quick(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *context)
46
+static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
47
+ const char *pathname, unsigned mode, int stage,
48
+ void *context)
49
{
45
- return read_one_entry_opt(sha1, base, baselen, pathname, mode, stage,
50
+ return read_one_entry_opt(sha1, base->buf, base->len, pathname,
51
+ mode, stage,
52
ADD_CACHE_JUST_APPEND);
53
}
54
@@ -70,7 +76,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
76
continue;
77
}
78
73
- switch (fn(entry.sha1, base->buf, base->len,
79
+ switch (fn(entry.sha1, base,
80
entry.path, entry.mode, stage, context)) {
81
case 0:
82
continue;
tree.h
+2
-1
@@ -4,6 +4,7 @@
4
#include "object.h"
5
6
extern const char *tree_type;
7
+struct strbuf;
8
9
struct tree {
10
struct object object;
@@ -22,7 +23,7 @@ void free_tree_buffer(struct tree *tree);
23
struct tree *parse_tree_indirect(const unsigned char *sha1);
24
25
#define READ_TREE_RECURSIVE 1
25
-typedef int (*read_tree_fn_t)(const unsigned char *, const char *, int, const char *, unsigned int, int, void *);
26
+typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);
27
28
extern int read_tree_recursive(struct tree *tree,
29
const char *base, int baselen,