refs/reftable: print errors on compaction failure
[alt-git.git] / reftable / generic.c
blobb9f1c7c18a2efc48e91c2526a42bb9433783f8dd
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 int reftable_table_seek_ref(struct reftable_table *tab,
16 struct reftable_iterator *it, const char *name)
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);
25 int reftable_table_seek_log(struct reftable_table *tab,
26 struct reftable_iterator *it, const char *name)
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);
36 int reftable_table_read_ref(struct reftable_table *tab, const char *name,
37 struct reftable_ref_record *ref)
39 struct reftable_iterator it = { NULL };
40 int err = reftable_table_seek_ref(tab, &it, name);
41 if (err)
42 goto done;
44 err = reftable_iterator_next_ref(&it, ref);
45 if (err)
46 goto done;
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;
55 done:
56 reftable_iterator_destroy(&it);
57 return err;
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;
70 while (1) {
71 err = reftable_iterator_next_ref(&it, &ref);
72 if (err > 0) {
73 break;
75 if (err < 0) {
76 return err;
78 reftable_ref_record_print(&ref, hash_id);
80 reftable_iterator_destroy(&it);
81 reftable_ref_record_release(&ref);
83 err = reftable_table_seek_log(tab, &it, "");
84 if (err < 0) {
85 return err;
87 while (1) {
88 err = reftable_iterator_next_log(&it, &log);
89 if (err > 0) {
90 break;
92 if (err < 0) {
93 return err;
95 reftable_log_record_print(&log, hash_id);
97 reftable_iterator_destroy(&it);
98 reftable_log_record_release(&log);
99 return 0;
102 uint64_t reftable_table_max_update_index(struct reftable_table *tab)
104 return tab->ops->max_update_index(tab->table_arg);
107 uint64_t reftable_table_min_update_index(struct reftable_table *tab)
109 return tab->ops->min_update_index(tab->table_arg);
112 uint32_t reftable_table_hash_id(struct reftable_table *tab)
114 return tab->ops->hash_id(tab->table_arg);
117 void reftable_iterator_destroy(struct reftable_iterator *it)
119 if (!it->ops) {
120 return;
122 it->ops->close(it->iter_arg);
123 it->ops = NULL;
124 FREE_AND_NULL(it->iter_arg);
127 int reftable_iterator_next_ref(struct reftable_iterator *it,
128 struct reftable_ref_record *ref)
130 struct reftable_record rec = {
131 .type = BLOCK_TYPE_REF,
132 .u = {
133 .ref = *ref
136 int err = iterator_next(it, &rec);
137 *ref = rec.u.ref;
138 return err;
141 int reftable_iterator_next_log(struct reftable_iterator *it,
142 struct reftable_log_record *log)
144 struct reftable_record rec = {
145 .type = BLOCK_TYPE_LOG,
146 .u = {
147 .log = *log,
150 int err = iterator_next(it, &rec);
151 *log = rec.u.log;
152 return err;
155 int iterator_next(struct reftable_iterator *it, struct reftable_record *rec)
157 return it->ops->next(it->iter_arg, rec);
160 static int empty_iterator_next(void *arg, struct reftable_record *rec)
162 return 1;
165 static void empty_iterator_close(void *arg)
169 static struct reftable_iterator_vtable empty_vtable = {
170 .next = &empty_iterator_next,
171 .close = &empty_iterator_close,
174 void iterator_set_empty(struct reftable_iterator *it)
176 assert(!it->ops);
177 it->iter_arg = NULL;
178 it->ops = &empty_vtable;