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
15 #include "constants.h"
17 #include "reftable-error.h"
19 static void filtering_ref_iterator_close(void *iter_arg
)
21 struct filtering_ref_iterator
*fri
= iter_arg
;
22 strbuf_release(&fri
->oid
);
23 reftable_iterator_destroy(&fri
->it
);
26 static int filtering_ref_iterator_next(void *iter_arg
,
27 struct reftable_record
*rec
)
29 struct filtering_ref_iterator
*fri
= iter_arg
;
30 struct reftable_ref_record
*ref
= &rec
->u
.ref
;
33 err
= reftable_iterator_next_ref(&fri
->it
, ref
);
38 if (fri
->double_check
) {
39 struct reftable_iterator it
= { NULL
};
41 err
= reftable_table_seek_ref(&fri
->tab
, &it
,
44 err
= reftable_iterator_next_ref(&it
, ref
);
47 reftable_iterator_destroy(&it
);
58 if (ref
->value_type
== REFTABLE_REF_VAL2
&&
59 (!memcmp(fri
->oid
.buf
, ref
->value
.val2
.target_value
,
61 !memcmp(fri
->oid
.buf
, ref
->value
.val2
.value
,
65 if (ref
->value_type
== REFTABLE_REF_VAL1
&&
66 !memcmp(fri
->oid
.buf
, ref
->value
.val1
, fri
->oid
.len
)) {
71 reftable_ref_record_release(ref
);
75 static struct reftable_iterator_vtable filtering_ref_iterator_vtable
= {
76 .next
= &filtering_ref_iterator_next
,
77 .close
= &filtering_ref_iterator_close
,
80 void iterator_from_filtering_ref_iterator(struct reftable_iterator
*it
,
81 struct filtering_ref_iterator
*fri
)
85 it
->ops
= &filtering_ref_iterator_vtable
;
88 static void indexed_table_ref_iter_close(void *p
)
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
);
97 static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter
*it
)
101 if (it
->offset_idx
== it
->offset_len
) {
106 reftable_block_done(&it
->block_reader
.block
);
108 off
= it
->offsets
[it
->offset_idx
++];
109 err
= reader_init_block_reader(it
->r
, &it
->block_reader
, off
,
115 /* indexed block does not exist. */
116 return REFTABLE_FORMAT_ERROR
;
118 block_reader_start(&it
->block_reader
, &it
->cur
);
122 static int indexed_table_ref_iter_next(void *p
, struct reftable_record
*rec
)
124 struct indexed_table_ref_iter
*it
= p
;
125 struct reftable_ref_record
*ref
= &rec
->u
.ref
;
128 int err
= block_iter_next(&it
->cur
, rec
);
134 err
= indexed_table_ref_iter_next_block(it
);
139 if (it
->is_finished
) {
145 if (!memcmp(it
->oid
.buf
, ref
->value
.val2
.target_value
,
147 !memcmp(it
->oid
.buf
, ref
->value
.val2
.value
, it
->oid
.len
)) {
153 int 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
)
157 struct indexed_table_ref_iter empty
= INDEXED_TABLE_REF_ITER_INIT
;
158 struct indexed_table_ref_iter
*itr
= reftable_calloc(1, sizeof(*itr
));
163 strbuf_add(&itr
->oid
, oid
, oid_len
);
165 itr
->offsets
= offsets
;
166 itr
->offset_len
= offset_len
;
168 err
= indexed_table_ref_iter_next_block(itr
);
177 static struct reftable_iterator_vtable indexed_table_ref_iter_vtable
= {
178 .next
= &indexed_table_ref_iter_next
,
179 .close
= &indexed_table_ref_iter_close
,
182 void iterator_from_indexed_table_ref_iter(struct reftable_iterator
*it
,
183 struct indexed_table_ref_iter
*itr
)
187 it
->ops
= &indexed_table_ref_iter_vtable
;