Skip to content

Commit fcacc2b

Browse files
pks-tgitster
authored andcommitted
refs/reftable: track last log record name via strbuf
The reflog iterator enumerates all reflogs known to a ref backend. In the "reftable" backend there is no way to list all existing reflogs directly. Instead, we have to iterate through all reflog entries and discard all those redundant entries for which we have already returned a reflog entry. This logic is implemented by tracking the last reflog name that we have emitted to the iterator's user. If the next log record has the same name we simply skip it until we find another record with a different refname. This last reflog name is stored in a simple C string, which requires us to free and reallocate it whenever we need to update the reflog name. Convert it to use a `struct strbuf` instead, which reduces the number of allocations. Before: HEAP SUMMARY: in use at exit: 13,473 bytes in 122 blocks total heap usage: 1,068,485 allocs, 1,068,363 frees, 281,122,886 bytes allocated After: HEAP SUMMARY: in use at exit: 13,473 bytes in 122 blocks total heap usage: 68,485 allocs, 68,363 frees, 256,234,072 bytes allocated Note that even after this change we still allocate quite a lot of data, even though the number of allocations does not scale with the number of log records anymore. This remainder comes mostly from decompressing the log blocks, where we decompress each block into newly allocated memory. This will be addressed at a later point in time. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7b8abc4 commit fcacc2b

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

refs/reftable-backend.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ struct reftable_reflog_iterator {
15751575
struct reftable_ref_store *refs;
15761576
struct reftable_iterator iter;
15771577
struct reftable_log_record log;
1578-
char *last_name;
1578+
struct strbuf last_name;
15791579
int err;
15801580
};
15811581

@@ -1594,15 +1594,15 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator)
15941594
* we've already produced this name. This could be faster by
15951595
* seeking directly to reflog@update_index==0.
15961596
*/
1597-
if (iter->last_name && !strcmp(iter->log.refname, iter->last_name))
1597+
if (!strcmp(iter->log.refname, iter->last_name.buf))
15981598
continue;
15991599

16001600
if (check_refname_format(iter->log.refname,
16011601
REFNAME_ALLOW_ONELEVEL))
16021602
continue;
16031603

1604-
free(iter->last_name);
1605-
iter->last_name = xstrdup(iter->log.refname);
1604+
strbuf_reset(&iter->last_name);
1605+
strbuf_addstr(&iter->last_name, iter->log.refname);
16061606
iter->base.refname = iter->log.refname;
16071607

16081608
break;
@@ -1635,7 +1635,7 @@ static int reftable_reflog_iterator_abort(struct ref_iterator *ref_iterator)
16351635
(struct reftable_reflog_iterator *)ref_iterator;
16361636
reftable_log_record_release(&iter->log);
16371637
reftable_iterator_destroy(&iter->iter);
1638-
free(iter->last_name);
1638+
strbuf_release(&iter->last_name);
16391639
free(iter);
16401640
return ITER_DONE;
16411641
}
@@ -1655,6 +1655,7 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl
16551655

16561656
iter = xcalloc(1, sizeof(*iter));
16571657
base_ref_iterator_init(&iter->base, &reftable_reflog_iterator_vtable);
1658+
strbuf_init(&iter->last_name, 0);
16581659
iter->refs = refs;
16591660

16601661
ret = refs->err;

0 commit comments

Comments
 (0)