Skip to content

Commit c983374

Browse files
hanwengitster
authored andcommitted
reftable: implement record equality generically
This simplifies unittests a little, and provides further coverage for reftable_record_copy(). Signed-off-by: Han-Wen Nienhuys <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a94b945 commit c983374

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

reftable/record.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,15 @@ static int reftable_ref_record_is_deletion_void(const void *p)
430430
(const struct reftable_ref_record *)p);
431431
}
432432

433+
434+
static int reftable_ref_record_equal_void(const void *a,
435+
const void *b, int hash_size)
436+
{
437+
struct reftable_ref_record *ra = (struct reftable_ref_record *) a;
438+
struct reftable_ref_record *rb = (struct reftable_ref_record *) b;
439+
return reftable_ref_record_equal(ra, rb, hash_size);
440+
}
441+
433442
static struct reftable_record_vtable reftable_ref_record_vtable = {
434443
.key = &reftable_ref_record_key,
435444
.type = BLOCK_TYPE_REF,
@@ -439,6 +448,7 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
439448
.decode = &reftable_ref_record_decode,
440449
.release = &reftable_ref_record_release_void,
441450
.is_deletion = &reftable_ref_record_is_deletion_void,
451+
.equal = &reftable_ref_record_equal_void,
442452
};
443453

444454
static void reftable_obj_record_key(const void *r, struct strbuf *dest)
@@ -572,6 +582,25 @@ static int not_a_deletion(const void *p)
572582
return 0;
573583
}
574584

585+
static int reftable_obj_record_equal_void(const void *a, const void *b, int hash_size)
586+
{
587+
struct reftable_obj_record *ra = (struct reftable_obj_record *) a;
588+
struct reftable_obj_record *rb = (struct reftable_obj_record *) b;
589+
590+
if (ra->hash_prefix_len != rb->hash_prefix_len
591+
|| ra->offset_len != rb->offset_len)
592+
return 0;
593+
594+
if (ra->hash_prefix_len &&
595+
memcmp(ra->hash_prefix, rb->hash_prefix, ra->hash_prefix_len))
596+
return 0;
597+
if (ra->offset_len &&
598+
memcmp(ra->offsets, rb->offsets, ra->offset_len * sizeof(uint64_t)))
599+
return 0;
600+
601+
return 1;
602+
}
603+
575604
static struct reftable_record_vtable reftable_obj_record_vtable = {
576605
.key = &reftable_obj_record_key,
577606
.type = BLOCK_TYPE_OBJ,
@@ -580,7 +609,8 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
580609
.encode = &reftable_obj_record_encode,
581610
.decode = &reftable_obj_record_decode,
582611
.release = &reftable_obj_record_release,
583-
.is_deletion = not_a_deletion,
612+
.is_deletion = &not_a_deletion,
613+
.equal = &reftable_obj_record_equal_void,
584614
};
585615

586616
void reftable_log_record_print(struct reftable_log_record *log,
@@ -881,6 +911,14 @@ static int zero_hash_eq(uint8_t *a, uint8_t *b, int sz)
881911
return !memcmp(a, b, sz);
882912
}
883913

914+
static int reftable_log_record_equal_void(const void *a,
915+
const void *b, int hash_size)
916+
{
917+
return reftable_log_record_equal((struct reftable_log_record *) a,
918+
(struct reftable_log_record *) b,
919+
hash_size);
920+
}
921+
884922
int reftable_log_record_equal(const struct reftable_log_record *a,
885923
const struct reftable_log_record *b, int hash_size)
886924
{
@@ -924,6 +962,7 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
924962
.decode = &reftable_log_record_decode,
925963
.release = &reftable_log_record_release_void,
926964
.is_deletion = &reftable_log_record_is_deletion_void,
965+
.equal = &reftable_log_record_equal_void
927966
};
928967

929968
struct reftable_record reftable_new_record(uint8_t typ)
@@ -1042,6 +1081,14 @@ static int reftable_index_record_decode(void *rec, struct strbuf key,
10421081
return start.len - in.len;
10431082
}
10441083

1084+
static int reftable_index_record_equal(const void *a, const void *b, int hash_size)
1085+
{
1086+
struct reftable_index_record *ia = (struct reftable_index_record *) a;
1087+
struct reftable_index_record *ib = (struct reftable_index_record *) b;
1088+
1089+
return ia->offset == ib->offset && !strbuf_cmp(&ia->last_key, &ib->last_key);
1090+
}
1091+
10451092
static struct reftable_record_vtable reftable_index_record_vtable = {
10461093
.key = &reftable_index_record_key,
10471094
.type = BLOCK_TYPE_INDEX,
@@ -1051,6 +1098,7 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
10511098
.decode = &reftable_index_record_decode,
10521099
.release = &reftable_index_record_release,
10531100
.is_deletion = &not_a_deletion,
1101+
.equal = &reftable_index_record_equal,
10541102
};
10551103

10561104
void reftable_record_key(struct reftable_record *rec, struct strbuf *dest)
@@ -1098,6 +1146,13 @@ int reftable_record_is_deletion(struct reftable_record *rec)
10981146
return rec->ops->is_deletion(rec->data);
10991147
}
11001148

1149+
int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size)
1150+
{
1151+
if (a->ops != b->ops)
1152+
return 0;
1153+
return a->ops->equal(a->data, b->data, hash_size);
1154+
}
1155+
11011156
void reftable_record_from_ref(struct reftable_record *rec,
11021157
struct reftable_ref_record *ref_rec)
11031158
{

reftable/record.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ struct reftable_record_vtable {
5858

5959
/* is this a tombstone? */
6060
int (*is_deletion)(const void *rec);
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);
6164
};
6265

6366
/* record is a generic wrapper for different types of records. */
@@ -98,7 +101,7 @@ struct reftable_obj_record {
98101
};
99102

100103
/* see struct record_vtable */
101-
104+
int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
102105
void reftable_record_key(struct reftable_record *rec, struct strbuf *dest);
103106
uint8_t reftable_record_type(struct reftable_record *rec);
104107
void reftable_record_copy_from(struct reftable_record *rec,

reftable/record_test.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,7 @@ static void test_copy(struct reftable_record *rec)
2121
reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
2222
/* do it twice to catch memory leaks */
2323
reftable_record_copy_from(&copy, rec, GIT_SHA1_RAWSZ);
24-
switch (reftable_record_type(&copy)) {
25-
case BLOCK_TYPE_REF:
26-
EXPECT(reftable_ref_record_equal(reftable_record_as_ref(&copy),
27-
reftable_record_as_ref(rec),
28-
GIT_SHA1_RAWSZ));
29-
break;
30-
case BLOCK_TYPE_LOG:
31-
EXPECT(reftable_log_record_equal(reftable_record_as_log(&copy),
32-
reftable_record_as_log(rec),
33-
GIT_SHA1_RAWSZ));
34-
break;
35-
}
24+
EXPECT(reftable_record_equal(rec, &copy, GIT_SHA1_RAWSZ));
3625
reftable_record_destroy(&copy);
3726
}
3827

@@ -346,13 +335,7 @@ static void test_reftable_obj_record_roundtrip(void)
346335
GIT_SHA1_RAWSZ);
347336
EXPECT(n == m);
348337

349-
EXPECT(in.hash_prefix_len == out.hash_prefix_len);
350-
EXPECT(in.offset_len == out.offset_len);
351-
352-
EXPECT(!memcmp(in.hash_prefix, out.hash_prefix,
353-
in.hash_prefix_len));
354-
EXPECT(0 == memcmp(in.offsets, out.offsets,
355-
sizeof(uint64_t) * in.offset_len));
338+
EXPECT(reftable_record_equal(&rec, &rec_out, GIT_SHA1_RAWSZ));
356339
strbuf_release(&key);
357340
reftable_record_release(&rec_out);
358341
}
@@ -390,7 +373,7 @@ static void test_reftable_index_record_roundtrip(void)
390373
m = reftable_record_decode(&out_rec, key, extra, dest, GIT_SHA1_RAWSZ);
391374
EXPECT(m == n);
392375

393-
EXPECT(in.offset == out.offset);
376+
EXPECT(reftable_record_equal(&rec, &out_rec, GIT_SHA1_RAWSZ));
394377

395378
reftable_record_release(&out_rec);
396379
strbuf_release(&key);

0 commit comments

Comments
 (0)