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

[PATCH v5 2/4] sha1_name: unroll len loop in find_unique_abbrev_r

From
Derrick Stolee <dstolee@microsoft.com>
Date
Oct 12, 2017, 12:02 UTC
Message-ID
<20171012120220.226427-3-dstolee@microsoft.com>
In-Reply-To
<61168095-d392-39d2-ba65-823525239b5c@gmail.com>

Unroll the while loop inside find_unique_abbrev_r to avoid iterating through all loose objects and packfiles multiple times when the short name is longer than the predicted length.

Instead, inspect each object that collides with the estimated abbreviation to find the longest common prefix.

The focus of this change is to refactor the existing method in a way that clearly does not change the current behavior. In some cases, the new method is slower than the previous method. Later changes will correct all performance loss.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 sha1_name.c | 57 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 42 insertions(+), 15 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index c7c5ab376..19603713f 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -474,10 +474,32 @@ static unsigned msb(unsigned long val)
 	return r;
 }
 
-int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
+struct min_abbrev_data {
+	unsigned int init_len;
+	unsigned int cur_len;
+	char *hex;
+};
+
+static int extend_abbrev_len(const struct object_id *oid, void *cb_data)
 {
-	int status, exists;
+	struct min_abbrev_data *mad = cb_data;
+
+	char *hex = oid_to_hex(oid);
+	unsigned int i = mad->init_len;
+	while (mad->hex[i] && mad->hex[i] == hex[i])
+		i++;
+
+	if (i < GIT_MAX_RAWSZ && i >= mad->cur_len)
+		mad->cur_len = i + 1;
+
+	return 0;
+}
 
+int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
+{
+	struct disambiguate_state ds;
+	struct min_abbrev_data mad;
+	struct object_id oid_ret;
 	if (len < 0) {
 		unsigned long count = approximate_object_count();
 		/*
@@ -503,19 +525,24 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
 	sha1_to_hex_r(hex, sha1);
 	if (len == GIT_SHA1_HEXSZ || !len)
 		return GIT_SHA1_HEXSZ;
-	exists = has_sha1_file(sha1);
-	while (len < GIT_SHA1_HEXSZ) {
-		struct object_id oid_ret;
-		status = get_short_oid(hex, len, &oid_ret, GET_OID_QUIETLY);
-		if (exists
-		    ? !status
-		    : status == SHORT_NAME_NOT_FOUND) {
-			hex[len] = 0;
-			return len;
-		}
-		len++;
-	}
-	return len;
+
+	if (init_object_disambiguation(hex, len, &ds) < 0)
+		return -1;
+
+	mad.init_len = len;
+	mad.cur_len = len;
+	mad.hex = hex;
+
+	ds.fn = extend_abbrev_len;
+	ds.always_call_fn = 1;
+	ds.cb_data = (void*)&mad;
+
+	find_short_object_filename(&ds);
+	find_short_packed_object(&ds);
+	(void)finish_object_disambiguation(&ds, &oid_ret);
+
+	hex[mad.cur_len] = 0;
+	return mad.cur_len;
 }
 
 const char *find_unique_abbrev(const unsigned char *sha1, int len)
-- 
2.14.1.538.g56ec8fc98.dirty
Previous: Derrick StoleeNext: Derrick Stolee
Message 19 of 22 in “Improve abbreviation disambiguation”
  1. 0/4 Improve abbreviation disambiguationDerrick Stolee, Oct 8, 2017
  2. 1/4 p4211-line-log.sh: add log --online --raw --parents perf testDerrick Stolee, Oct 8, 2017
  3. 3/4 sha1_name: parse less while finding common prefixDerrick Stolee, Oct 8, 2017
  4. Jeff KingOct 9, 2017
  5. 4/4 sha1_name: minimize OID comparisons during disambiguationDerrick Stolee, Oct 8, 2017
  6. Jeff KingOct 9, 2017
  7. Derrick StoleeOct 10, 2017
  8. Jeff KingOct 10, 2017
  9. Junio C HamanoOct 10, 2017
  10. Jeff KingOct 10, 2017
  11. Derrick StoleeOct 10, 2017
  12. Jeff KingOct 10, 2017
  13. Derrick StoleeOct 11, 2017
  14. 0/4 Improve abbreviation disambiguationDerrick Stolee, Oct 12, 2017
  15. Derrick StoleeOct 12, 2017
  16. Junio C HamanoOct 12, 2017
  17. Jeff KingOct 12, 2017
  18. 3/4 sha1_name: parse less while finding common prefixDerrick Stolee, Oct 12, 2017
  19. 2/4 sha1_name: unroll len loop in find_unique_abbrev_rDerrick Stolee, Oct 12, 2017
  20. 1/4 p4211-line-log.sh: add log --online --raw --parents perf testDerrick Stolee, Oct 12, 2017
  21. 4/4 sha1_name: minimize OID comparisons during disambiguationDerrick Stolee, Oct 12, 2017
  22. 2/4 sha1_name: unroll len loop in find_unique_abbrev_rDerrick Stolee, Oct 8, 2017

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.