reftable/block: reuse buffer to compute record keys

When iterating over entries in the block iterator 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. Refactor the code to reuse the buffer. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Dec 11, 2023 at 10:08 UTC c0cadb0576d4920915eb3bd38a7d1abfcbd25f98
2 files changed +10 -11
reftable/block.c
+8 -11
@@ -323,30 +323,28 @@ int block_iter_next(struct block_iter *it, struct reftable_record *rec)
323 .len = it->br->block_len - it->next_off,
324 };
325 struct string_view start = in;
326 - struct strbuf key = STRBUF_INIT;
326 uint8_t extra = 0;
327 int n = 0;
328
329 if (it->next_off >= it->br->block_len)
330 return 1;
331
333 - n = reftable_decode_key(&key, &extra, it->last_key, in);
332 + n = reftable_decode_key(&it->key, &extra, it->last_key, in);
333 if (n < 0)
334 return -1;
335
337 - if (!key.len)
336 + if (!it->key.len)
337 return REFTABLE_FORMAT_ERROR;
338
339 string_view_consume(&in, n);
341 - n = reftable_record_decode(rec, key, extra, in, it->br->hash_size);
340 + n = reftable_record_decode(rec, it->key, extra, in, it->br->hash_size);
341 if (n < 0)
342 return -1;
343 string_view_consume(&in, n);
344
345 strbuf_reset(&it->last_key);
347 - strbuf_addbuf(&it->last_key, &key);
346 + strbuf_addbuf(&it->last_key, &it->key);
347 it->next_off += start.len - in.len;
349 - strbuf_release(&key);
348 return 0;
349 }
350
@@ -377,6 +375,7 @@ int block_iter_seek(struct block_iter *it, struct strbuf *want)
375 void block_iter_close(struct block_iter *it)
376 {
377 strbuf_release(&it->last_key);
378 + strbuf_release(&it->key);
379 }
380
381 int block_reader_seek(struct block_reader *br, struct block_iter *it,
@@ -387,7 +386,6 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it,
386 .r = br,
387 };
388 struct reftable_record rec = reftable_new_record(block_reader_type(br));
390 - struct strbuf key = STRBUF_INIT;
389 int err = 0;
390 struct block_iter next = BLOCK_ITER_INIT;
391
@@ -414,8 +412,8 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it,
412 if (err < 0)
413 goto done;
414
417 - reftable_record_key(&rec, &key);
418 - if (err > 0 || strbuf_cmp(&key, want) >= 0) {
415 + reftable_record_key(&rec, &it->key);
416 + if (err > 0 || strbuf_cmp(&it->key, want) >= 0) {
417 err = 0;
418 goto done;
419 }
@@ -424,8 +422,7 @@ int block_reader_seek(struct block_reader *br, struct block_iter *it,
422 }
423
424 done:
427 - strbuf_release(&key);
428 - strbuf_release(&next.last_key);
425 + block_iter_close(&next);
426 reftable_record_release(&rec);
427
428 return err;
reftable/block.h
+2
@@ -84,10 +84,12 @@ struct block_iter {
84
85 /* key for last entry we read. */
86 struct strbuf last_key;
87 + struct strbuf key;
88 };
89
90 #define BLOCK_ITER_INIT { \
91 .last_key = STRBUF_INIT, \
92 + .key = STRBUF_INIT, \
93 }
94
95 /* initializes a block reader. */