]> git.ipfire.org Git - thirdparty/git.git/blob - reftable/generic.c
Merge branch 'rs/opt-parse-long-fixups'
[thirdparty/git.git] / reftable / generic.c
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 #include "constants.h"
10 #include "record.h"
11 #include "generic.h"
12 #include "reftable-iterator.h"
13 #include "reftable-generic.h"
14
15 int reftable_table_seek_ref(struct reftable_table *tab,
16 struct reftable_iterator *it, const char *name)
17 {
18 struct reftable_record rec = { .type = BLOCK_TYPE_REF,
19 .u.ref = {
20 .refname = (char *)name,
21 } };
22 return tab->ops->seek_record(tab->table_arg, it, &rec);
23 }
24
25 int reftable_table_seek_log(struct reftable_table *tab,
26 struct reftable_iterator *it, const char *name)
27 {
28 struct reftable_record rec = { .type = BLOCK_TYPE_LOG,
29 .u.log = {
30 .refname = (char *)name,
31 .update_index = ~((uint64_t)0),
32 } };
33 return tab->ops->seek_record(tab->table_arg, it, &rec);
34 }
35
36 int reftable_table_read_ref(struct reftable_table *tab, const char *name,
37 struct reftable_ref_record *ref)
38 {
39 struct reftable_iterator it = { NULL };
40 int err = reftable_table_seek_ref(tab, &it, name);
41 if (err)
42 goto done;
43
44 err = reftable_iterator_next_ref(&it, ref);
45 if (err)
46 goto done;
47
48 if (strcmp(ref->refname, name) ||
49 reftable_ref_record_is_deletion(ref)) {
50 reftable_ref_record_release(ref);
51 err = 1;
52 goto done;
53 }
54
55 done:
56 reftable_iterator_destroy(&it);
57 return err;
58 }
59
60 int reftable_table_print(struct reftable_table *tab) {
61 struct reftable_iterator it = { NULL };
62 struct reftable_ref_record ref = { NULL };
63 struct reftable_log_record log = { NULL };
64 uint32_t hash_id = reftable_table_hash_id(tab);
65 int err = reftable_table_seek_ref(tab, &it, "");
66 if (err < 0) {
67 return err;
68 }
69
70 while (1) {
71 err = reftable_iterator_next_ref(&it, &ref);
72 if (err > 0) {
73 break;
74 }
75 if (err < 0) {
76 return err;
77 }
78 reftable_ref_record_print(&ref, hash_id);
79 }
80 reftable_iterator_destroy(&it);
81 reftable_ref_record_release(&ref);
82
83 err = reftable_table_seek_log(tab, &it, "");
84 if (err < 0) {
85 return err;
86 }
87 while (1) {
88 err = reftable_iterator_next_log(&it, &log);
89 if (err > 0) {
90 break;
91 }
92 if (err < 0) {
93 return err;
94 }
95 reftable_log_record_print(&log, hash_id);
96 }
97 reftable_iterator_destroy(&it);
98 reftable_log_record_release(&log);
99 return 0;
100 }
101
102 uint64_t reftable_table_max_update_index(struct reftable_table *tab)
103 {
104 return tab->ops->max_update_index(tab->table_arg);
105 }
106
107 uint64_t reftable_table_min_update_index(struct reftable_table *tab)
108 {
109 return tab->ops->min_update_index(tab->table_arg);
110 }
111
112 uint32_t reftable_table_hash_id(struct reftable_table *tab)
113 {
114 return tab->ops->hash_id(tab->table_arg);
115 }
116
117 void reftable_iterator_destroy(struct reftable_iterator *it)
118 {
119 if (!it->ops) {
120 return;
121 }
122 it->ops->close(it->iter_arg);
123 it->ops = NULL;
124 FREE_AND_NULL(it->iter_arg);
125 }
126
127 int reftable_iterator_next_ref(struct reftable_iterator *it,
128 struct reftable_ref_record *ref)
129 {
130 struct reftable_record rec = {
131 .type = BLOCK_TYPE_REF,
132 .u = {
133 .ref = *ref
134 },
135 };
136 int err = iterator_next(it, &rec);
137 *ref = rec.u.ref;
138 return err;
139 }
140
141 int reftable_iterator_next_log(struct reftable_iterator *it,
142 struct reftable_log_record *log)
143 {
144 struct reftable_record rec = {
145 .type = BLOCK_TYPE_LOG,
146 .u = {
147 .log = *log,
148 },
149 };
150 int err = iterator_next(it, &rec);
151 *log = rec.u.log;
152 return err;
153 }
154
155 int iterator_next(struct reftable_iterator *it, struct reftable_record *rec)
156 {
157 return it->ops->next(it->iter_arg, rec);
158 }
159
160 static int empty_iterator_next(void *arg, struct reftable_record *rec)
161 {
162 return 1;
163 }
164
165 static void empty_iterator_close(void *arg)
166 {
167 }
168
169 static struct reftable_iterator_vtable empty_vtable = {
170 .next = &empty_iterator_next,
171 .close = &empty_iterator_close,
172 };
173
174 void iterator_set_empty(struct reftable_iterator *it)
175 {
176 assert(!it->ops);
177 it->iter_arg = NULL;
178 it->ops = &empty_vtable;
179 }