Raw
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_WRITER_H
10 #define REFTABLE_WRITER_H
11
12 #include "reftable-system.h"
13 #include "reftable-record.h"
14
15 /* Writing single reftables */
16
17 /* reftable_write_options sets options for writing a single reftable. */
18 struct reftable_write_options {
19 /* boolean: do not pad out blocks to block size. */
20 unsigned unpadded : 1;
21
22 /* the blocksize. Should be less than 2^24. */
23 uint32_t block_size;
24
25 /* boolean: do not generate a SHA1 => ref index. */
26 unsigned skip_index_objects : 1;
27
28 /* how often to write complete keys in each block. */
29 uint16_t restart_interval;
30
31 /* 4-byte identifier ("sha1", "s256") of the hash.
32 * Defaults to SHA1 if unset
33 */
34 enum reftable_hash hash_id;
35
36 /* Default mode for creating files. If unset, use 0666 (+umask) */
37 unsigned int default_permissions;
38
39 /* boolean: copy log messages exactly. If unset, check that the message
40 * is a single line, and add '\n' if missing.
41 */
42 unsigned exact_log_message : 1;
43
44 /* boolean: Prevent auto-compaction of tables. */
45 unsigned disable_auto_compact : 1;
46
47 /*
48 * Geometric sequence factor used by auto-compaction to decide which
49 * tables to compact. Defaults to 2 if unset.
50 */
51 uint8_t auto_compaction_factor;
52
53 /*
54 * The number of milliseconds to wait when trying to lock "tables.list".
55 * Note that this does not apply to locking individual tables, as these
56 * should only ever be locked when already holding the "tables.list"
57 * lock.
58 *
59 * Passing 0 will fail immediately when the file is locked, passing a
60 * negative value will cause us to block indefinitely.
61 */
62 long lock_timeout_ms;
63
64 /*
65 * Callback function to execute whenever the stack is being reloaded.
66 * This can be used e.g. to discard cached information that relies on
67 * the old stack's data. The payload data will be passed as argument to
68 * the callback.
69 */
70 void (*on_reload)(void *payload);
71 void *on_reload_payload;
72 };
73
74 /* reftable_block_stats holds statistics for a single block type */
75 struct reftable_block_stats {
76 /* total number of entries written */
77 int entries;
78 /* total number of key restarts */
79 uint32_t restarts;
80 /* total number of blocks */
81 int blocks;
82 /* total number of index blocks */
83 int index_blocks;
84 /* depth of the index */
85 int max_index_level;
86
87 /* offset of the first block for this type */
88 uint64_t offset;
89 /* offset of the top level index block for this type, or 0 if not
90 * present */
91 uint64_t index_offset;
92 };
93
94 /* stats holds overall statistics for a single reftable */
95 struct reftable_stats {
96 /* total number of blocks written. */
97 int blocks;
98 /* stats for ref data */
99 struct reftable_block_stats ref_stats;
100 /* stats for the SHA1 to ref map. */
101 struct reftable_block_stats obj_stats;
102 /* stats for index blocks */
103 struct reftable_block_stats idx_stats;
104 /* stats for log blocks */
105 struct reftable_block_stats log_stats;
106
107 /* disambiguation length of shortened object IDs. */
108 int object_id_len;
109 };
110
111 struct reftable_writer;
112
113 /* Create a new writer. */
114 int reftable_writer_new(struct reftable_writer **out,
115 ssize_t (*writer_func)(void *, const void *, size_t),
116 int (*flush_func)(void *),
117 void *writer_arg, const struct reftable_write_options *opts);
118
119 /*
120 * Set the range of update indices for the records we will add. When writing a
121 * table into a stack, the min should be at least
122 * reftable_stack_next_update_index(), or REFTABLE_API_ERROR is returned.
123 *
124 * For transactional updates to a stack, typically min==max, and the
125 * update_index can be obtained by inspeciting the stack. When converting an
126 * existing ref database into a single reftable, this would be a range of
127 * update-index timestamps.
128 *
129 * The function should be called before adding any records to the writer. If not
130 * it will fail with REFTABLE_API_ERROR.
131 */
132 int reftable_writer_set_limits(struct reftable_writer *w, uint64_t min,
133 uint64_t max);
134
135 /*
136 Add a reftable_ref_record. The record should have names that come after
137 already added records.
138
139 The update_index must be within the limits set by
140 reftable_writer_set_limits(), or REFTABLE_API_ERROR is returned. It is an
141 REFTABLE_API_ERROR error to write a ref record after a log record.
142 */
143 int reftable_writer_add_ref(struct reftable_writer *w,
144 struct reftable_ref_record *ref);
145
146 /*
147 Convenience function to add multiple reftable_ref_records; the function sorts
148 the records before adding them, reordering the records array passed in.
149 */
150 int reftable_writer_add_refs(struct reftable_writer *w,
151 struct reftable_ref_record *refs, size_t n);
152
153 /*
154 adds reftable_log_records. Log records are keyed by (refname, decreasing
155 update_index). The key for the record added must come after the already added
156 log records.
157 */
158 int reftable_writer_add_log(struct reftable_writer *w,
159 struct reftable_log_record *log);
160
161 /*
162 Convenience function to add multiple reftable_log_records; the function sorts
163 the records before adding them, reordering records array passed in.
164 */
165 int reftable_writer_add_logs(struct reftable_writer *w,
166 struct reftable_log_record *logs, size_t n);
167
168 /* reftable_writer_close finalizes the reftable. The writer is retained so
169 * statistics can be inspected. */
170 int reftable_writer_close(struct reftable_writer *w);
171
172 /* writer_stats returns the statistics on the reftable being written.
173
174 This struct becomes invalid when the writer is freed.
175 */
176 const struct reftable_stats *reftable_writer_stats(struct reftable_writer *w);
177
178 /* reftable_writer_free deallocates memory for the writer */
179 void reftable_writer_free(struct reftable_writer *w);
180
181 #endif