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

[PATCH 2/3] fast-import: tree allocation cleanups

From
Jeff King <peff@peff.net>
Date
Mar 10, 2007, 19:21 UTC
Message-ID
<20070310192114.GA3875@coredump.intra.peff.net>
In-Reply-To
<20070310191515.GA3416@coredump.intra.peff.net>

These cleanups are in preparation for improving the efficiency of the tree-construction code. There should be no functionality changes.

1. Insert entries into tree_content _after_ they have a name
   assigned. This means that the insertion can use a smarter
   data structure than an unordered list.
2. Factor out the linear search for existing tree entries in
   tree_content_set, which will make it simpler to change.
   Most of the line changes here are simply indentation changes.
Signed-off-by: Jeff King <peff@peff.net>
---
 fast-import.c |   65 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index 81bc6ea..ac14a5a 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -594,6 +594,15 @@ static struct tree_content *grow_tree_content(
 	return r;
 }
 
+static int find_tree_entry(struct tree_content *t, struct atom_str *s)
+{
+	int i;
+	for (i = 0; i < t->entry_count; i++)
+		if (!strcmp(t->entries[i]->name->str_dat, s->str_dat))
+			return i;
+	return -1;
+}
+
 static struct tree_entry *new_tree_entry(void)
 {
 	struct tree_entry *e;
@@ -1059,7 +1068,6 @@ static void load_tree(struct tree_entry *root)
 
 		if (t->entry_count == t->entry_capacity)
 			root->tree = t = grow_tree_content(t, t->entry_count);
-		t->entries[t->entry_count++] = e;
 
 		e->tree = NULL;
 		c = get_mode(c, &e->versions[1].mode);
@@ -1071,6 +1079,8 @@ static void load_tree(struct tree_entry *root)
 		hashcpy(e->versions[0].sha1, (unsigned char*)c);
 		hashcpy(e->versions[1].sha1, (unsigned char*)c);
 		c += 20;
+
+		t->entries[t->entry_count++] = e;
 	}
 	free(buf);
 }
@@ -1187,6 +1197,7 @@ static int tree_content_set(
 	const char *slash1;
 	unsigned int i, n;
 	struct tree_entry *e;
+	struct atom_str *name;
 
 	slash1 = strchr(p, '/');
 	if (slash1)
@@ -1194,40 +1205,40 @@ static int tree_content_set(
 	else
 		n = strlen(p);
 
-	for (i = 0; i < t->entry_count; i++) {
+	name = to_atom(p, n);
+	i = find_tree_entry(t, name);
+	if (i != -1) {
 		e = t->entries[i];
-		if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
-			if (!slash1) {
-				if (e->versions[1].mode == mode
-						&& !hashcmp(e->versions[1].sha1, sha1))
-					return 0;
-				e->versions[1].mode = mode;
-				hashcpy(e->versions[1].sha1, sha1);
-				if (e->tree) {
-					release_tree_content_recursive(e->tree);
-					e->tree = NULL;
-				}
-				hashclr(root->versions[1].sha1);
-				return 1;
-			}
-			if (!S_ISDIR(e->versions[1].mode)) {
-				e->tree = new_tree_content(8);
-				e->versions[1].mode = S_IFDIR;
-			}
-			if (!e->tree)
-				load_tree(e);
-			if (tree_content_set(e, slash1 + 1, sha1, mode)) {
-				hashclr(root->versions[1].sha1);
-				return 1;
+		if (!slash1) {
+			if (e->versions[1].mode == mode
+					&& !hashcmp(e->versions[1].sha1, sha1))
+				return 0;
+			e->versions[1].mode = mode;
+			hashcpy(e->versions[1].sha1, sha1);
+			if (e->tree) {
+				release_tree_content_recursive(e->tree);
+				e->tree = NULL;
 			}
-			return 0;
+			hashclr(root->versions[1].sha1);
+			return 1;
+		}
+		if (!S_ISDIR(e->versions[1].mode)) {
+			e->tree = new_tree_content(8);
+			e->versions[1].mode = S_IFDIR;
+		}
+		if (!e->tree)
+			load_tree(e);
+		if (tree_content_set(e, slash1 + 1, sha1, mode)) {
+			hashclr(root->versions[1].sha1);
+			return 1;
 		}
+		return 0;
 	}
 
 	if (t->entry_count == t->entry_capacity)
 		root->tree = t = grow_tree_content(t, t->entry_count);
 	e = new_tree_entry();
-	e->name = to_atom(p, (unsigned short)n);
+	e->name = name;
 	e->versions[0].mode = 0;
 	hashclr(e->versions[0].sha1);
 	t->entries[t->entry_count++] = e;
-- 
1.5.0.3.931.g55c05
Previous: Jeff KingNext: Shawn O. Pearce
Message 3 of 15 in “fast-import slow on large directories”
  1. 0/3 fast-import slow on large directoriesJeff King, Mar 10, 2007
  2. 1/3 fast-import: grow tree storage more aggressivelyJeff King, Mar 10, 2007
  3. 2/3 fast-import: tree allocation cleanupsJeff King, Mar 10, 2007
  4. Shawn O. PearceMar 11, 2007
  5. Jeff KingMar 11, 2007
  6. Jeff KingMar 11, 2007
  7. Shawn O. PearceMar 12, 2007
  8. 3/3 fast-import: improve efficiency of tree_content_setJeff King, Mar 10, 2007
  9. Jeff KingMar 10, 2007
  10. fast-import: use binary search in tree_content_removeJeff King, Mar 10, 2007
  11. Shawn O. PearceMar 11, 2007
  12. Jeff KingMar 11, 2007
  13. Jeff KingMar 11, 2007
  14. Shawn O. PearceMar 11, 2007
  15. Shawn O. PearceMar 12, 2007

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.