reftable/block: create public interface for reading blocks

While users of the reftable library wouldn't generally require access to individual blocks in a reftable table, there are valid usecases where one may require low-level access to them. One such upcoming usecase in the Git codebase is to implement consistency checks for the reftable library where we want to verify each block individually. Create a public interface for reading blocks. The interface isn't yet complete and lacks e.g. a way to read individual records from a block. Such missing functionality will be backfilled in subsequent commits. Note that this change also requires us to expose `reftable_buf`, which is used by the `reftable_block_first_key()` function. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 7, 2025 at 15:16 UTC 655e18d6b4f845090b0ba4761105b32726893ecb
4 files changed +78 -54
reftable/basics.h
-7
@@ -18,13 +18,6 @@
18
19 #define REFTABLE_UNUSED __attribute__((__unused__))
20
21 -struct reftable_buf {
22 - size_t alloc;
23 - size_t len;
24 - char *buf;
25 -};
26 -#define REFTABLE_BUF_INIT { 0 }
27 -
21 /*
22 * Initialize the buffer such that it is ready for use. This is equivalent to
23 * using REFTABLE_BUF_INIT for stack-allocated variables.
reftable/block.h
+1 -47
@@ -11,6 +11,7 @@
11
12 #include "basics.h"
13 #include "record.h"
14 +#include "reftable-block.h"
15 #include "reftable-blocksource.h"
16
17 /*
@@ -62,53 +63,6 @@ int block_writer_finish(struct block_writer *w);
63 /* clears out internally allocated block_writer members. */
64 void block_writer_release(struct block_writer *bw);
65
65 -/*
66 - * A block part of a reftable. Contains records as well as some metadata
67 - * describing them.
68 - */
69 -struct reftable_block {
70 - /* offset of the block header; nonzero for the first block in a
71 - * reftable. */
72 - uint32_t header_off;
73 -
74 - /* the memory block */
75 - struct reftable_block_data block_data;
76 - uint32_t hash_size;
77 -
78 - /* Uncompressed data for log entries. */
79 - struct z_stream_s *zstream;
80 - unsigned char *uncompressed_data;
81 - size_t uncompressed_cap;
82 -
83 - /*
84 - * Restart point data. Restart points are located after the block's
85 - * record data.
86 - */
87 - uint16_t restart_count;
88 - uint32_t restart_off;
89 -
90 - /* size of the data in the file. For log blocks, this is the compressed
91 - * size. */
92 - uint32_t full_block_size;
93 - uint8_t block_type;
94 -};
95 -
96 -/*
97 - * Initialize a reftable block from the given block source.
98 - */
99 -int reftable_block_init(struct reftable_block *b,
100 - struct reftable_block_source *source,
101 - uint32_t offset, uint32_t header_size,
102 - uint32_t table_block_size, uint32_t hash_size);
103 -
104 -void reftable_block_release(struct reftable_block *b);
105 -
106 -/* Returns the block type (eg. 'r' for refs) */
107 -uint8_t reftable_block_type(const struct reftable_block *b);
108 -
109 -/* Decodes the first key in the block */
110 -int reftable_block_first_key(const struct reftable_block *b, struct reftable_buf *key);
111 -
66 /* Iterate over entries in a block */
67 struct block_iter {
68 /* offset within the block of the next entry to read. */
reftable/reftable-basics.h
+8
@@ -11,6 +11,14 @@
11
12 #include <stddef.h>
13
14 +/* A buffer that contains arbitrary byte slices. */
15 +struct reftable_buf {
16 + size_t alloc;
17 + size_t len;
18 + char *buf;
19 +};
20 +#define REFTABLE_BUF_INIT { 0 }
21 +
22 /*
23 * Hash functions understood by the reftable library. Note that the values are
24 * arbitrary and somewhat random such that we can easily detect cases where the
reftable/reftable-block.h new
+69
@@ -0,0 +1,69 @@
1 +/*
2 + * Copyright 2020 Google LLC
3 + *
4 + * Use of this source code is governed by a BSD-style
5 + * license that can be found in the LICENSE file or at
6 + * https://developers.google.com/open-source/licenses/bsd
7 + */
8 +
9 +#ifndef REFTABLE_BLOCK_H
10 +#define REFTABLE_BLOCK_H
11 +
12 +#include <stdint.h>
13 +
14 +#include "reftable-basics.h"
15 +#include "reftable-blocksource.h"
16 +
17 +struct z_stream_s;
18 +
19 +/*
20 + * A block part of a reftable. Contains records as well as some metadata
21 + * describing them.
22 + */
23 +struct reftable_block {
24 + /*
25 + * Offset of the block header; nonzero for the first block in a
26 + * reftable.
27 + */
28 + uint32_t header_off;
29 +
30 + /* The memory block. */
31 + struct reftable_block_data block_data;
32 + uint32_t hash_size;
33 +
34 + /* Uncompressed data for log entries. */
35 + struct z_stream_s *zstream;
36 + unsigned char *uncompressed_data;
37 + size_t uncompressed_cap;
38 +
39 + /*
40 + * Restart point data. Restart points are located after the block's
41 + * record data.
42 + */
43 + uint16_t restart_count;
44 + uint32_t restart_off;
45 +
46 + /*
47 + * Size of the data in the file. For log blocks, this is the compressed
48 + * size.
49 + */
50 + uint32_t full_block_size;
51 + uint8_t block_type;
52 +};
53 +
54 +/* Initialize a reftable block from the given block source. */
55 +int reftable_block_init(struct reftable_block *b,
56 + struct reftable_block_source *source,
57 + uint32_t offset, uint32_t header_size,
58 + uint32_t table_block_size, uint32_t hash_size);
59 +
60 +/* Release resources allocated by the block. */
61 +void reftable_block_release(struct reftable_block *b);
62 +
63 +/* Returns the block type (eg. 'r' for refs). */
64 +uint8_t reftable_block_type(const struct reftable_block *b);
65 +
66 +/* Decodes the first key in the block. */
67 +int reftable_block_first_key(const struct reftable_block *b, struct reftable_buf *key);
68 +
69 +#endif /* REFTABLE_BLOCK_H */