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

[PATCH 3/3] fast-import: improve efficiency of tree_content_set

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

This patch keeps the tree entries of a tree_content in order, sorted by entry name. The lookup in find_tree_entry now performs a binary search instead of a linear search.

Signed-off-by: Jeff King <peff@peff.net>
---
 fast-import.c |   48 +++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/fast-import.c b/fast-import.c
index ac14a5a..4cd01ee 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -594,13 +594,47 @@ static struct tree_content *grow_tree_content(
 	return r;
 }
 
+static int find_tree_entry_bsearch(struct tree_content *t,
+				   struct atom_str *s,
+				   int *found)
+{
+	int high, low, mid=0, cmp=-1;
+	low = 0;
+	high = t->entry_count - 1;
+	while (low <= high) {
+		mid = low + ((high - low) / 2);
+		cmp = strcmp(s->str_dat, t->entries[mid]->name->str_dat);
+		if (cmp < 0)
+			high = mid - 1;
+		else if (cmp > 0)
+			low = mid + 1;
+		else {
+			*found = 1;
+			return mid;
+		}
+	}
+	*found = 0;
+	return cmp < 0 ? mid : mid + 1;
+}
+
 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;
+	int i, found;
+	i = find_tree_entry_bsearch(t, s, &found);
+	return found ? i : -1;
+}
+
+static void insert_tree_content(struct tree_content *t, struct tree_entry *e)
+{
+	int i, found;
+
+	i = find_tree_entry_bsearch(t, e->name, &found);
+	if (found)
+		die("BUG: duplicate tree content");
+	memmove(t->entries + i + 1, t->entries + i,
+			sizeof(t->entries[0]) * (t->entry_count - i));
+	t->entries[i] = e;
+	t->entry_count++;
 }
 
 static struct tree_entry *new_tree_entry(void)
@@ -1080,7 +1114,7 @@ static void load_tree(struct tree_entry *root)
 		hashcpy(e->versions[1].sha1, (unsigned char*)c);
 		c += 20;
 
-		t->entries[t->entry_count++] = e;
+		insert_tree_content(t, e);
 	}
 	free(buf);
 }
@@ -1241,7 +1275,7 @@ static int tree_content_set(
 	e->name = name;
 	e->versions[0].mode = 0;
 	hashclr(e->versions[0].sha1);
-	t->entries[t->entry_count++] = e;
+	insert_tree_content(t, e);
 	if (slash1) {
 		e->tree = new_tree_content(8);
 		e->versions[1].mode = S_IFDIR;
-- 
1.5.0.3.931.g55c05
Previous: Shawn O. PearceNext: Jeff King
Message 8 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.