]>
Commit | Line | Data |
---|---|---|
17df8dbe HWN |
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 | ||
66c0daba | 9 | #include "constants.h" |
17df8dbe HWN |
10 | #include "record.h" |
11 | #include "generic.h" | |
12 | #include "reftable-iterator.h" | |
13 | #include "reftable-generic.h" | |
14 | ||
5bf96e0c PS |
15 | void table_init_iter(struct reftable_table *tab, |
16 | struct reftable_iterator *it, | |
17 | uint8_t typ) | |
18 | { | |
19 | ||
20 | tab->ops->init_iter(tab->table_arg, it, typ); | |
21 | } | |
22 | ||
d76f0d3f PS |
23 | void reftable_table_init_ref_iter(struct reftable_table *tab, |
24 | struct reftable_iterator *it) | |
25 | { | |
26 | table_init_iter(tab, it, BLOCK_TYPE_REF); | |
27 | } | |
28 | ||
29 | void reftable_table_init_log_iter(struct reftable_table *tab, | |
30 | struct reftable_iterator *it) | |
31 | { | |
32 | table_init_iter(tab, it, BLOCK_TYPE_LOG); | |
33 | } | |
34 | ||
35 | int reftable_iterator_seek_ref(struct reftable_iterator *it, | |
36 | const char *name) | |
17df8dbe | 37 | { |
5bf96e0c PS |
38 | struct reftable_record want = { |
39 | .type = BLOCK_TYPE_REF, | |
40 | .u.ref = { | |
41 | .refname = (char *)name, | |
42 | }, | |
43 | }; | |
5bf96e0c | 44 | return it->ops->seek(it->iter_arg, &want); |
17df8dbe HWN |
45 | } |
46 | ||
d76f0d3f PS |
47 | int reftable_iterator_seek_log_at(struct reftable_iterator *it, |
48 | const char *name, uint64_t update_index) | |
17df8dbe | 49 | { |
5bf96e0c PS |
50 | struct reftable_record want = { |
51 | .type = BLOCK_TYPE_LOG, | |
52 | .u.log = { | |
53 | .refname = (char *)name, | |
d76f0d3f | 54 | .update_index = update_index, |
5bf96e0c PS |
55 | }, |
56 | }; | |
5bf96e0c | 57 | return it->ops->seek(it->iter_arg, &want); |
17df8dbe HWN |
58 | } |
59 | ||
d76f0d3f PS |
60 | int reftable_iterator_seek_log(struct reftable_iterator *it, |
61 | const char *name) | |
62 | { | |
63 | return reftable_iterator_seek_log_at(it, name, ~((uint64_t) 0)); | |
64 | } | |
65 | ||
17df8dbe HWN |
66 | int reftable_table_read_ref(struct reftable_table *tab, const char *name, |
67 | struct reftable_ref_record *ref) | |
68 | { | |
69 | struct reftable_iterator it = { NULL }; | |
d76f0d3f PS |
70 | int err; |
71 | ||
72 | reftable_table_init_ref_iter(tab, &it); | |
73 | ||
74 | err = reftable_iterator_seek_ref(&it, name); | |
17df8dbe HWN |
75 | if (err) |
76 | goto done; | |
77 | ||
78 | err = reftable_iterator_next_ref(&it, ref); | |
79 | if (err) | |
80 | goto done; | |
81 | ||
82 | if (strcmp(ref->refname, name) || | |
83 | reftable_ref_record_is_deletion(ref)) { | |
84 | reftable_ref_record_release(ref); | |
85 | err = 1; | |
86 | goto done; | |
87 | } | |
88 | ||
89 | done: | |
90 | reftable_iterator_destroy(&it); | |
91 | return err; | |
92 | } | |
93 | ||
94 | int reftable_table_print(struct reftable_table *tab) { | |
95 | struct reftable_iterator it = { NULL }; | |
96 | struct reftable_ref_record ref = { NULL }; | |
97 | struct reftable_log_record log = { NULL }; | |
98 | uint32_t hash_id = reftable_table_hash_id(tab); | |
d76f0d3f PS |
99 | int err; |
100 | ||
101 | reftable_table_init_ref_iter(tab, &it); | |
102 | ||
103 | err = reftable_iterator_seek_ref(&it, ""); | |
104 | if (err < 0) | |
17df8dbe | 105 | return err; |
17df8dbe HWN |
106 | |
107 | while (1) { | |
108 | err = reftable_iterator_next_ref(&it, &ref); | |
109 | if (err > 0) { | |
110 | break; | |
111 | } | |
112 | if (err < 0) { | |
113 | return err; | |
114 | } | |
115 | reftable_ref_record_print(&ref, hash_id); | |
116 | } | |
117 | reftable_iterator_destroy(&it); | |
118 | reftable_ref_record_release(&ref); | |
119 | ||
d76f0d3f PS |
120 | reftable_table_init_log_iter(tab, &it); |
121 | ||
122 | err = reftable_iterator_seek_log(&it, ""); | |
123 | if (err < 0) | |
17df8dbe | 124 | return err; |
d76f0d3f | 125 | |
17df8dbe HWN |
126 | while (1) { |
127 | err = reftable_iterator_next_log(&it, &log); | |
128 | if (err > 0) { | |
129 | break; | |
130 | } | |
131 | if (err < 0) { | |
132 | return err; | |
133 | } | |
134 | reftable_log_record_print(&log, hash_id); | |
135 | } | |
136 | reftable_iterator_destroy(&it); | |
137 | reftable_log_record_release(&log); | |
138 | return 0; | |
139 | } | |
140 | ||
141 | uint64_t reftable_table_max_update_index(struct reftable_table *tab) | |
142 | { | |
143 | return tab->ops->max_update_index(tab->table_arg); | |
144 | } | |
145 | ||
146 | uint64_t reftable_table_min_update_index(struct reftable_table *tab) | |
147 | { | |
148 | return tab->ops->min_update_index(tab->table_arg); | |
149 | } | |
150 | ||
151 | uint32_t reftable_table_hash_id(struct reftable_table *tab) | |
152 | { | |
153 | return tab->ops->hash_id(tab->table_arg); | |
154 | } | |
155 | ||
156 | void reftable_iterator_destroy(struct reftable_iterator *it) | |
157 | { | |
158 | if (!it->ops) { | |
159 | return; | |
160 | } | |
161 | it->ops->close(it->iter_arg); | |
162 | it->ops = NULL; | |
163 | FREE_AND_NULL(it->iter_arg); | |
164 | } | |
165 | ||
166 | int reftable_iterator_next_ref(struct reftable_iterator *it, | |
167 | struct reftable_ref_record *ref) | |
168 | { | |
66c0daba HWN |
169 | struct reftable_record rec = { |
170 | .type = BLOCK_TYPE_REF, | |
33665d98 ÆAB |
171 | .u = { |
172 | .ref = *ref | |
173 | }, | |
66c0daba HWN |
174 | }; |
175 | int err = iterator_next(it, &rec); | |
176 | *ref = rec.u.ref; | |
177 | return err; | |
17df8dbe HWN |
178 | } |
179 | ||
180 | int reftable_iterator_next_log(struct reftable_iterator *it, | |
181 | struct reftable_log_record *log) | |
182 | { | |
66c0daba HWN |
183 | struct reftable_record rec = { |
184 | .type = BLOCK_TYPE_LOG, | |
33665d98 ÆAB |
185 | .u = { |
186 | .log = *log, | |
187 | }, | |
66c0daba HWN |
188 | }; |
189 | int err = iterator_next(it, &rec); | |
190 | *log = rec.u.log; | |
191 | return err; | |
17df8dbe HWN |
192 | } |
193 | ||
5bf96e0c PS |
194 | int iterator_seek(struct reftable_iterator *it, struct reftable_record *want) |
195 | { | |
196 | return it->ops->seek(it->iter_arg, want); | |
197 | } | |
198 | ||
17df8dbe HWN |
199 | int iterator_next(struct reftable_iterator *it, struct reftable_record *rec) |
200 | { | |
201 | return it->ops->next(it->iter_arg, rec); | |
202 | } | |
203 | ||
5bf96e0c PS |
204 | static int empty_iterator_seek(void *arg, struct reftable_record *want) |
205 | { | |
206 | return 0; | |
207 | } | |
208 | ||
17df8dbe HWN |
209 | static int empty_iterator_next(void *arg, struct reftable_record *rec) |
210 | { | |
211 | return 1; | |
212 | } | |
213 | ||
214 | static void empty_iterator_close(void *arg) | |
215 | { | |
216 | } | |
217 | ||
218 | static struct reftable_iterator_vtable empty_vtable = { | |
5bf96e0c | 219 | .seek = &empty_iterator_seek, |
17df8dbe HWN |
220 | .next = &empty_iterator_next, |
221 | .close = &empty_iterator_close, | |
222 | }; | |
223 | ||
224 | void iterator_set_empty(struct reftable_iterator *it) | |
225 | { | |
226 | assert(!it->ops); | |
227 | it->iter_arg = NULL; | |
228 | it->ops = &empty_vtable; | |
229 | } |