reftable/record: store "val2" hashes as static arrays

Similar to the preceding commit, convert ref records of type "val2" to store their object IDs in static arrays instead of allocating them for every single record. We're using the same benchmark as in the preceding commit, with `git show-ref --quiet` in a repository with ~350k refs. This time around though the effects aren't this huge. Before: HEAP SUMMARY: in use at exit: 21,163 bytes in 193 blocks total heap usage: 1,419,040 allocs, 1,418,847 frees, 62,153,868 bytes allocated After: HEAP SUMMARY: in use at exit: 21,163 bytes in 193 blocks total heap usage: 1,410,148 allocs, 1,409,955 frees, 61,976,068 bytes allocated This is because "val2"-type records are typically only stored for peeled tags, and the number of annotated tags in the benchmark repository is rather low. Still, it can be seen that this change leads to a reduction of allocations overall, even if only a small one. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jan 3, 2024 at 07:22 UTC b31e3cc620f926273af9346fbda4ff507f60682e
4 files changed +6 -20
reftable/readwrite_test.c
+4 -8
@@ -547,8 +547,6 @@ static void test_table_refs_for(int indexed)
547 uint8_t hash[GIT_SHA1_RAWSZ];
548 char fill[51] = { 0 };
549 char name[100];
550 - uint8_t hash1[GIT_SHA1_RAWSZ];
551 - uint8_t hash2[GIT_SHA1_RAWSZ];
550 struct reftable_ref_record ref = { NULL };
551
552 memset(hash, i, sizeof(hash));
@@ -558,11 +556,9 @@ static void test_table_refs_for(int indexed)
556 name[40] = 0;
557 ref.refname = name;
558
561 - set_test_hash(hash1, i / 4);
562 - set_test_hash(hash2, 3 + i / 4);
559 ref.value_type = REFTABLE_REF_VAL2;
564 - ref.value.val2.value = hash1;
565 - ref.value.val2.target_value = hash2;
560 + set_test_hash(ref.value.val2.value, i / 4);
561 + set_test_hash(ref.value.val2.target_value, 3 + i / 4);
562
563 /* 80 bytes / entry, so 3 entries per block. Yields 17
564 */
@@ -570,8 +566,8 @@ static void test_table_refs_for(int indexed)
566 n = reftable_writer_add_ref(w, &ref);
567 EXPECT(n == 0);
568
573 - if (!memcmp(hash1, want_hash, GIT_SHA1_RAWSZ) ||
574 - !memcmp(hash2, want_hash, GIT_SHA1_RAWSZ)) {
569 + if (!memcmp(ref.value.val2.value, want_hash, GIT_SHA1_RAWSZ) ||
570 + !memcmp(ref.value.val2.target_value, want_hash, GIT_SHA1_RAWSZ)) {
571 want_names[want_names_len++] = xstrdup(name);
572 }
573 }
reftable/record.c
-6
@@ -222,9 +222,7 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec,
222 memcpy(ref->value.val1, src->value.val1, hash_size);
223 break;
224 case REFTABLE_REF_VAL2:
225 - ref->value.val2.value = reftable_malloc(hash_size);
225 memcpy(ref->value.val2.value, src->value.val2.value, hash_size);
227 - ref->value.val2.target_value = reftable_malloc(hash_size);
226 memcpy(ref->value.val2.target_value,
227 src->value.val2.target_value, hash_size);
228 break;
@@ -298,8 +296,6 @@ void reftable_ref_record_release(struct reftable_ref_record *ref)
296 reftable_free(ref->value.symref);
297 break;
298 case REFTABLE_REF_VAL2:
301 - reftable_free(ref->value.val2.target_value);
302 - reftable_free(ref->value.val2.value);
299 break;
300 case REFTABLE_REF_VAL1:
301 break;
@@ -401,11 +397,9 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key,
397 return -1;
398 }
399
404 - r->value.val2.value = reftable_malloc(hash_size);
400 memcpy(r->value.val2.value, in.buf, hash_size);
401 string_view_consume(&in, hash_size);
402
408 - r->value.val2.target_value = reftable_malloc(hash_size);
403 memcpy(r->value.val2.target_value, in.buf, hash_size);
404 string_view_consume(&in, hash_size);
405 break;
reftable/record_test.c
-4
@@ -122,11 +122,7 @@ static void test_reftable_ref_record_roundtrip(void)
122 set_hash(in.u.ref.value.val1, 1);
123 break;
124 case REFTABLE_REF_VAL2:
125 - in.u.ref.value.val2.value =
126 - reftable_malloc(GIT_SHA1_RAWSZ);
125 set_hash(in.u.ref.value.val2.value, 1);
128 - in.u.ref.value.val2.target_value =
129 - reftable_malloc(GIT_SHA1_RAWSZ);
126 set_hash(in.u.ref.value.val2.target_value, 2);
127 break;
128 case REFTABLE_REF_SYMREF:
reftable/reftable-record.h
+2 -2
@@ -41,8 +41,8 @@ struct reftable_ref_record {
41 union {
42 unsigned char val1[GIT_MAX_RAWSZ];
43 struct {
44 - uint8_t *value; /* first value, malloced hash */
45 - uint8_t *target_value; /* second value, malloced hash */
44 + unsigned char value[GIT_MAX_RAWSZ]; /* first hash */
45 + unsigned char target_value[GIT_MAX_RAWSZ]; /* second hash */
46 } val2;
47 char *symref; /* referent, malloced 0-terminated string */
48 } value;