/src/git/reftable/record.h
Line | Count | Source |
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 RECORD_H |
10 | | #define RECORD_H |
11 | | |
12 | | #include "basics.h" |
13 | | #include "system.h" |
14 | | |
15 | | #include <stdint.h> |
16 | | |
17 | | #include "reftable-record.h" |
18 | | |
19 | | /* |
20 | | * A substring of existing string data. This structure takes no responsibility |
21 | | * for the lifetime of the data it points to. |
22 | | */ |
23 | | struct string_view { |
24 | | uint8_t *buf; |
25 | | size_t len; |
26 | | }; |
27 | | |
28 | | /* Advance `s.buf` by `n`, and decrease length. */ |
29 | | static inline void string_view_consume(struct string_view *s, int n) |
30 | 0 | { |
31 | 0 | s->buf += n; |
32 | 0 | s->len -= n; |
33 | 0 | } Unexecuted instantiation: iter.c:string_view_consume Unexecuted instantiation: record.c:string_view_consume Unexecuted instantiation: stack.c:string_view_consume Unexecuted instantiation: table.c:string_view_consume Unexecuted instantiation: writer.c:string_view_consume Unexecuted instantiation: block.c:string_view_consume Unexecuted instantiation: merged.c:string_view_consume Unexecuted instantiation: pq.c:string_view_consume |
34 | | |
35 | | /* |
36 | | * Decode and encode a varint. Returns the number of bytes read/written, or a |
37 | | * negative value in case encoding/decoding the varint has failed. |
38 | | */ |
39 | | int get_var_int(uint64_t *dest, struct string_view *in); |
40 | | int put_var_int(struct string_view *dest, uint64_t val); |
41 | | |
42 | | /* Methods for records. */ |
43 | | struct reftable_record_vtable { |
44 | | /* encode the key of to a uint8_t reftable_buf. */ |
45 | | int (*key)(const void *rec, struct reftable_buf *dest); |
46 | | |
47 | | /* The record type of ('r' for ref). */ |
48 | | uint8_t type; |
49 | | |
50 | | int (*copy_from)(void *dest, const void *src, uint32_t hash_size); |
51 | | |
52 | | /* a value of [0..7], indicating record subvariants (eg. ref vs. symref |
53 | | * vs ref deletion) */ |
54 | | uint8_t (*val_type)(const void *rec); |
55 | | |
56 | | /* encodes rec into dest, returning how much space was used. */ |
57 | | int (*encode)(const void *rec, struct string_view dest, uint32_t hash_size); |
58 | | |
59 | | /* decode data from `src` into the record. */ |
60 | | int (*decode)(void *rec, struct reftable_buf key, uint8_t extra, |
61 | | struct string_view src, uint32_t hash_size, |
62 | | struct reftable_buf *scratch); |
63 | | |
64 | | /* deallocate and null the record. */ |
65 | | void (*release)(void *rec); |
66 | | |
67 | | /* is this a tombstone? */ |
68 | | int (*is_deletion)(const void *rec); |
69 | | |
70 | | /* Are two records equal? This assumes they have the same type. Returns 0 for non-equal. */ |
71 | | int (*equal)(const void *a, const void *b, uint32_t hash_size); |
72 | | |
73 | | /* |
74 | | * Compare keys of two records with each other. The records must have |
75 | | * the same type. |
76 | | */ |
77 | | int (*cmp)(const void *a, const void *b); |
78 | | }; |
79 | | |
80 | | /* returns true for recognized block types. Block start with the block type. */ |
81 | | int reftable_is_block_type(uint8_t typ); |
82 | | |
83 | | /* Encode `key` into `dest`. Sets `is_restart` to indicate a restart. Returns |
84 | | * number of bytes written. */ |
85 | | int reftable_encode_key(int *is_restart, struct string_view dest, |
86 | | struct reftable_buf prev_key, struct reftable_buf key, |
87 | | uint8_t extra); |
88 | | |
89 | | /* Decode a record's key lengths. */ |
90 | | int reftable_decode_keylen(struct string_view in, |
91 | | uint64_t *prefix_len, |
92 | | uint64_t *suffix_len, |
93 | | uint8_t *extra); |
94 | | |
95 | | /* |
96 | | * Decode into `last_key` and `extra` from `in`. `last_key` is expected to |
97 | | * contain the decoded key of the preceding record, if any. |
98 | | */ |
99 | | int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra, |
100 | | struct string_view in); |
101 | | |
102 | | /* reftable_index_record are used internally to speed up lookups. */ |
103 | | struct reftable_index_record { |
104 | | uint64_t offset; /* Offset of block */ |
105 | | struct reftable_buf last_key; /* Last key of the block. */ |
106 | | }; |
107 | | |
108 | | /* reftable_obj_record stores an object ID => ref mapping. */ |
109 | | struct reftable_obj_record { |
110 | | uint8_t *hash_prefix; /* leading bytes of the object ID */ |
111 | | int hash_prefix_len; /* number of leading bytes. Constant |
112 | | * across a single table. */ |
113 | | uint64_t *offsets; /* a vector of file offsets. */ |
114 | | int offset_len; |
115 | | }; |
116 | | |
117 | | /* record is a generic wrapper for different types of records. It is normally |
118 | | * created on the stack, or embedded within another struct. If the type is |
119 | | * known, a fresh instance can be initialized explicitly. Otherwise, use |
120 | | * `reftable_record_init()` to initialize generically (as the index_record is |
121 | | * not valid as 0-initialized structure) |
122 | | */ |
123 | | struct reftable_record { |
124 | | uint8_t type; |
125 | | union { |
126 | | struct reftable_ref_record ref; |
127 | | struct reftable_log_record log; |
128 | | struct reftable_obj_record obj; |
129 | | struct reftable_index_record idx; |
130 | | } u; |
131 | | }; |
132 | | |
133 | | /* Initialize the reftable record for the given type. */ |
134 | | int reftable_record_init(struct reftable_record *rec, uint8_t typ); |
135 | | |
136 | | /* see struct record_vtable */ |
137 | | int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b, int *cmp); |
138 | | int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, uint32_t hash_size); |
139 | | int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest); |
140 | | int reftable_record_copy_from(struct reftable_record *rec, |
141 | | struct reftable_record *src, uint32_t hash_size); |
142 | | uint8_t reftable_record_val_type(struct reftable_record *rec); |
143 | | int reftable_record_encode(struct reftable_record *rec, struct string_view dest, |
144 | | uint32_t hash_size); |
145 | | int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key, |
146 | | uint8_t extra, struct string_view src, |
147 | | uint32_t hash_size, struct reftable_buf *scratch); |
148 | | int reftable_record_is_deletion(struct reftable_record *rec); |
149 | | |
150 | | static inline uint8_t reftable_record_type(struct reftable_record *rec) |
151 | 0 | { |
152 | 0 | return rec->type; |
153 | 0 | } Unexecuted instantiation: iter.c:reftable_record_type Unexecuted instantiation: record.c:reftable_record_type Unexecuted instantiation: stack.c:reftable_record_type Unexecuted instantiation: table.c:reftable_record_type Unexecuted instantiation: writer.c:reftable_record_type Unexecuted instantiation: block.c:reftable_record_type Unexecuted instantiation: merged.c:reftable_record_type Unexecuted instantiation: pq.c:reftable_record_type |
154 | | |
155 | | /* frees and zeroes out the embedded record */ |
156 | | void reftable_record_release(struct reftable_record *rec); |
157 | | |
158 | | /* for qsort. */ |
159 | | int reftable_ref_record_compare_name(const void *a, const void *b); |
160 | | |
161 | | /* for qsort. */ |
162 | | int reftable_log_record_compare_key(const void *a, const void *b); |
163 | | |
164 | | #endif |