reftable: add print functions to the record types

This isn't used per se, but it is useful for debugging, especially Windows CI failures. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Han-Wen Nienhuys committed Jan 20, 2022 at 15:12 UTC 01033de49f26b75afd1e868d56c332c60b141faa
3 files changed +95 -15
reftable/record.c
+71 -14
@@ -255,8 +255,8 @@ static void hex_format(char *dest, uint8_t *src, int hash_size)
255 }
256 }
257
258 -void reftable_ref_record_print(const struct reftable_ref_record *ref,
259 - uint32_t hash_id)
258 +static void reftable_ref_record_print_sz(const struct reftable_ref_record *ref,
259 + int hash_size)
260 {
261 char hex[GIT_MAX_HEXSZ + 1] = { 0 }; /* BUG */
262 printf("ref{%s(%" PRIu64 ") ", ref->refname, ref->update_index);
@@ -265,14 +265,14 @@ void reftable_ref_record_print(const struct reftable_ref_record *ref,
265 printf("=> %s", ref->value.symref);
266 break;
267 case REFTABLE_REF_VAL2:
268 - hex_format(hex, ref->value.val2.value, hash_size(hash_id));
268 + hex_format(hex, ref->value.val2.value, hash_size);
269 printf("val 2 %s", hex);
270 hex_format(hex, ref->value.val2.target_value,
271 - hash_size(hash_id));
271 + hash_size);
272 printf("(T %s)", hex);
273 break;
274 case REFTABLE_REF_VAL1:
275 - hex_format(hex, ref->value.val1, hash_size(hash_id));
275 + hex_format(hex, ref->value.val1, hash_size);
276 printf("val 1 %s", hex);
277 break;
278 case REFTABLE_REF_DELETION:
@@ -282,6 +282,11 @@ void reftable_ref_record_print(const struct reftable_ref_record *ref,
282 printf("}\n");
283 }
284
285 +void reftable_ref_record_print(const struct reftable_ref_record *ref,
286 + uint32_t hash_id) {
287 + reftable_ref_record_print_sz(ref, hash_size(hash_id));
288 +}
289 +
290 static void reftable_ref_record_release_void(void *rec)
291 {
292 reftable_ref_record_release(rec);
@@ -443,6 +448,12 @@ static int reftable_ref_record_equal_void(const void *a,
448 return reftable_ref_record_equal(ra, rb, hash_size);
449 }
450
451 +static void reftable_ref_record_print_void(const void *rec,
452 + int hash_size)
453 +{
454 + reftable_ref_record_print_sz((struct reftable_ref_record *) rec, hash_size);
455 +}
456 +
457 static struct reftable_record_vtable reftable_ref_record_vtable = {
458 .key = &reftable_ref_record_key,
459 .type = BLOCK_TYPE_REF,
@@ -453,6 +464,7 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
464 .release = &reftable_ref_record_release_void,
465 .is_deletion = &reftable_ref_record_is_deletion_void,
466 .equal = &reftable_ref_record_equal_void,
467 + .print = &reftable_ref_record_print_void,
468 };
469
470 static void reftable_obj_record_key(const void *r, struct strbuf *dest)
@@ -471,6 +483,21 @@ static void reftable_obj_record_release(void *rec)
483 memset(obj, 0, sizeof(struct reftable_obj_record));
484 }
485
486 +static void reftable_obj_record_print(const void *rec, int hash_size)
487 +{
488 + const struct reftable_obj_record *obj = rec;
489 + char hex[GIT_MAX_HEXSZ + 1] = { 0 };
490 + struct strbuf offset_str = STRBUF_INIT;
491 + int i;
492 +
493 + for (i = 0; i < obj->offset_len; i++)
494 + strbuf_addf(&offset_str, "%" PRIu64 " ", obj->offsets[i]);
495 + hex_format(hex, obj->hash_prefix, obj->hash_prefix_len);
496 + printf("prefix %s (len %d), offsets [%s]\n",
497 + hex, obj->hash_prefix_len, offset_str.buf);
498 + strbuf_release(&offset_str);
499 +}
500 +
501 static void reftable_obj_record_copy_from(void *rec, const void *src_rec,
502 int hash_size)
503 {
@@ -617,31 +644,41 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
644 .release = &reftable_obj_record_release,
645 .is_deletion = &not_a_deletion,
646 .equal = &reftable_obj_record_equal_void,
647 + .print = &reftable_obj_record_print,
648 };
649
622 -void reftable_log_record_print(struct reftable_log_record *log,
623 - uint32_t hash_id)
650 +static void reftable_log_record_print_sz(struct reftable_log_record *log,
651 + int hash_size)
652 {
653 char hex[GIT_MAX_HEXSZ + 1] = { 0 };
654
655 switch (log->value_type) {
656 case REFTABLE_LOG_DELETION:
629 - printf("log{%s(%" PRIu64 ") delete", log->refname,
657 + printf("log{%s(%" PRIu64 ") delete\n", log->refname,
658 log->update_index);
659 break;
660 case REFTABLE_LOG_UPDATE:
661 printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n",
634 - log->refname, log->update_index, log->value.update.name,
635 - log->value.update.email, log->value.update.time,
662 + log->refname, log->update_index,
663 + log->value.update.name ? log->value.update.name : "",
664 + log->value.update.email ? log->value.update.email : "",
665 + log->value.update.time,
666 log->value.update.tz_offset);
637 - hex_format(hex, log->value.update.old_hash, hash_size(hash_id));
667 + hex_format(hex, log->value.update.old_hash, hash_size);
668 printf("%s => ", hex);
639 - hex_format(hex, log->value.update.new_hash, hash_size(hash_id));
640 - printf("%s\n\n%s\n}\n", hex, log->value.update.message);
669 + hex_format(hex, log->value.update.new_hash, hash_size);
670 + printf("%s\n\n%s\n}\n", hex,
671 + log->value.update.message ? log->value.update.message : "");
672 break;
673 }
674 }
675
676 +void reftable_log_record_print(struct reftable_log_record *log,
677 + uint32_t hash_id)
678 +{
679 + reftable_log_record_print_sz(log, hash_size(hash_id));
680 +}
681 +
682 static void reftable_log_record_key(const void *r, struct strbuf *dest)
683 {
684 const struct reftable_log_record *rec =
@@ -959,6 +996,11 @@ static int reftable_log_record_is_deletion_void(const void *p)
996 (const struct reftable_log_record *)p);
997 }
998
999 +static void reftable_log_record_print_void(const void *rec, int hash_size)
1000 +{
1001 + reftable_log_record_print_sz((struct reftable_log_record*)rec, hash_size);
1002 +}
1003 +
1004 static struct reftable_record_vtable reftable_log_record_vtable = {
1005 .key = &reftable_log_record_key,
1006 .type = BLOCK_TYPE_LOG,
@@ -968,7 +1010,8 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
1010 .decode = &reftable_log_record_decode,
1011 .release = &reftable_log_record_release_void,
1012 .is_deletion = &reftable_log_record_is_deletion_void,
971 - .equal = &reftable_log_record_equal_void
1013 + .equal = &reftable_log_record_equal_void,
1014 + .print = &reftable_log_record_print_void,
1015 };
1016
1017 static void reftable_index_record_key(const void *r, struct strbuf *dest)
@@ -1043,6 +1086,13 @@ static int reftable_index_record_equal(const void *a, const void *b, int hash_si
1086 return ia->offset == ib->offset && !strbuf_cmp(&ia->last_key, &ib->last_key);
1087 }
1088
1089 +static void reftable_index_record_print(const void *rec, int hash_size)
1090 +{
1091 + const struct reftable_index_record *idx = rec;
1092 + /* TODO: escape null chars? */
1093 + printf("\"%s\" %" PRIu64 "\n", idx->last_key.buf, idx->offset);
1094 +}
1095 +
1096 static struct reftable_record_vtable reftable_index_record_vtable = {
1097 .key = &reftable_index_record_key,
1098 .type = BLOCK_TYPE_INDEX,
@@ -1053,6 +1103,7 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
1103 .release = &reftable_index_record_release,
1104 .is_deletion = &not_a_deletion,
1105 .equal = &reftable_index_record_equal,
1106 + .print = &reftable_index_record_print,
1107 };
1108
1109 void reftable_record_key(struct reftable_record *rec, struct strbuf *dest)
@@ -1255,3 +1306,9 @@ struct reftable_record reftable_new_record(uint8_t typ)
1306 }
1307 return clean;
1308 }
1309 +
1310 +void reftable_record_print(struct reftable_record *rec, int hash_size)
1311 +{
1312 + printf("'%c': ", rec->type);
1313 + reftable_record_vtable(rec)->print(reftable_record_data(rec), hash_size);
1314 +}
reftable/record.h
+4
@@ -61,6 +61,9 @@ struct reftable_record_vtable {
61
62 /* Are two records equal? This assumes they have the same type. Returns 0 for non-equal. */
63 int (*equal)(const void *a, const void *b, int hash_size);
64 +
65 + /* Print on stdout, for debugging. */
66 + void (*print)(const void *rec, int hash_size);
67 };
68
69 /* returns true for recognized block types. Block start with the block type. */
@@ -112,6 +115,7 @@ struct reftable_record {
115
116 /* see struct record_vtable */
117 int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
118 +void reftable_record_print(struct reftable_record *rec, int hash_size);
119 void reftable_record_key(struct reftable_record *rec, struct strbuf *dest);
120 uint8_t reftable_record_type(struct reftable_record *rec);
121 void reftable_record_copy_from(struct reftable_record *rec,
reftable/record_test.c
+20 -1
@@ -25,6 +25,10 @@ static void test_copy(struct reftable_record *rec)
25 /* do it twice to catch memory leaks */
26 reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
27 EXPECT(reftable_record_equal(rec, &copy, GIT_SHA1_RAWSZ));
28 +
29 + puts("testing print coverage:\n");
30 + reftable_record_print(&copy, GIT_SHA1_RAWSZ);
31 +
32 reftable_record_release(&copy);
33 }
34
@@ -176,7 +180,8 @@ static void test_reftable_log_record_equal(void)
180 static void test_reftable_log_record_roundtrip(void)
181 {
182 int i;
179 - struct reftable_log_record in[2] = {
183 +
184 + struct reftable_log_record in[] = {
185 {
186 .refname = xstrdup("refs/heads/master"),
187 .update_index = 42,
@@ -197,10 +202,24 @@ static void test_reftable_log_record_roundtrip(void)
202 .refname = xstrdup("refs/heads/master"),
203 .update_index = 22,
204 .value_type = REFTABLE_LOG_DELETION,
205 + },
206 + {
207 + .refname = xstrdup("branch"),
208 + .update_index = 33,
209 + .value_type = REFTABLE_LOG_UPDATE,
210 + .value = {
211 + .update = {
212 + .old_hash = reftable_malloc(GIT_SHA1_RAWSZ),
213 + .new_hash = reftable_malloc(GIT_SHA1_RAWSZ),
214 + /* rest of fields left empty. */
215 + },
216 + },
217 }
218 };
219 set_test_hash(in[0].value.update.new_hash, 1);
220 set_test_hash(in[0].value.update.old_hash, 2);
221 + set_test_hash(in[2].value.update.new_hash, 3);
222 + set_test_hash(in[2].value.update.old_hash, 4);
223 for (i = 0; i < ARRAY_SIZE(in); i++) {
224 struct reftable_record rec = { .type = BLOCK_TYPE_LOG };
225 struct strbuf key = STRBUF_INIT;