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 int iterator_is_null(struct reftable_iterator
*it
)
24 static void filtering_ref_iterator_close(void *iter_arg
)
26 struct filtering_ref_iterator
*fri
= iter_arg
;
27 strbuf_release(&fri
->oid
);
28 reftable_iterator_destroy(&fri
->it
);
31 static int filtering_ref_iterator_next(void *iter_arg
,
32 struct reftable_record
*rec
)
34 struct filtering_ref_iterator
*fri
= iter_arg
;
35 struct reftable_ref_record
*ref
= &rec
->u
.ref
;
38 err
= reftable_iterator_next_ref(&fri
->it
, ref
);
43 if (fri
->double_check
) {
44 struct reftable_iterator it
= { NULL
};
46 err
= reftable_table_seek_ref(&fri
->tab
, &it
,
49 err
= reftable_iterator_next_ref(&it
, ref
);
52 reftable_iterator_destroy(&it
);
63 if (ref
->value_type
== REFTABLE_REF_VAL2
&&
64 (!memcmp(fri
->oid
.buf
, ref
->value
.val2
.target_value
,
66 !memcmp(fri
->oid
.buf
, ref
->value
.val2
.value
,
70 if (ref
->value_type
== REFTABLE_REF_VAL1
&&
71 !memcmp(fri
->oid
.buf
, ref
->value
.val1
, fri
->oid
.len
)) {
76 reftable_ref_record_release(ref
);
80 static struct reftable_iterator_vtable filtering_ref_iterator_vtable
= {
81 .next
= &filtering_ref_iterator_next
,
82 .close
= &filtering_ref_iterator_close
,
85 void iterator_from_filtering_ref_iterator(struct reftable_iterator
*it
,
86 struct filtering_ref_iterator
*fri
)
90 it
->ops
= &filtering_ref_iterator_vtable
;
93 static void indexed_table_ref_iter_close(void *p
)
95 struct indexed_table_ref_iter
*it
= p
;
96 block_iter_close(&it
->cur
);
97 reftable_block_done(&it
->block_reader
.block
);
98 reftable_free(it
->offsets
);
99 strbuf_release(&it
->oid
);
102 static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter
*it
)
106 if (it
->offset_idx
== it
->offset_len
) {
111 reftable_block_done(&it
->block_reader
.block
);
113 off
= it
->offsets
[it
->offset_idx
++];
114 err
= reader_init_block_reader(it
->r
, &it
->block_reader
, off
,
120 /* indexed block does not exist. */
121 return REFTABLE_FORMAT_ERROR
;
123 block_reader_start(&it
->block_reader
, &it
->cur
);
127 static int indexed_table_ref_iter_next(void *p
, struct reftable_record
*rec
)
129 struct indexed_table_ref_iter
*it
= p
;
130 struct reftable_ref_record
*ref
= &rec
->u
.ref
;
133 int err
= block_iter_next(&it
->cur
, rec
);
139 err
= indexed_table_ref_iter_next_block(it
);
144 if (it
->is_finished
) {
150 if (!memcmp(it
->oid
.buf
, ref
->value
.val2
.target_value
,
152 !memcmp(it
->oid
.buf
, ref
->value
.val2
.value
, it
->oid
.len
)) {
158 int new_indexed_table_ref_iter(struct indexed_table_ref_iter
**dest
,
159 struct reftable_reader
*r
, uint8_t *oid
,
160 int oid_len
, uint64_t *offsets
, int offset_len
)
162 struct indexed_table_ref_iter empty
= INDEXED_TABLE_REF_ITER_INIT
;
163 struct indexed_table_ref_iter
*itr
=
164 reftable_calloc(sizeof(struct indexed_table_ref_iter
));
169 strbuf_add(&itr
->oid
, oid
, oid_len
);
171 itr
->offsets
= offsets
;
172 itr
->offset_len
= offset_len
;
174 err
= indexed_table_ref_iter_next_block(itr
);
183 static struct reftable_iterator_vtable indexed_table_ref_iter_vtable
= {
184 .next
= &indexed_table_ref_iter_next
,
185 .close
= &indexed_table_ref_iter_close
,
188 void iterator_from_indexed_table_ref_iter(struct reftable_iterator
*it
,
189 struct indexed_table_ref_iter
*itr
)
193 it
->ops
= &indexed_table_ref_iter_vtable
;