git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/4] pack v4: avoid strlen() in tree_entry_prefix

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Sep 12, 2013, 10:38 UTC
Message-ID
<1378982284-7848-1-git-send-email-pclouds@gmail.com>

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>
---
 packv4-parse.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/packv4-parse.c b/packv4-parse.c
index c00a014..ae3e6a5 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;
@@ -163,7 +165,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);
@@ -172,6 +175,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];
 }
 
@@ -373,9 +379,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];
@@ -463,14 +469,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);
-- 
1.8.2.83.gc99314b
Next: Nguyễn Thái Ngọc Duy
Message 1 of 12 in “pack v4: avoid strlen() in tree_entry_prefix”
  1. 1/4 pack v4: avoid strlen() in tree_entry_prefixNguyễn Thái Ngọc Duy, Sep 12, 2013
  2. 2/4 pack v4: add v4_size to struct delta_base_cache_entryNguyễn Thái Ngọc Duy, Sep 12, 2013
  3. Nicolas PitreSep 13, 2013
  4. Duy NguyenSep 13, 2013
  5. Nicolas PitreSep 14, 2013
  6. Nicolas PitreSep 14, 2013
  7. Duy NguyenSep 15, 2013
  8. Nicolas PitreSep 16, 2013
  9. Duy NguyenSep 16, 2013
  10. 3/4 pack v4: cache flattened v4 trees in delta base cacheNguyễn Thái Ngọc Duy, Sep 12, 2013
  11. 4/4 pack v4: make use of cached v4 trees when unpackingNguyễn Thái Ngọc Duy, Sep 12, 2013
  12. 5/4 pack v4: convert v4 tree to canonical format if found in base cacheNguyễn Thái Ngọc Duy, Sep 12, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.