builtin/bundle: have unbundle check for repo before opening its bundle
[git/gitster.git] / reftable / generic.c
blob28ae26145e6ef64ad970e66a6fa935092faba785
1 /*
2 Copyright 2020 Google LLC
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 */
9 #include "constants.h"
10 #include "record.h"
11 #include "generic.h"
12 #include "reftable-iterator.h"
13 #include "reftable-generic.h"
15 void table_init_iter(struct reftable_table *tab,
16 struct reftable_iterator *it,
17 uint8_t typ)
20 tab->ops->init_iter(tab->table_arg, it, typ);
23 void reftable_table_init_ref_iter(struct reftable_table *tab,
24 struct reftable_iterator *it)
26 table_init_iter(tab, it, BLOCK_TYPE_REF);
29 void reftable_table_init_log_iter(struct reftable_table *tab,
30 struct reftable_iterator *it)
32 table_init_iter(tab, it, BLOCK_TYPE_LOG);
35 int reftable_iterator_seek_ref(struct reftable_iterator *it,
36 const char *name)
38 struct reftable_record want = {
39 .type = BLOCK_TYPE_REF,
40 .u.ref = {
41 .refname = (char *)name,
44 return it->ops->seek(it->iter_arg, &want);
47 int reftable_iterator_seek_log_at(struct reftable_iterator *it,
48 const char *name, uint64_t update_index)
50 struct reftable_record want = {
51 .type = BLOCK_TYPE_LOG,
52 .u.log = {
53 .refname = (char *)name,
54 .update_index = update_index,
57 return it->ops->seek(it->iter_arg, &want);
60 int reftable_iterator_seek_log(struct reftable_iterator *it,
61 const char *name)
63 return reftable_iterator_seek_log_at(it, name, ~((uint64_t) 0));
66 int reftable_table_read_ref(struct reftable_table *tab, const char *name,
67 struct reftable_ref_record *ref)
69 struct reftable_iterator it = { NULL };
70 int err;
72 reftable_table_init_ref_iter(tab, &it);
74 err = reftable_iterator_seek_ref(&it, name);
75 if (err)
76 goto done;
78 err = reftable_iterator_next_ref(&it, ref);
79 if (err)
80 goto done;
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;
89 done:
90 reftable_iterator_destroy(&it);
91 return err;
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);
99 int err;
101 reftable_table_init_ref_iter(tab, &it);
103 err = reftable_iterator_seek_ref(&it, "");
104 if (err < 0)
105 return err;
107 while (1) {
108 err = reftable_iterator_next_ref(&it, &ref);
109 if (err > 0) {
110 break;
112 if (err < 0) {
113 return err;
115 reftable_ref_record_print(&ref, hash_id);
117 reftable_iterator_destroy(&it);
118 reftable_ref_record_release(&ref);
120 reftable_table_init_log_iter(tab, &it);
122 err = reftable_iterator_seek_log(&it, "");
123 if (err < 0)
124 return err;
126 while (1) {
127 err = reftable_iterator_next_log(&it, &log);
128 if (err > 0) {
129 break;
131 if (err < 0) {
132 return err;
134 reftable_log_record_print(&log, hash_id);
136 reftable_iterator_destroy(&it);
137 reftable_log_record_release(&log);
138 return 0;
141 uint64_t reftable_table_max_update_index(struct reftable_table *tab)
143 return tab->ops->max_update_index(tab->table_arg);
146 uint64_t reftable_table_min_update_index(struct reftable_table *tab)
148 return tab->ops->min_update_index(tab->table_arg);
151 uint32_t reftable_table_hash_id(struct reftable_table *tab)
153 return tab->ops->hash_id(tab->table_arg);
156 void reftable_iterator_destroy(struct reftable_iterator *it)
158 if (!it->ops) {
159 return;
161 it->ops->close(it->iter_arg);
162 it->ops = NULL;
163 FREE_AND_NULL(it->iter_arg);
166 int reftable_iterator_next_ref(struct reftable_iterator *it,
167 struct reftable_ref_record *ref)
169 struct reftable_record rec = {
170 .type = BLOCK_TYPE_REF,
171 .u = {
172 .ref = *ref
175 int err = iterator_next(it, &rec);
176 *ref = rec.u.ref;
177 return err;
180 int reftable_iterator_next_log(struct reftable_iterator *it,
181 struct reftable_log_record *log)
183 struct reftable_record rec = {
184 .type = BLOCK_TYPE_LOG,
185 .u = {
186 .log = *log,
189 int err = iterator_next(it, &rec);
190 *log = rec.u.log;
191 return err;
194 int iterator_seek(struct reftable_iterator *it, struct reftable_record *want)
196 return it->ops->seek(it->iter_arg, want);
199 int iterator_next(struct reftable_iterator *it, struct reftable_record *rec)
201 return it->ops->next(it->iter_arg, rec);
204 static int empty_iterator_seek(void *arg, struct reftable_record *want)
206 return 0;
209 static int empty_iterator_next(void *arg, struct reftable_record *rec)
211 return 1;
214 static void empty_iterator_close(void *arg)
218 static struct reftable_iterator_vtable empty_vtable = {
219 .seek = &empty_iterator_seek,
220 .next = &empty_iterator_next,
221 .close = &empty_iterator_close,
224 void iterator_set_empty(struct reftable_iterator *it)
226 assert(!it->ops);
227 it->iter_arg = NULL;
228 it->ops = &empty_vtable;