]> git.ipfire.org Git - thirdparty/git.git/blame - reftable/iter.c
Merge branch 'rs/no-openssl-compilation-fix-on-macos'
[thirdparty/git.git] / reftable / iter.c
CommitLineData
46bc0e73
HWN
1/*
2Copyright 2020 Google LLC
3
4Use of this source code is governed by a BSD-style
5license that can be found in the LICENSE file or at
6https://developers.google.com/open-source/licenses/bsd
7*/
8
9#include "iter.h"
10
11#include "system.h"
12
13#include "block.h"
14#include "generic.h"
15#include "constants.h"
16#include "reader.h"
17#include "reftable-error.h"
18
46bc0e73
HWN
19static void filtering_ref_iterator_close(void *iter_arg)
20{
21 struct filtering_ref_iterator *fri = iter_arg;
22 strbuf_release(&fri->oid);
23 reftable_iterator_destroy(&fri->it);
24}
25
26static int filtering_ref_iterator_next(void *iter_arg,
27 struct reftable_record *rec)
28{
29 struct filtering_ref_iterator *fri = iter_arg;
66c0daba 30 struct reftable_ref_record *ref = &rec->u.ref;
46bc0e73
HWN
31 int err = 0;
32 while (1) {
33 err = reftable_iterator_next_ref(&fri->it, ref);
34 if (err != 0) {
35 break;
36 }
37
38 if (fri->double_check) {
39 struct reftable_iterator it = { NULL };
40
41 err = reftable_table_seek_ref(&fri->tab, &it,
42 ref->refname);
43 if (err == 0) {
44 err = reftable_iterator_next_ref(&it, ref);
45 }
46
47 reftable_iterator_destroy(&it);
48
49 if (err < 0) {
50 break;
51 }
52
53 if (err > 0) {
54 continue;
55 }
56 }
57
58 if (ref->value_type == REFTABLE_REF_VAL2 &&
59 (!memcmp(fri->oid.buf, ref->value.val2.target_value,
60 fri->oid.len) ||
61 !memcmp(fri->oid.buf, ref->value.val2.value,
62 fri->oid.len)))
63 return 0;
64
65 if (ref->value_type == REFTABLE_REF_VAL1 &&
66 !memcmp(fri->oid.buf, ref->value.val1, fri->oid.len)) {
67 return 0;
68 }
69 }
70
71 reftable_ref_record_release(ref);
72 return err;
73}
74
75static struct reftable_iterator_vtable filtering_ref_iterator_vtable = {
76 .next = &filtering_ref_iterator_next,
77 .close = &filtering_ref_iterator_close,
78};
79
80void iterator_from_filtering_ref_iterator(struct reftable_iterator *it,
81 struct filtering_ref_iterator *fri)
82{
83 assert(!it->ops);
84 it->iter_arg = fri;
85 it->ops = &filtering_ref_iterator_vtable;
86}
87
88static void indexed_table_ref_iter_close(void *p)
89{
90 struct indexed_table_ref_iter *it = p;
91 block_iter_close(&it->cur);
92 reftable_block_done(&it->block_reader.block);
93 reftable_free(it->offsets);
94 strbuf_release(&it->oid);
95}
96
97static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it)
98{
99 uint64_t off;
100 int err = 0;
101 if (it->offset_idx == it->offset_len) {
102 it->is_finished = 1;
103 return 1;
104 }
105
106 reftable_block_done(&it->block_reader.block);
107
108 off = it->offsets[it->offset_idx++];
109 err = reader_init_block_reader(it->r, &it->block_reader, off,
110 BLOCK_TYPE_REF);
111 if (err < 0) {
112 return err;
113 }
114 if (err > 0) {
115 /* indexed block does not exist. */
116 return REFTABLE_FORMAT_ERROR;
117 }
3122d440 118 block_iter_seek_start(&it->cur, &it->block_reader);
46bc0e73
HWN
119 return 0;
120}
121
122static int indexed_table_ref_iter_next(void *p, struct reftable_record *rec)
123{
124 struct indexed_table_ref_iter *it = p;
66c0daba 125 struct reftable_ref_record *ref = &rec->u.ref;
46bc0e73
HWN
126
127 while (1) {
128 int err = block_iter_next(&it->cur, rec);
129 if (err < 0) {
130 return err;
131 }
132
133 if (err > 0) {
134 err = indexed_table_ref_iter_next_block(it);
135 if (err < 0) {
136 return err;
137 }
138
139 if (it->is_finished) {
140 return 1;
141 }
142 continue;
143 }
144 /* BUG */
145 if (!memcmp(it->oid.buf, ref->value.val2.target_value,
146 it->oid.len) ||
147 !memcmp(it->oid.buf, ref->value.val2.value, it->oid.len)) {
148 return 0;
149 }
150 }
151}
152
153int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
154 struct reftable_reader *r, uint8_t *oid,
155 int oid_len, uint64_t *offsets, int offset_len)
156{
157 struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT;
b4ff12c8 158 struct indexed_table_ref_iter *itr = reftable_calloc(1, sizeof(*itr));
46bc0e73
HWN
159 int err = 0;
160
161 *itr = empty;
162 itr->r = r;
163 strbuf_add(&itr->oid, oid, oid_len);
164
165 itr->offsets = offsets;
166 itr->offset_len = offset_len;
167
168 err = indexed_table_ref_iter_next_block(itr);
169 if (err < 0) {
170 reftable_free(itr);
171 } else {
172 *dest = itr;
173 }
174 return err;
175}
176
177static struct reftable_iterator_vtable indexed_table_ref_iter_vtable = {
178 .next = &indexed_table_ref_iter_next,
179 .close = &indexed_table_ref_iter_close,
180};
181
182void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it,
183 struct indexed_table_ref_iter *itr)
184{
185 assert(!it->ops);
186 it->iter_arg = itr;
187 it->ops = &indexed_table_ref_iter_vtable;
188}