summaryrefslogtreecommitdiff
path: root/contrib/perf/03-git-decoration-type-elision.patch
blob: c1ac3f8d875b2f0bfdec25fd7ada01759c0b7c08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
diff --git a/log-tree.c b/log-tree.c
--- a/log-tree.c
+++ b/log-tree.c
@@ -174,9 +174,20 @@
 		return 0;
 	}
 
-	objtype = odb_read_object_info(the_repository->objects, ref->oid, NULL);
-	if (objtype < 0)
-		return 0;
+	if (ref->peeled_oid) {
+		/*
+		 * packed-refs only records a peeled line for refs that point
+		 * at a tag object, so the ref backend has already told us the
+		 * type. Asking the object store again costs a binary search
+		 * through the pack index, per ref, per process.
+		 */
+		objtype = OBJ_TAG;
+	} else {
+		objtype = odb_read_object_info(the_repository->objects,
+					       ref->oid, NULL);
+		if (objtype < 0)
+			return 0;
+	}
 	obj = lookup_object_by_type(the_repository, ref->oid, objtype);
 
 	for (i = 0; i < ARRAY_SIZE(ref_namespace); i++) {
@@ -206,12 +217,14 @@
 		 */
 		if (ref->peeled_oid &&
 		    !reference_get_peeled_oid(the_repository, ref, &peeled)) {
-			enum object_type ptype;
-			ptype = odb_read_object_info(the_repository->objects,
-						     &peeled, NULL);
-			if (ptype < 0)
-				return 0;
-			obj = lookup_object_by_type(the_repository, &peeled, ptype);
+			/*
+			 * The decoration only ever uses this object as a key;
+			 * nothing reads its type. lookup_unknown_object()
+			 * hands back the same struct that a later
+			 * lookup_commit() will fill in, and skips a second
+			 * pack index search.
+			 */
+			obj = lookup_unknown_object(the_repository, &peeled);
 			if (obj)
 				add_name_decoration(DECORATION_REF_TAG, ref->name, obj);
 			return 0;