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