/* Copyright 2020 Google LLC Use of this source code is governed by a BSD-style license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ #include "basics.h" #include "record.h" #include "generic.h" #include "reftable-iterator.h" #include "reftable-generic.h" int reftable_table_seek_ref(struct reftable_table *tab, struct reftable_iterator *it, const char *name) { struct reftable_ref_record ref = { .refname = (char *)name, }; struct reftable_record rec = { NULL }; reftable_record_from_ref(&rec, &ref); return tab->ops->seek_record(tab->table_arg, it, &rec); } int reftable_table_read_ref(struct reftable_table *tab, const char *name, struct reftable_ref_record *ref) { struct reftable_iterator it = { NULL }; int err = reftable_table_seek_ref(tab, &it, name); if (err) goto done; err = reftable_iterator_next_ref(&it, ref); if (err) goto done; if (strcmp(ref->refname, name) || reftable_ref_record_is_deletion(ref)) { reftable_ref_record_release(ref); err = 1; goto done; } done: reftable_iterator_destroy(&it); return err; } uint64_t reftable_table_max_update_index(struct reftable_table *tab) { return tab->ops->max_update_index(tab->table_arg); } uint64_t reftable_table_min_update_index(struct reftable_table *tab) { return tab->ops->min_update_index(tab->table_arg); } uint32_t reftable_table_hash_id(struct reftable_table *tab) { return tab->ops->hash_id(tab->table_arg); } void reftable_iterator_destroy(struct reftable_iterator *it) { if (!it->ops) { return; } it->ops->close(it->iter_arg); it->ops = NULL; FREE_AND_NULL(it->iter_arg); } int reftable_iterator_next_ref(struct reftable_iterator *it, struct reftable_ref_record *ref) { struct reftable_record rec = { NULL }; reftable_record_from_ref(&rec, ref); return iterator_next(it, &rec); } int reftable_iterator_next_log(struct reftable_iterator *it, struct reftable_log_record *log) { struct reftable_record rec = { NULL }; reftable_record_from_log(&rec, log); return iterator_next(it, &rec); } int iterator_next(struct reftable_iterator *it, struct reftable_record *rec) { return it->ops->next(it->iter_arg, rec); } static int empty_iterator_next(void *arg, struct reftable_record *rec) { return 1; } static void empty_iterator_close(void *arg) { } static struct reftable_iterator_vtable empty_vtable = { .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; }