Merge branch 'ds/sparse-checkout-malformed-pattern-fix'
[git/debian.git] / reftable / generic.c
blob7a8a738d860982c57398dad589d11bd233b9266c
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 "basics.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_ref_record ref = {
19 .refname = (char *)name,
21 struct reftable_record rec = { NULL };
22 reftable_record_from_ref(&rec, &ref);
23 return tab->ops->seek_record(tab->table_arg, it, &rec);
26 int reftable_table_seek_log(struct reftable_table *tab,
27 struct reftable_iterator *it, const char *name)
29 struct reftable_log_record log = {
30 .refname = (char *)name,
31 .update_index = ~((uint64_t)0),
33 struct reftable_record rec = { NULL };
34 reftable_record_from_log(&rec, &log);
35 return tab->ops->seek_record(tab->table_arg, it, &rec);
38 int reftable_table_read_ref(struct reftable_table *tab, const char *name,
39 struct reftable_ref_record *ref)
41 struct reftable_iterator it = { NULL };
42 int err = reftable_table_seek_ref(tab, &it, name);
43 if (err)
44 goto done;
46 err = reftable_iterator_next_ref(&it, ref);
47 if (err)
48 goto done;
50 if (strcmp(ref->refname, name) ||
51 reftable_ref_record_is_deletion(ref)) {
52 reftable_ref_record_release(ref);
53 err = 1;
54 goto done;
57 done:
58 reftable_iterator_destroy(&it);
59 return err;
62 int reftable_table_print(struct reftable_table *tab) {
63 struct reftable_iterator it = { NULL };
64 struct reftable_ref_record ref = { NULL };
65 struct reftable_log_record log = { NULL };
66 uint32_t hash_id = reftable_table_hash_id(tab);
67 int err = reftable_table_seek_ref(tab, &it, "");
68 if (err < 0) {
69 return err;
72 while (1) {
73 err = reftable_iterator_next_ref(&it, &ref);
74 if (err > 0) {
75 break;
77 if (err < 0) {
78 return err;
80 reftable_ref_record_print(&ref, hash_id);
82 reftable_iterator_destroy(&it);
83 reftable_ref_record_release(&ref);
85 err = reftable_table_seek_log(tab, &it, "");
86 if (err < 0) {
87 return err;
89 while (1) {
90 err = reftable_iterator_next_log(&it, &log);
91 if (err > 0) {
92 break;
94 if (err < 0) {
95 return err;
97 reftable_log_record_print(&log, hash_id);
99 reftable_iterator_destroy(&it);
100 reftable_log_record_release(&log);
101 return 0;
104 uint64_t reftable_table_max_update_index(struct reftable_table *tab)
106 return tab->ops->max_update_index(tab->table_arg);
109 uint64_t reftable_table_min_update_index(struct reftable_table *tab)
111 return tab->ops->min_update_index(tab->table_arg);
114 uint32_t reftable_table_hash_id(struct reftable_table *tab)
116 return tab->ops->hash_id(tab->table_arg);
119 void reftable_iterator_destroy(struct reftable_iterator *it)
121 if (!it->ops) {
122 return;
124 it->ops->close(it->iter_arg);
125 it->ops = NULL;
126 FREE_AND_NULL(it->iter_arg);
129 int reftable_iterator_next_ref(struct reftable_iterator *it,
130 struct reftable_ref_record *ref)
132 struct reftable_record rec = { NULL };
133 reftable_record_from_ref(&rec, ref);
134 return iterator_next(it, &rec);
137 int reftable_iterator_next_log(struct reftable_iterator *it,
138 struct reftable_log_record *log)
140 struct reftable_record rec = { NULL };
141 reftable_record_from_log(&rec, log);
142 return iterator_next(it, &rec);
145 int iterator_next(struct reftable_iterator *it, struct reftable_record *rec)
147 return it->ops->next(it->iter_arg, rec);
150 static int empty_iterator_next(void *arg, struct reftable_record *rec)
152 return 1;
155 static void empty_iterator_close(void *arg)
159 static struct reftable_iterator_vtable empty_vtable = {
160 .next = &empty_iterator_next,
161 .close = &empty_iterator_close,
164 void iterator_set_empty(struct reftable_iterator *it)
166 assert(!it->ops);
167 it->iter_arg = NULL;
168 it->ops = &empty_vtable;