Skip to content

Commit 829231d

Browse files
pks-tgitster
authored andcommitted
reftable/merged: reuse buffer to compute record keys
When iterating over entries in the merged iterator's queue, we compute the key of each of the entries and write it into a buffer. We do not reuse the buffer though and thus re-allocate it on every iteration, which is wasteful given that we never transfer ownership of the allocated bytes outside of the loop. Refactor the code to reuse the buffer. This also fixes a potential memory leak when `merged_iter_advance_subiter()` returns an error. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9abda98 commit 829231d

File tree

2 files changed

+18
-15
lines changed

2 files changed

+18
-15
lines changed

reftable/merged.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ static void merged_iter_close(void *p)
5252
reftable_iterator_destroy(&mi->stack[i]);
5353
}
5454
reftable_free(mi->stack);
55+
strbuf_release(&mi->key);
56+
strbuf_release(&mi->entry_key);
5557
}
5658

5759
static int merged_iter_advance_nonnull_subiter(struct merged_iter *mi,
@@ -85,7 +87,6 @@ static int merged_iter_advance_subiter(struct merged_iter *mi, size_t idx)
8587
static int merged_iter_next_entry(struct merged_iter *mi,
8688
struct reftable_record *rec)
8789
{
88-
struct strbuf entry_key = STRBUF_INIT;
8990
struct pq_entry entry = { 0 };
9091
int err = 0;
9192

@@ -105,33 +106,31 @@ static int merged_iter_next_entry(struct merged_iter *mi,
105106
such a deployment, the loop below must be changed to collect all
106107
entries for the same key, and return new the newest one.
107108
*/
108-
reftable_record_key(&entry.rec, &entry_key);
109+
reftable_record_key(&entry.rec, &mi->entry_key);
109110
while (!merged_iter_pqueue_is_empty(mi->pq)) {
110111
struct pq_entry top = merged_iter_pqueue_top(mi->pq);
111-
struct strbuf k = STRBUF_INIT;
112-
int err = 0, cmp = 0;
112+
int cmp = 0;
113113

114-
reftable_record_key(&top.rec, &k);
114+
reftable_record_key(&top.rec, &mi->key);
115115

116-
cmp = strbuf_cmp(&k, &entry_key);
117-
strbuf_release(&k);
118-
119-
if (cmp > 0) {
116+
cmp = strbuf_cmp(&mi->key, &mi->entry_key);
117+
if (cmp > 0)
120118
break;
121-
}
122119

123120
merged_iter_pqueue_remove(&mi->pq);
124121
err = merged_iter_advance_subiter(mi, top.index);
125-
if (err < 0) {
126-
return err;
127-
}
122+
if (err < 0)
123+
goto done;
128124
reftable_record_release(&top.rec);
129125
}
130126

131127
reftable_record_copy_from(rec, &entry.rec, hash_size(mi->hash_id));
128+
129+
done:
132130
reftable_record_release(&entry.rec);
133-
strbuf_release(&entry_key);
134-
return 0;
131+
strbuf_release(&mi->entry_key);
132+
strbuf_release(&mi->key);
133+
return err;
135134
}
136135

137136
static int merged_iter_next(struct merged_iter *mi, struct reftable_record *rec)
@@ -248,6 +247,8 @@ static int merged_table_seek_record(struct reftable_merged_table *mt,
248247
.typ = reftable_record_type(rec),
249248
.hash_id = mt->hash_id,
250249
.suppress_deletions = mt->suppress_deletions,
250+
.key = STRBUF_INIT,
251+
.entry_key = STRBUF_INIT,
251252
};
252253
int n = 0;
253254
int err = 0;

reftable/merged.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct merged_iter {
3131
uint8_t typ;
3232
int suppress_deletions;
3333
struct merged_iter_pqueue pq;
34+
struct strbuf key;
35+
struct strbuf entry_key;
3436
};
3537

3638
void merged_table_release(struct reftable_merged_table *mt);

0 commit comments

Comments
 (0)