Skip to content

Commit 87ff723

Browse files
pks-tgitster
authored andcommitted
reftable/record: convert old and new object IDs to arrays
In 7af607c (reftable/record: store "val1" hashes as static arrays, 2024-01-03) and b31e3cc (reftable/record: store "val2" hashes as static arrays, 2024-01-03) we have converted ref records to store their object IDs in a static array. Convert log records to do the same so that their old and new object IDs are arrays, too. This change results in two allocations less per log record that we're iterating over. Before: HEAP SUMMARY: in use at exit: 13,473 bytes in 122 blocks total heap usage: 8,068,495 allocs, 8,068,373 frees, 401,011,862 bytes allocated After: HEAP SUMMARY: in use at exit: 13,473 bytes in 122 blocks total heap usage: 6,068,489 allocs, 6,068,367 frees, 361,011,822 bytes allocated Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent eea0d11 commit 87ff723

File tree

7 files changed

+61
-151
lines changed

7 files changed

+61
-151
lines changed

refs/reftable-backend.c

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -171,23 +171,6 @@ static int should_write_log(struct ref_store *refs, const char *refname)
171171
}
172172
}
173173

174-
static void clear_reftable_log_record(struct reftable_log_record *log)
175-
{
176-
switch (log->value_type) {
177-
case REFTABLE_LOG_UPDATE:
178-
/*
179-
* When we write log records, the hashes are owned by the
180-
* caller and thus shouldn't be free'd.
181-
*/
182-
log->value.update.old_hash = NULL;
183-
log->value.update.new_hash = NULL;
184-
break;
185-
case REFTABLE_LOG_DELETION:
186-
break;
187-
}
188-
reftable_log_record_release(log);
189-
}
190-
191174
static void fill_reftable_log_record(struct reftable_log_record *log)
192175
{
193176
const char *info = git_committer_info(0);
@@ -1102,8 +1085,8 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
11021085
fill_reftable_log_record(log);
11031086
log->update_index = ts;
11041087
log->refname = xstrdup(u->refname);
1105-
log->value.update.new_hash = u->new_oid.hash;
1106-
log->value.update.old_hash = tx_update->current_oid.hash;
1088+
memcpy(log->value.update.new_hash, u->new_oid.hash, GIT_MAX_RAWSZ);
1089+
memcpy(log->value.update.old_hash, tx_update->current_oid.hash, GIT_MAX_RAWSZ);
11071090
log->value.update.message =
11081091
xstrndup(u->msg, arg->refs->write_options.block_size / 2);
11091092
}
@@ -1158,7 +1141,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
11581141
done:
11591142
assert(ret != REFTABLE_API_ERROR);
11601143
for (i = 0; i < logs_nr; i++)
1161-
clear_reftable_log_record(&logs[i]);
1144+
reftable_log_record_release(&logs[i]);
11621145
free(logs);
11631146
return ret;
11641147
}
@@ -1275,13 +1258,13 @@ static int write_create_symref_table(struct reftable_writer *writer, void *cb_da
12751258
log.update_index = ts;
12761259
log.value.update.message = xstrndup(create->logmsg,
12771260
create->refs->write_options.block_size / 2);
1278-
log.value.update.new_hash = new_oid.hash;
1261+
memcpy(log.value.update.new_hash, new_oid.hash, GIT_MAX_RAWSZ);
12791262
if (refs_resolve_ref_unsafe(&create->refs->base, create->refname,
12801263
RESOLVE_REF_READING, &old_oid, NULL))
1281-
log.value.update.old_hash = old_oid.hash;
1264+
memcpy(log.value.update.old_hash, old_oid.hash, GIT_MAX_RAWSZ);
12821265

12831266
ret = reftable_writer_add_log(writer, &log);
1284-
clear_reftable_log_record(&log);
1267+
reftable_log_record_release(&log);
12851268
return ret;
12861269
}
12871270

@@ -1420,7 +1403,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
14201403
logs[logs_nr].update_index = deletion_ts;
14211404
logs[logs_nr].value.update.message =
14221405
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
1423-
logs[logs_nr].value.update.old_hash = old_ref.value.val1;
1406+
memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
14241407
logs_nr++;
14251408

14261409
ret = read_ref_without_reload(arg->stack, "HEAD", &head_oid, &head_referent, &head_type);
@@ -1452,7 +1435,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
14521435
logs[logs_nr].update_index = creation_ts;
14531436
logs[logs_nr].value.update.message =
14541437
xstrndup(arg->logmsg, arg->refs->write_options.block_size / 2);
1455-
logs[logs_nr].value.update.new_hash = old_ref.value.val1;
1438+
memcpy(logs[logs_nr].value.update.new_hash, old_ref.value.val1, GIT_MAX_RAWSZ);
14561439
logs_nr++;
14571440

14581441
/*
@@ -1515,10 +1498,6 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
15151498
for (i = 0; i < logs_nr; i++) {
15161499
if (!strcmp(logs[i].refname, "HEAD"))
15171500
continue;
1518-
if (logs[i].value.update.old_hash == old_ref.value.val1)
1519-
logs[i].value.update.old_hash = NULL;
1520-
if (logs[i].value.update.new_hash == old_ref.value.val1)
1521-
logs[i].value.update.new_hash = NULL;
15221501
logs[i].refname = NULL;
15231502
reftable_log_record_release(&logs[i]);
15241503
}
@@ -2180,7 +2159,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
21802159
dest->value_type = REFTABLE_LOG_DELETION;
21812160
} else {
21822161
if ((flags & EXPIRE_REFLOGS_REWRITE) && last_hash)
2183-
dest->value.update.old_hash = last_hash;
2162+
memcpy(dest->value.update.old_hash, last_hash, GIT_MAX_RAWSZ);
21842163
last_hash = logs[i].value.update.new_hash;
21852164
}
21862165
}

reftable/merged_test.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,13 @@ merged_table_from_log_records(struct reftable_log_record **logs,
289289

290290
static void test_merged_logs(void)
291291
{
292-
uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 };
293-
uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 };
294-
uint8_t hash3[GIT_SHA1_RAWSZ] = { 3 };
295292
struct reftable_log_record r1[] = {
296293
{
297294
.refname = "a",
298295
.update_index = 2,
299296
.value_type = REFTABLE_LOG_UPDATE,
300297
.value.update = {
301-
.old_hash = hash2,
298+
.old_hash = { 2 },
302299
/* deletion */
303300
.name = "jane doe",
304301
.email = "jane@invalid",
@@ -310,8 +307,8 @@ static void test_merged_logs(void)
310307
.update_index = 1,
311308
.value_type = REFTABLE_LOG_UPDATE,
312309
.value.update = {
313-
.old_hash = hash1,
314-
.new_hash = hash2,
310+
.old_hash = { 1 },
311+
.new_hash = { 2 },
315312
.name = "jane doe",
316313
.email = "jane@invalid",
317314
.message = "message1",
@@ -324,7 +321,7 @@ static void test_merged_logs(void)
324321
.update_index = 3,
325322
.value_type = REFTABLE_LOG_UPDATE,
326323
.value.update = {
327-
.new_hash = hash3,
324+
.new_hash = { 3 },
328325
.name = "jane doe",
329326
.email = "jane@invalid",
330327
.message = "message3",

reftable/readwrite_test.c

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,15 @@ static void write_table(char ***names, struct strbuf *buf, int N,
7777
}
7878

7979
for (i = 0; i < N; i++) {
80-
uint8_t hash[GIT_SHA256_RAWSZ] = { 0 };
8180
char name[100];
8281
int n;
8382

84-
set_test_hash(hash, i);
85-
8683
snprintf(name, sizeof(name), "refs/heads/branch%02d", i);
8784

8885
log.refname = name;
8986
log.update_index = update_index;
9087
log.value_type = REFTABLE_LOG_UPDATE;
91-
log.value.update.new_hash = hash;
88+
set_test_hash(log.value.update.new_hash, i);
9289
log.value.update.message = "message";
9390

9491
n = reftable_writer_add_log(w, &log);
@@ -137,13 +134,10 @@ static void test_log_buffer_size(void)
137134
/* This tests buffer extension for log compression. Must use a random
138135
hash, to ensure that the compressed part is larger than the original.
139136
*/
140-
uint8_t hash1[GIT_SHA1_RAWSZ], hash2[GIT_SHA1_RAWSZ];
141137
for (i = 0; i < GIT_SHA1_RAWSZ; i++) {
142-
hash1[i] = (uint8_t)(git_rand() % 256);
143-
hash2[i] = (uint8_t)(git_rand() % 256);
138+
log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256);
139+
log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256);
144140
}
145-
log.value.update.old_hash = hash1;
146-
log.value.update.new_hash = hash2;
147141
reftable_writer_set_limits(w, update_index, update_index);
148142
err = reftable_writer_add_log(w, &log);
149143
EXPECT_ERR(err);
@@ -161,25 +155,26 @@ static void test_log_overflow(void)
161155
.block_size = ARRAY_SIZE(msg),
162156
};
163157
int err;
164-
struct reftable_log_record
165-
log = { .refname = "refs/heads/master",
166-
.update_index = 0xa,
167-
.value_type = REFTABLE_LOG_UPDATE,
168-
.value = { .update = {
169-
.name = "Han-Wen Nienhuys",
170-
.email = "[email protected]",
171-
.tz_offset = 100,
172-
.time = 0x5e430672,
173-
.message = msg,
174-
} } };
158+
struct reftable_log_record log = {
159+
.refname = "refs/heads/master",
160+
.update_index = 0xa,
161+
.value_type = REFTABLE_LOG_UPDATE,
162+
.value = {
163+
.update = {
164+
.old_hash = { 1 },
165+
.new_hash = { 2 },
166+
.name = "Han-Wen Nienhuys",
167+
.email = "[email protected]",
168+
.tz_offset = 100,
169+
.time = 0x5e430672,
170+
.message = msg,
171+
},
172+
},
173+
};
175174
struct reftable_writer *w =
176175
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
177176

178-
uint8_t hash1[GIT_SHA1_RAWSZ] = {1}, hash2[GIT_SHA1_RAWSZ] = { 2 };
179-
180177
memset(msg, 'x', sizeof(msg) - 1);
181-
log.value.update.old_hash = hash1;
182-
log.value.update.new_hash = hash2;
183178
reftable_writer_set_limits(w, update_index, update_index);
184179
err = reftable_writer_add_log(w, &log);
185180
EXPECT(err == REFTABLE_ENTRY_TOO_BIG_ERROR);
@@ -219,16 +214,13 @@ static void test_log_write_read(void)
219214
EXPECT_ERR(err);
220215
}
221216
for (i = 0; i < N; i++) {
222-
uint8_t hash1[GIT_SHA1_RAWSZ], hash2[GIT_SHA1_RAWSZ];
223217
struct reftable_log_record log = { NULL };
224-
set_test_hash(hash1, i);
225-
set_test_hash(hash2, i + 1);
226218

227219
log.refname = names[i];
228220
log.update_index = i;
229221
log.value_type = REFTABLE_LOG_UPDATE;
230-
log.value.update.old_hash = hash1;
231-
log.value.update.new_hash = hash2;
222+
set_test_hash(log.value.update.old_hash, i);
223+
set_test_hash(log.value.update.new_hash, i + 1);
232224

233225
err = reftable_writer_add_log(w, &log);
234226
EXPECT_ERR(err);
@@ -298,18 +290,15 @@ static void test_log_zlib_corruption(void)
298290
struct reftable_writer *w =
299291
reftable_new_writer(&strbuf_add_void, &noop_flush, &buf, &opts);
300292
const struct reftable_stats *stats = NULL;
301-
uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 };
302-
uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 };
303293
char message[100] = { 0 };
304294
int err, i, n;
305-
306295
struct reftable_log_record log = {
307296
.refname = "refname",
308297
.value_type = REFTABLE_LOG_UPDATE,
309298
.value = {
310299
.update = {
311-
.new_hash = hash1,
312-
.old_hash = hash2,
300+
.new_hash = { 1 },
301+
.old_hash = { 2 },
313302
.name = "My Name",
314303
.email = "myname@invalid",
315304
.message = message,
@@ -821,13 +810,12 @@ static void test_write_multiple_indices(void)
821810
}
822811

823812
for (i = 0; i < 100; i++) {
824-
unsigned char hash[GIT_SHA1_RAWSZ] = {i};
825813
struct reftable_log_record log = {
826814
.update_index = 1,
827815
.value_type = REFTABLE_LOG_UPDATE,
828816
.value.update = {
829-
.old_hash = hash,
830-
.new_hash = hash,
817+
.old_hash = { i },
818+
.new_hash = { i },
831819
},
832820
};
833821

reftable/record.c

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -763,16 +763,10 @@ static void reftable_log_record_copy_from(void *rec, const void *src_rec,
763763
xstrdup(dst->value.update.message);
764764
}
765765

766-
if (dst->value.update.new_hash) {
767-
REFTABLE_ALLOC_ARRAY(dst->value.update.new_hash, hash_size);
768-
memcpy(dst->value.update.new_hash,
769-
src->value.update.new_hash, hash_size);
770-
}
771-
if (dst->value.update.old_hash) {
772-
REFTABLE_ALLOC_ARRAY(dst->value.update.old_hash, hash_size);
773-
memcpy(dst->value.update.old_hash,
774-
src->value.update.old_hash, hash_size);
775-
}
766+
memcpy(dst->value.update.new_hash,
767+
src->value.update.new_hash, hash_size);
768+
memcpy(dst->value.update.old_hash,
769+
src->value.update.old_hash, hash_size);
776770
break;
777771
}
778772
}
@@ -790,8 +784,6 @@ void reftable_log_record_release(struct reftable_log_record *r)
790784
case REFTABLE_LOG_DELETION:
791785
break;
792786
case REFTABLE_LOG_UPDATE:
793-
reftable_free(r->value.update.new_hash);
794-
reftable_free(r->value.update.old_hash);
795787
reftable_free(r->value.update.name);
796788
reftable_free(r->value.update.email);
797789
reftable_free(r->value.update.message);
@@ -808,33 +800,20 @@ static uint8_t reftable_log_record_val_type(const void *rec)
808800
return reftable_log_record_is_deletion(log) ? 0 : 1;
809801
}
810802

811-
static uint8_t zero[GIT_SHA256_RAWSZ] = { 0 };
812-
813803
static int reftable_log_record_encode(const void *rec, struct string_view s,
814804
int hash_size)
815805
{
816806
const struct reftable_log_record *r = rec;
817807
struct string_view start = s;
818808
int n = 0;
819-
uint8_t *oldh = NULL;
820-
uint8_t *newh = NULL;
821809
if (reftable_log_record_is_deletion(r))
822810
return 0;
823811

824-
oldh = r->value.update.old_hash;
825-
newh = r->value.update.new_hash;
826-
if (!oldh) {
827-
oldh = zero;
828-
}
829-
if (!newh) {
830-
newh = zero;
831-
}
832-
833812
if (s.len < 2 * hash_size)
834813
return -1;
835814

836-
memcpy(s.buf, oldh, hash_size);
837-
memcpy(s.buf + hash_size, newh, hash_size);
815+
memcpy(s.buf, r->value.update.old_hash, hash_size);
816+
memcpy(s.buf + hash_size, r->value.update.new_hash, hash_size);
838817
string_view_consume(&s, 2 * hash_size);
839818

840819
n = encode_string(r->value.update.name ? r->value.update.name : "", s);
@@ -891,8 +870,6 @@ static int reftable_log_record_decode(void *rec, struct strbuf key,
891870
if (val_type != r->value_type) {
892871
switch (r->value_type) {
893872
case REFTABLE_LOG_UPDATE:
894-
FREE_AND_NULL(r->value.update.old_hash);
895-
FREE_AND_NULL(r->value.update.new_hash);
896873
FREE_AND_NULL(r->value.update.message);
897874
FREE_AND_NULL(r->value.update.email);
898875
FREE_AND_NULL(r->value.update.name);
@@ -909,11 +886,6 @@ static int reftable_log_record_decode(void *rec, struct strbuf key,
909886
if (in.len < 2 * hash_size)
910887
return REFTABLE_FORMAT_ERROR;
911888

912-
r->value.update.old_hash =
913-
reftable_realloc(r->value.update.old_hash, hash_size);
914-
r->value.update.new_hash =
915-
reftable_realloc(r->value.update.new_hash, hash_size);
916-
917889
memcpy(r->value.update.old_hash, in.buf, hash_size);
918890
memcpy(r->value.update.new_hash, in.buf + hash_size, hash_size);
919891

@@ -983,17 +955,6 @@ static int null_streq(char *a, char *b)
983955
return 0 == strcmp(a, b);
984956
}
985957

986-
static int zero_hash_eq(uint8_t *a, uint8_t *b, int sz)
987-
{
988-
if (!a)
989-
a = zero;
990-
991-
if (!b)
992-
b = zero;
993-
994-
return !memcmp(a, b, sz);
995-
}
996-
997958
static int reftable_log_record_equal_void(const void *a,
998959
const void *b, int hash_size)
999960
{
@@ -1037,10 +998,10 @@ int reftable_log_record_equal(const struct reftable_log_record *a,
1037998
b->value.update.email) &&
1038999
null_streq(a->value.update.message,
10391000
b->value.update.message) &&
1040-
zero_hash_eq(a->value.update.old_hash,
1041-
b->value.update.old_hash, hash_size) &&
1042-
zero_hash_eq(a->value.update.new_hash,
1043-
b->value.update.new_hash, hash_size);
1001+
!memcmp(a->value.update.old_hash,
1002+
b->value.update.old_hash, hash_size) &&
1003+
!memcmp(a->value.update.new_hash,
1004+
b->value.update.new_hash, hash_size);
10441005
}
10451006

10461007
abort();

0 commit comments

Comments
 (0)