git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 5/9] reftable/block: move ownership of block reader into `struct table_iter`

From
Patrick Steinhardt <ps@pks.im>
Date
Apr 3, 2024, 13:10 UTC
Message-ID
<Zg1VM6fz3TnmTGqy@tanuki>
In-Reply-To
<hwfkdfilniy46usnc3vnksaphdxboi5bxep4ek7aj2qxfhu332@6ym7dnn35k7z>
On Tue, Apr 02, 2024 at 11:52:58PM -0500, Justin Tobler wrote:
Show 49 quoted lines
> On 24/03/27 07:37AM, Patrick Steinhardt wrote:
> > The table iterator allows the caller to iterate through all records in a
> > reftable table. To do so it iterates through all blocks of the desired
> > type one by one, where for each block it creates a new block iterator
> > and yields all its entries.
> > 
> > One of the things that is somewhat confusing in this context is who owns
> > the block reader that is being used to read the blocks and pass them to
> > the block iterator. Intuitively, as the table iterator is responsible
> > for iterating through the blocks, one would assume that this iterator is
> > also responsible for managing the lifecycle of the reader. And while it
> > somewhat is, the block reader is ultimately stored inside of the block
> > iterator.
> > 
> > Refactor the code such that the block reader is instead fully managed by
> > the table iterator. Instead of passing the reader to the block iterator,
> > we now only end up passing the block data to it. Despite clearing up the
> > lifecycle of the reader, it will also allow for better reuse of the
> > reader in subsequent patches.
> > 
> > The following benchmark prints a single matching ref out of 1 million
> > refs. Before:
> > 
> >   HEAP SUMMARY:
> >       in use at exit: 13,603 bytes in 125 blocks
> >     total heap usage: 6,607 allocs, 6,482 frees, 509,635 bytes allocated
> > 
> > After:
> > 
> >   HEAP SUMMARY:
> >       in use at exit: 13,603 bytes in 125 blocks
> >     total heap usage: 7,235 allocs, 7,110 frees, 301,481 bytes allocated
> > 
> > Note that while there are more allocation and free calls now, the
> > overall number of bytes allocated is significantly lower. The number of
> > allocations will be reduced significantly by the next patch though.
> > 
> > Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ...
> > @@ -340,14 +344,14 @@ void block_iter_copy_from(struct block_iter *dest, struct block_iter *src)
> >  int block_iter_next(struct block_iter *it, struct reftable_record *rec)
> >  {
> >  	struct string_view in = {
> > -		.buf = it->br->block.data + it->next_off,
> > -		.len = it->br->block_len - it->next_off,
> > +		.buf = (unsigned char *) it->block + it->next_off,
> 
> Would it be best to use the `uint8_t *` type instead of `unsigned char *`
> to match `string_view.buf`? Not sure if it matters in this case.

It doesn't really. `uint8_t` should always be equivalent to `unsigned char`. I'd also think that `unsigned char` is a bit more idiomatic in our codebase, but may be mistaken there.

Show 27 quoted lines
> > +		.len = it->block_len - it->next_off,
> >  	};
> ...  
> > diff --git a/reftable/block.h b/reftable/block.h
> > index 601a1e0e89..b41efa5042 100644
> > --- a/reftable/block.h
> > +++ b/reftable/block.h
> > @@ -84,16 +84,18 @@ int block_reader_init(struct block_reader *br, struct reftable_block *bl,
> >  void block_reader_release(struct block_reader *br);
> >  
> >  /* Returns the block type (eg. 'r' for refs) */
> > -uint8_t block_reader_type(struct block_reader *r);
> > +uint8_t block_reader_type(const struct block_reader *r);
> >  
> >  /* Decodes the first key in the block */
> > -int block_reader_first_key(struct block_reader *br, struct strbuf *key);
> > +int block_reader_first_key(const struct block_reader *br, struct strbuf *key);
> >  
> >  /* Iterate over entries in a block */
> >  struct block_iter {
> >  	/* offset within the block of the next entry to read. */
> >  	uint32_t next_off;
> > -	struct block_reader *br;
> > +	const unsigned char *block;
> 
> Same question here. Would it be better to use `uint8_t *`? Or does it not
> really matter?
Same answer :)
Show 29 quoted lines
> > +	size_t block_len;
> > +	int hash_size;
> >  
> >  	/* key for last entry we read. */
> >  	struct strbuf last_key;
> > @@ -106,17 +108,22 @@ struct block_iter {
> >  }
> >  
> >  /* Position `it` at start of the block */
> > -void block_iter_seek_start(struct block_iter *it, struct block_reader *br);
> > +void block_iter_seek_start(struct block_iter *it, const struct block_reader *br);
> >  
> >  /* Position `it` to the `want` key in the block */
> > -int block_iter_seek_key(struct block_iter *it, struct block_reader *br,
> > +int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
> >  			struct strbuf *want);
> >  
> > -void block_iter_copy_from(struct block_iter *dest, struct block_iter *src);
> > +void block_iter_copy_from(struct block_iter *dest, const struct block_iter *src);
> >  
> >  /* return < 0 for error, 0 for OK, > 0 for EOF. */
> >  int block_iter_next(struct block_iter *it, struct reftable_record *rec);
> >  
> > +/*
> > + * Reset the block iterator to pristine state without releasing its memory.
> > + */
> 
> Do we want to make the comment a single line to match the other adjacent
> examples?

Can do. I'll refrain from sending a new version of this patch series for now though as none of the comments really need addressing, in my opinion. But please, feel free to push back in case you disagree.

Patrick
Show 8 quoted lines
> > +void block_iter_reset(struct block_iter *it);
> > +
> >  /* deallocate memory for `it`. The block reader and its block is left intact. */
> >  void block_iter_close(struct block_iter *it);
> >  
> ...
> 
> -Justin
Previous: Justin ToblerNext: Patrick Steinhardt
Message 10 of 31 in “reftable: optimize table and block iterators”
  1. 0/9 reftable: optimize table and block iteratorsPatrick Steinhardt, Mar 27, 2024
  2. 1/9 reftable/block: rename `block_reader_start()`Patrick Steinhardt, Mar 27, 2024
  3. 2/9 reftable/block: merge `block_iter_seek()` and `block_reader_seek()`Patrick Steinhardt, Mar 27, 2024
  4. 3/9 reftable/block: better grouping of functionsPatrick Steinhardt, Mar 27, 2024
  5. 4/9 reftable/block: introduce `block_reader_release()`Patrick Steinhardt, Mar 27, 2024
  6. Karthik NayakApr 3, 2024
  7. Patrick SteinhardtApr 8, 2024
  8. 5/9 reftable/block: move ownership of block reader into `struct table_iter`Patrick Steinhardt, Mar 27, 2024
  9. Justin ToblerApr 3, 2024
  10. Patrick SteinhardtApr 3, 2024
  11. 6/9 reftable/reader: iterate to next block in placePatrick Steinhardt, Mar 27, 2024
  12. 7/9 reftable/block: reuse uncompressed blocksPatrick Steinhardt, Mar 27, 2024
  13. 8/9 reftable/block: open-code call to `uncompress2()`Patrick Steinhardt, Mar 27, 2024
  14. 9/9 reftable/block: reuse `zstream` state on inflationPatrick Steinhardt, Mar 27, 2024
  15. Karthik NayakApr 3, 2024
  16. 00/10 reftable: optimize table and block iteratorsPatrick Steinhardt, Apr 8, 2024
  17. 01/10 reftable/block: rename `block_reader_start()`Patrick Steinhardt, Apr 8, 2024
  18. 02/10 reftable/block: merge `block_iter_seek()` and `block_reader_seek()`Patrick Steinhardt, Apr 8, 2024
  19. 03/10 reftable/block: better grouping of functionsPatrick Steinhardt, Apr 8, 2024
  20. 04/10 reftable/block: introduce `block_reader_release()`Patrick Steinhardt, Apr 8, 2024
  21. 05/10 reftable/block: move ownership of block reader into `struct table_iter`Patrick Steinhardt, Apr 8, 2024
  22. 06/10 reftable/reader: iterate to next block in placePatrick Steinhardt, Apr 8, 2024
  23. 07/10 reftable/block: reuse uncompressed blocksPatrick Steinhardt, Apr 8, 2024
  24. 08/10 reftable/block: open-code call to `uncompress2()`Patrick Steinhardt, Apr 8, 2024
  25. 09/10 reftable/block: reuse `zstream` state on inflationPatrick Steinhardt, Apr 8, 2024
  26. Karthik NayakApr 10, 2024
  27. 10/10 reftable/block: avoid copying block iterators on seekPatrick Steinhardt, Apr 8, 2024
  28. Justin ToblerApr 9, 2024
  29. Patrick SteinhardtApr 9, 2024
  30. Justin ToblerApr 9, 2024
  31. Karthik NayakApr 10, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.