diff options
Diffstat (limited to 'reftable/iter.c')
-rw-r--r-- | reftable/iter.c | 173 |
1 files changed, 141 insertions, 32 deletions
diff --git a/reftable/iter.c b/reftable/iter.c index a8d174c040..86e801ca9f 100644 --- a/reftable/iter.c +++ b/reftable/iter.c @@ -11,23 +11,61 @@ https://developers.google.com/open-source/licenses/bsd #include "system.h" #include "block.h" -#include "generic.h" #include "constants.h" #include "reader.h" #include "reftable-error.h" -int iterator_is_null(struct reftable_iterator *it) +int iterator_seek(struct reftable_iterator *it, struct reftable_record *want) { - return !it->ops; + return it->ops->seek(it->iter_arg, want); +} + +int iterator_next(struct reftable_iterator *it, struct reftable_record *rec) +{ + return it->ops->next(it->iter_arg, rec); +} + +static int empty_iterator_seek(void *arg UNUSED, struct reftable_record *want UNUSED) +{ + return 0; +} + +static int empty_iterator_next(void *arg UNUSED, struct reftable_record *rec UNUSED) +{ + return 1; +} + +static void empty_iterator_close(void *arg UNUSED) +{ +} + +static struct reftable_iterator_vtable empty_vtable = { + .seek = &empty_iterator_seek, + .next = &empty_iterator_next, + .close = &empty_iterator_close, +}; + +void iterator_set_empty(struct reftable_iterator *it) +{ + assert(!it->ops); + it->iter_arg = NULL; + it->ops = &empty_vtable; } static void filtering_ref_iterator_close(void *iter_arg) { struct filtering_ref_iterator *fri = iter_arg; - strbuf_release(&fri->oid); + reftable_buf_release(&fri->oid); reftable_iterator_destroy(&fri->it); } +static int filtering_ref_iterator_seek(void *iter_arg, + struct reftable_record *want) +{ + struct filtering_ref_iterator *fri = iter_arg; + return iterator_seek(&fri->it, want); +} + static int filtering_ref_iterator_next(void *iter_arg, struct reftable_record *rec) { @@ -40,26 +78,6 @@ static int filtering_ref_iterator_next(void *iter_arg, break; } - if (fri->double_check) { - struct reftable_iterator it = { NULL }; - - err = reftable_table_seek_ref(&fri->tab, &it, - ref->refname); - if (err == 0) { - err = reftable_iterator_next_ref(&it, ref); - } - - reftable_iterator_destroy(&it); - - if (err < 0) { - break; - } - - if (err > 0) { - continue; - } - } - if (ref->value_type == REFTABLE_REF_VAL2 && (!memcmp(fri->oid.buf, ref->value.val2.target_value, fri->oid.len) || @@ -78,6 +96,7 @@ static int filtering_ref_iterator_next(void *iter_arg, } static struct reftable_iterator_vtable filtering_ref_iterator_vtable = { + .seek = &filtering_ref_iterator_seek, .next = &filtering_ref_iterator_next, .close = &filtering_ref_iterator_close, }; @@ -96,7 +115,7 @@ static void indexed_table_ref_iter_close(void *p) block_iter_close(&it->cur); reftable_block_done(&it->block_reader.block); reftable_free(it->offsets); - strbuf_release(&it->oid); + reftable_buf_release(&it->oid); } static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it) @@ -120,10 +139,17 @@ static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it) /* indexed block does not exist. */ return REFTABLE_FORMAT_ERROR; } - block_reader_start(&it->block_reader, &it->cur); + block_iter_seek_start(&it->cur, &it->block_reader); return 0; } +static int indexed_table_ref_iter_seek(void *p UNUSED, + struct reftable_record *want UNUSED) +{ + BUG("seeking indexed table is not supported"); + return -1; +} + static int indexed_table_ref_iter_next(void *p, struct reftable_record *rec) { struct indexed_table_ref_iter *it = p; @@ -155,32 +181,47 @@ static int indexed_table_ref_iter_next(void *p, struct reftable_record *rec) } } -int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest, +int indexed_table_ref_iter_new(struct indexed_table_ref_iter **dest, struct reftable_reader *r, uint8_t *oid, int oid_len, uint64_t *offsets, int offset_len) { struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT; - struct indexed_table_ref_iter *itr = - reftable_calloc(sizeof(struct indexed_table_ref_iter)); + struct indexed_table_ref_iter *itr; int err = 0; + itr = reftable_calloc(1, sizeof(*itr)); + if (!itr) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + *itr = empty; itr->r = r; - strbuf_add(&itr->oid, oid, oid_len); + + err = reftable_buf_add(&itr->oid, oid, oid_len); + if (err < 0) + goto out; itr->offsets = offsets; itr->offset_len = offset_len; err = indexed_table_ref_iter_next_block(itr); + if (err < 0) + goto out; + + *dest = itr; + err = 0; + +out: if (err < 0) { + *dest = NULL; reftable_free(itr); - } else { - *dest = itr; } return err; } static struct reftable_iterator_vtable indexed_table_ref_iter_vtable = { + .seek = &indexed_table_ref_iter_seek, .next = &indexed_table_ref_iter_next, .close = &indexed_table_ref_iter_close, }; @@ -192,3 +233,71 @@ void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it, it->iter_arg = itr; it->ops = &indexed_table_ref_iter_vtable; } + +void reftable_iterator_destroy(struct reftable_iterator *it) +{ + if (!it->ops) + return; + it->ops->close(it->iter_arg); + it->ops = NULL; + REFTABLE_FREE_AND_NULL(it->iter_arg); +} + +int reftable_iterator_seek_ref(struct reftable_iterator *it, + const char *name) +{ + struct reftable_record want = { + .type = BLOCK_TYPE_REF, + .u.ref = { + .refname = (char *)name, + }, + }; + return it->ops->seek(it->iter_arg, &want); +} + +int reftable_iterator_next_ref(struct reftable_iterator *it, + struct reftable_ref_record *ref) +{ + struct reftable_record rec = { + .type = BLOCK_TYPE_REF, + .u = { + .ref = *ref + }, + }; + int err = iterator_next(it, &rec); + *ref = rec.u.ref; + return err; +} + +int reftable_iterator_seek_log_at(struct reftable_iterator *it, + const char *name, uint64_t update_index) +{ + struct reftable_record want = { + .type = BLOCK_TYPE_LOG, + .u.log = { + .refname = (char *)name, + .update_index = update_index, + }, + }; + return it->ops->seek(it->iter_arg, &want); +} + +int reftable_iterator_seek_log(struct reftable_iterator *it, + const char *name) +{ + return reftable_iterator_seek_log_at(it, name, ~((uint64_t) 0)); +} + +int reftable_iterator_next_log(struct reftable_iterator *it, + struct reftable_log_record *log) +{ + struct reftable_record rec = { + .type = BLOCK_TYPE_LOG, + .u = { + .log = *log, + }, + }; + int err = iterator_next(it, &rec); + *log = rec.u.log; + return err; +} |