diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2013-09-12 17:38:01 +0700 |
---|---|---|
committer | Nicolas Pitre <nico@fluxnic.net> | 2013-09-13 21:00:27 -0400 |
commit | 3a965a953675aa6f3282d1d50e2a88f57b39b142 (patch) | |
tree | afd66ebf6880f970b9597fd1af60b9bc2b49e178 | |
parent | b8c2ae07bcebfa1981d86e6e997c36b5bd048f23 (diff) | |
download | git-3a965a953675aa6f3282d1d50e2a88f57b39b142.tar.gz |
pack v4: avoid strlen() in tree_entry_prefix
We do know the length of the path name of an tree entry from the tree
dictionary. On an unoptimized build, this cuts down "git rev-list
--objects v1.8.4"'s time from 6.2s to 5.8s. This difference is less on
optimized builds.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
-rw-r--r-- | packv4-parse.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/packv4-parse.c b/packv4-parse.c index dc1708e799..fe01de05a2 100644 --- a/packv4-parse.c +++ b/packv4-parse.c @@ -50,15 +50,17 @@ struct packv4_dict *pv4_create_dict(const unsigned char *data, int dict_size) return NULL; } - dict = xmalloc(sizeof(*dict) + nb_entries * sizeof(dict->offsets[0])); + dict = xmalloc(sizeof(*dict) + + (nb_entries + 1) * sizeof(dict->offsets[0])); dict->data = data; dict->nb_entries = nb_entries; + dict->offsets[0] = 0; cp = data; for (i = 0; i < nb_entries; i++) { - dict->offsets[i] = cp - data; cp += 2; cp += strlen((const char *)cp) + 1; + dict->offsets[i + 1] = cp - data; } return dict; @@ -167,7 +169,8 @@ static void load_path_dict(struct packed_git *p) p->path_dict = paths; } -const unsigned char *get_pathref(struct packed_git *p, unsigned int index) +const unsigned char *get_pathref(struct packed_git *p, unsigned int index, + int *len) { if (!p->path_dict) load_path_dict(p); @@ -176,6 +179,9 @@ const unsigned char *get_pathref(struct packed_git *p, unsigned int index) error("%s: index overflow", __func__); return NULL; } + if (len) + *len = p->path_dict->offsets[index + 1] - + p->path_dict->offsets[index]; return p->path_dict->data + p->path_dict->offsets[index]; } @@ -377,9 +383,9 @@ static int copy_canonical_tree_entries(struct packed_git *p, off_t offset, } static int tree_entry_prefix(unsigned char *buf, unsigned long size, - const unsigned char *path, unsigned mode) + const unsigned char *path, int path_len, + unsigned mode) { - int path_len = strlen((const char *)path) + 1; int mode_len = 0; int len; unsigned char mode_buf[8]; @@ -468,14 +474,15 @@ static int decode_entries(struct packed_git *p, struct pack_window **w_curs, */ const unsigned char *path, *sha1; unsigned mode; - int len; + int len, pathlen; - path = get_pathref(p, what >> 1); + path = get_pathref(p, what >> 1, &pathlen); sha1 = get_sha1ref(p, &scp); if (!path || !sha1) return -1; mode = (path[0] << 8) | path[1]; - len = tree_entry_prefix(*dstp, *sizep, path + 2, mode); + len = tree_entry_prefix(*dstp, *sizep, + path + 2, pathlen - 2, mode); if (!len || len + 20 > *sizep) return -1; hashcpy(*dstp + len, sha1); |