summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2013-09-12 17:38:01 +0700
committerNicolas Pitre <nico@fluxnic.net>2013-09-13 21:00:27 -0400
commit3a965a953675aa6f3282d1d50e2a88f57b39b142 (patch)
treeafd66ebf6880f970b9597fd1af60b9bc2b49e178
parentb8c2ae07bcebfa1981d86e6e997c36b5bd048f23 (diff)
downloadgit-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.c23
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);