summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2024-08-29 20:08:15 +0200
committerJunio C Hamano <gitster@pobox.com>2024-08-29 20:08:16 +0200
commitd4d677704d74db389d2f56975794cd85acb8181f (patch)
treec5106f13995266db81b81552933d00e0206194ee
parentThe tenth batch (diff)
parentreftable: mark unused parameters in empty iterator functions (diff)
downloadgit-d4d677704d74db389d2f56975794cd85acb8181f.tar.xz
git-d4d677704d74db389d2f56975794cd85acb8181f.zip
Merge branch 'ps/reftable-drop-generic'
The code in the reftable library has been cleaned up by discarding unused "generic" interface. * ps/reftable-drop-generic: reftable: mark unused parameters in empty iterator functions reftable/generic: drop interface t/helper: refactor to not use `struct reftable_table` t/helper: use `hash_to_hex_algop()` to print hashes t/helper: inline printing of reftable records t/helper: inline `reftable_table_print()` t/helper: inline `reftable_stack_print_directory()` t/helper: inline `reftable_reader_print_file()` t/helper: inline `reftable_dump_main()` reftable/dump: drop unused `compact_stack()` reftable/generic: move generic iterator code into iterator interface reftable/iter: drop double-checking logic reftable/stack: open-code reading refs reftable/merged: stop using generic tables in the merged table reftable/merged: rename `reftable_new_merged_table()` reftable/merged: expose functions to initialize iterators
-rw-r--r--Makefile2
-rw-r--r--reftable/dump.c111
-rw-r--r--reftable/generic.c231
-rw-r--r--reftable/generic.h37
-rw-r--r--reftable/iter.c126
-rw-r--r--reftable/iter.h30
-rw-r--r--reftable/merged.c72
-rw-r--r--reftable/merged.h4
-rw-r--r--reftable/reader.c70
-rw-r--r--reftable/reader.h4
-rw-r--r--reftable/record.c127
-rw-r--r--reftable/record.h1
-rw-r--r--reftable/reftable-generic.h47
-rw-r--r--reftable/reftable-merged.h26
-rw-r--r--reftable/reftable-reader.h9
-rw-r--r--reftable/reftable-record.h8
-rw-r--r--reftable/reftable-stack.h3
-rw-r--r--reftable/reftable-tests.h1
-rw-r--r--reftable/stack.c94
-rw-r--r--reftable/stack_test.c29
-rw-r--r--t/helper/test-reftable.c189
-rw-r--r--t/unit-tests/t-reftable-merged.c17
22 files changed, 422 insertions, 816 deletions
diff --git a/Makefile b/Makefile
index deb175a040..b72725d2b0 100644
--- a/Makefile
+++ b/Makefile
@@ -2678,13 +2678,11 @@ REFTABLE_OBJS += reftable/merged.o
REFTABLE_OBJS += reftable/pq.o
REFTABLE_OBJS += reftable/reader.o
REFTABLE_OBJS += reftable/record.o
-REFTABLE_OBJS += reftable/generic.o
REFTABLE_OBJS += reftable/stack.o
REFTABLE_OBJS += reftable/tree.o
REFTABLE_OBJS += reftable/writer.o
REFTABLE_TEST_OBJS += reftable/block_test.o
-REFTABLE_TEST_OBJS += reftable/dump.o
REFTABLE_TEST_OBJS += reftable/stack_test.o
REFTABLE_TEST_OBJS += reftable/test_framework.o
diff --git a/reftable/dump.c b/reftable/dump.c
deleted file mode 100644
index dd65d9e8bb..0000000000
--- a/reftable/dump.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-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 "git-compat-util.h"
-#include "hash.h"
-
-#include "reftable-blocksource.h"
-#include "reftable-error.h"
-#include "reftable-record.h"
-#include "reftable-tests.h"
-#include "reftable-writer.h"
-#include "reftable-iterator.h"
-#include "reftable-reader.h"
-#include "reftable-stack.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-static int compact_stack(const char *stackdir)
-{
- struct reftable_stack *stack = NULL;
- struct reftable_write_options opts = { 0 };
-
- int err = reftable_new_stack(&stack, stackdir, &opts);
- if (err < 0)
- goto done;
-
- err = reftable_stack_compact_all(stack, NULL);
- if (err < 0)
- goto done;
-done:
- if (stack) {
- reftable_stack_destroy(stack);
- }
- return err;
-}
-
-static void print_help(void)
-{
- printf("usage: dump [-cst] arg\n\n"
- "options: \n"
- " -c compact\n"
- " -b dump blocks\n"
- " -t dump table\n"
- " -s dump stack\n"
- " -6 sha256 hash format\n"
- " -h this help\n"
- "\n");
-}
-
-int reftable_dump_main(int argc, char *const *argv)
-{
- int err = 0;
- int opt_dump_blocks = 0;
- int opt_dump_table = 0;
- int opt_dump_stack = 0;
- int opt_compact = 0;
- uint32_t opt_hash_id = GIT_SHA1_FORMAT_ID;
- const char *arg = NULL, *argv0 = argv[0];
-
- for (; argc > 1; argv++, argc--)
- if (*argv[1] != '-')
- break;
- else if (!strcmp("-b", argv[1]))
- opt_dump_blocks = 1;
- else if (!strcmp("-t", argv[1]))
- opt_dump_table = 1;
- else if (!strcmp("-6", argv[1]))
- opt_hash_id = GIT_SHA256_FORMAT_ID;
- else if (!strcmp("-s", argv[1]))
- opt_dump_stack = 1;
- else if (!strcmp("-c", argv[1]))
- opt_compact = 1;
- else if (!strcmp("-?", argv[1]) || !strcmp("-h", argv[1])) {
- print_help();
- return 2;
- }
-
- if (argc != 2) {
- fprintf(stderr, "need argument\n");
- print_help();
- return 2;
- }
-
- arg = argv[1];
-
- if (opt_dump_blocks) {
- err = reftable_reader_print_blocks(arg);
- } else if (opt_dump_table) {
- err = reftable_reader_print_file(arg);
- } else if (opt_dump_stack) {
- err = reftable_stack_print_directory(arg, opt_hash_id);
- } else if (opt_compact) {
- err = compact_stack(arg);
- }
-
- if (err < 0) {
- fprintf(stderr, "%s: %s: %s\n", argv0, arg,
- reftable_error_str(err));
- return 1;
- }
- return 0;
-}
diff --git a/reftable/generic.c b/reftable/generic.c
deleted file mode 100644
index a00725d9c4..0000000000
--- a/reftable/generic.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-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 "constants.h"
-#include "record.h"
-#include "generic.h"
-#include "reftable-iterator.h"
-#include "reftable-generic.h"
-
-void table_init_iter(struct reftable_table *tab,
- struct reftable_iterator *it,
- uint8_t typ)
-{
-
- tab->ops->init_iter(tab->table_arg, it, typ);
-}
-
-void reftable_table_init_ref_iter(struct reftable_table *tab,
- struct reftable_iterator *it)
-{
- table_init_iter(tab, it, BLOCK_TYPE_REF);
-}
-
-void reftable_table_init_log_iter(struct reftable_table *tab,
- struct reftable_iterator *it)
-{
- table_init_iter(tab, it, BLOCK_TYPE_LOG);
-}
-
-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_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_table_read_ref(struct reftable_table *tab, const char *name,
- struct reftable_ref_record *ref)
-{
- struct reftable_iterator it = { NULL };
- int err;
-
- reftable_table_init_ref_iter(tab, &it);
-
- err = reftable_iterator_seek_ref(&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;
-}
-
-int reftable_table_print(struct reftable_table *tab) {
- struct reftable_iterator it = { NULL };
- struct reftable_ref_record ref = { NULL };
- struct reftable_log_record log = { NULL };
- uint32_t hash_id = reftable_table_hash_id(tab);
- int err;
-
- reftable_table_init_ref_iter(tab, &it);
-
- err = reftable_iterator_seek_ref(&it, "");
- if (err < 0)
- return err;
-
- while (1) {
- err = reftable_iterator_next_ref(&it, &ref);
- if (err > 0) {
- break;
- }
- if (err < 0) {
- return err;
- }
- reftable_ref_record_print(&ref, hash_id);
- }
- reftable_iterator_destroy(&it);
- reftable_ref_record_release(&ref);
-
- reftable_table_init_log_iter(tab, &it);
-
- err = reftable_iterator_seek_log(&it, "");
- if (err < 0)
- return err;
-
- while (1) {
- err = reftable_iterator_next_log(&it, &log);
- if (err > 0) {
- break;
- }
- if (err < 0) {
- return err;
- }
- reftable_log_record_print(&log, hash_id);
- }
- reftable_iterator_destroy(&it);
- reftable_log_record_release(&log);
- return 0;
-}
-
-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 = {
- .type = BLOCK_TYPE_REF,
- .u = {
- .ref = *ref
- },
- };
- int err = iterator_next(it, &rec);
- *ref = rec.u.ref;
- return err;
-}
-
-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;
-}
-
-int iterator_seek(struct reftable_iterator *it, struct reftable_record *want)
-{
- 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;
-}
diff --git a/reftable/generic.h b/reftable/generic.h
deleted file mode 100644
index 8341fa570e..0000000000
--- a/reftable/generic.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-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
-*/
-
-#ifndef GENERIC_H
-#define GENERIC_H
-
-#include "record.h"
-#include "reftable-generic.h"
-
-/* generic interface to reftables */
-struct reftable_table_vtable {
- void (*init_iter)(void *tab, struct reftable_iterator *it, uint8_t typ);
- uint32_t (*hash_id)(void *tab);
- uint64_t (*min_update_index)(void *tab);
- uint64_t (*max_update_index)(void *tab);
-};
-
-void table_init_iter(struct reftable_table *tab,
- struct reftable_iterator *it,
- uint8_t typ);
-
-struct reftable_iterator_vtable {
- int (*seek)(void *iter_arg, struct reftable_record *want);
- int (*next)(void *iter_arg, struct reftable_record *rec);
- void (*close)(void *iter_arg);
-};
-
-void iterator_set_empty(struct reftable_iterator *it);
-int iterator_seek(struct reftable_iterator *it, struct reftable_record *want);
-int iterator_next(struct reftable_iterator *it, struct reftable_record *rec);
-
-#endif
diff --git a/reftable/iter.c b/reftable/iter.c
index 9e8b2952fd..416a9f6996 100644
--- a/reftable/iter.c
+++ b/reftable/iter.c
@@ -11,11 +11,47 @@ 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_seek(struct reftable_iterator *it, struct reftable_record *want)
+{
+ 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;
@@ -42,26 +78,6 @@ static int filtering_ref_iterator_next(void *iter_arg,
break;
}
- if (fri->double_check) {
- struct reftable_iterator it = { NULL };
-
- reftable_table_init_ref_iter(&fri->tab, &it);
-
- err = reftable_iterator_seek_ref(&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) ||
@@ -202,3 +218,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;
+ 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;
+}
diff --git a/reftable/iter.h b/reftable/iter.h
index 537431baba..befc4597df 100644
--- a/reftable/iter.h
+++ b/reftable/iter.h
@@ -14,12 +14,36 @@ https://developers.google.com/open-source/licenses/bsd
#include "record.h"
#include "reftable-iterator.h"
-#include "reftable-generic.h"
+
+/*
+ * The virtual function table for implementing generic reftable iterators.
+ */
+struct reftable_iterator_vtable {
+ int (*seek)(void *iter_arg, struct reftable_record *want);
+ int (*next)(void *iter_arg, struct reftable_record *rec);
+ void (*close)(void *iter_arg);
+};
+
+/*
+ * Position the iterator at the wanted record such that a call to
+ * `iterator_next()` would return that record, if it exists.
+ */
+int iterator_seek(struct reftable_iterator *it, struct reftable_record *want);
+
+/*
+ * Yield the next record and advance the iterator. Returns <0 on error, 0 when
+ * a record was yielded, and >0 when the iterator hit an error.
+ */
+int iterator_next(struct reftable_iterator *it, struct reftable_record *rec);
+
+/*
+ * Set up the iterator such that it behaves the same as an iterator with no
+ * entries.
+ */
+void iterator_set_empty(struct reftable_iterator *it);
/* iterator that produces only ref records that point to `oid` */
struct filtering_ref_iterator {
- int double_check;
- struct reftable_table tab;
struct strbuf oid;
struct reftable_iterator it;
};
diff --git a/reftable/merged.c b/reftable/merged.c
index 6adce44f4b..128a810c55 100644
--- a/reftable/merged.c
+++ b/reftable/merged.c
@@ -11,8 +11,8 @@ https://developers.google.com/open-source/licenses/bsd
#include "constants.h"
#include "iter.h"
#include "pq.h"
+#include "reader.h"
#include "record.h"
-#include "generic.h"
#include "reftable-merged.h"
#include "reftable-error.h"
#include "system.h"
@@ -25,7 +25,7 @@ struct merged_subiter {
struct merged_iter {
struct merged_subiter *subiters;
struct merged_iter_pqueue pq;
- size_t stack_len;
+ size_t subiters_len;
int suppress_deletions;
ssize_t advance_index;
};
@@ -38,12 +38,12 @@ static void merged_iter_init(struct merged_iter *mi,
mi->advance_index = -1;
mi->suppress_deletions = mt->suppress_deletions;
- REFTABLE_CALLOC_ARRAY(mi->subiters, mt->stack_len);
- for (size_t i = 0; i < mt->stack_len; i++) {
+ REFTABLE_CALLOC_ARRAY(mi->subiters, mt->readers_len);
+ for (size_t i = 0; i < mt->readers_len; i++) {
reftable_record_init(&mi->subiters[i].rec, typ);
- table_init_iter(&mt->stack[i], &mi->subiters[i].iter, typ);
+ reader_init_iter(mt->readers[i], &mi->subiters[i].iter, typ);
}
- mi->stack_len = mt->stack_len;
+ mi->subiters_len = mt->readers_len;
}
static void merged_iter_close(void *p)
@@ -51,7 +51,7 @@ static void merged_iter_close(void *p)
struct merged_iter *mi = p;
merged_iter_pqueue_release(&mi->pq);
- for (size_t i = 0; i < mi->stack_len; i++) {
+ for (size_t i = 0; i < mi->subiters_len; i++) {
reftable_iterator_destroy(&mi->subiters[i].iter);
reftable_record_release(&mi->subiters[i].rec);
}
@@ -80,7 +80,7 @@ static int merged_iter_seek(struct merged_iter *mi, struct reftable_record *want
mi->advance_index = -1;
- for (size_t i = 0; i < mi->stack_len; i++) {
+ for (size_t i = 0; i < mi->subiters_len; i++) {
err = iterator_seek(&mi->subiters[i].iter, want);
if (err < 0)
return err;
@@ -192,8 +192,8 @@ static void iterator_from_merged_iter(struct reftable_iterator *it,
it->ops = &merged_iter_vtable;
}
-int reftable_new_merged_table(struct reftable_merged_table **dest,
- struct reftable_table *stack, size_t n,
+int reftable_merged_table_new(struct reftable_merged_table **dest,
+ struct reftable_reader **readers, size_t n,
uint32_t hash_id)
{
struct reftable_merged_table *m = NULL;
@@ -201,10 +201,10 @@ int reftable_new_merged_table(struct reftable_merged_table **dest,
uint64_t first_min = 0;
for (size_t i = 0; i < n; i++) {
- uint64_t min = reftable_table_min_update_index(&stack[i]);
- uint64_t max = reftable_table_max_update_index(&stack[i]);
+ uint64_t min = reftable_reader_min_update_index(readers[i]);
+ uint64_t max = reftable_reader_max_update_index(readers[i]);
- if (reftable_table_hash_id(&stack[i]) != hash_id) {
+ if (reftable_reader_hash_id(readers[i]) != hash_id) {
return REFTABLE_FORMAT_ERROR;
}
if (i == 0 || min < first_min) {
@@ -216,8 +216,8 @@ int reftable_new_merged_table(struct reftable_merged_table **dest,
}
REFTABLE_CALLOC_ARRAY(m, 1);
- m->stack = stack;
- m->stack_len = n;
+ m->readers = readers;
+ m->readers_len = n;
m->min = first_min;
m->max = last_max;
m->hash_id = hash_id;
@@ -229,7 +229,6 @@ void reftable_merged_table_free(struct reftable_merged_table *mt)
{
if (!mt)
return;
- FREE_AND_NULL(mt->stack);
reftable_free(mt);
}
@@ -254,44 +253,19 @@ void merged_table_init_iter(struct reftable_merged_table *mt,
iterator_from_merged_iter(it, mi);
}
-uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt)
-{
- return mt->hash_id;
-}
-
-static void reftable_merged_table_init_iter_void(void *tab,
- struct reftable_iterator *it,
- uint8_t typ)
-{
- merged_table_init_iter(tab, it, typ);
-}
-
-static uint32_t reftable_merged_table_hash_id_void(void *tab)
+void reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt,
+ struct reftable_iterator *it)
{
- return reftable_merged_table_hash_id(tab);
+ merged_table_init_iter(mt, it, BLOCK_TYPE_REF);
}
-static uint64_t reftable_merged_table_min_update_index_void(void *tab)
+void reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt,
+ struct reftable_iterator *it)
{
- return reftable_merged_table_min_update_index(tab);
+ merged_table_init_iter(mt, it, BLOCK_TYPE_LOG);
}
-static uint64_t reftable_merged_table_max_update_index_void(void *tab)
-{
- return reftable_merged_table_max_update_index(tab);
-}
-
-static struct reftable_table_vtable merged_table_vtable = {
- .init_iter = reftable_merged_table_init_iter_void,
- .hash_id = reftable_merged_table_hash_id_void,
- .min_update_index = reftable_merged_table_min_update_index_void,
- .max_update_index = reftable_merged_table_max_update_index_void,
-};
-
-void reftable_table_from_merged_table(struct reftable_table *tab,
- struct reftable_merged_table *merged)
+uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt)
{
- assert(!tab->ops);
- tab->ops = &merged_table_vtable;
- tab->table_arg = merged;
+ return mt->hash_id;
}
diff --git a/reftable/merged.h b/reftable/merged.h
index 2efe571da6..de5fd33f01 100644
--- a/reftable/merged.h
+++ b/reftable/merged.h
@@ -12,8 +12,8 @@ https://developers.google.com/open-source/licenses/bsd
#include "system.h"
struct reftable_merged_table {
- struct reftable_table *stack;
- size_t stack_len;
+ struct reftable_reader **readers;
+ size_t readers_len;
uint32_t hash_id;
/* If unset, produce deletions. This is useful for compaction. For the
diff --git a/reftable/reader.c b/reftable/reader.c
index 29c99e2269..082cf00b60 100644
--- a/reftable/reader.c
+++ b/reftable/reader.c
@@ -11,11 +11,9 @@ https://developers.google.com/open-source/licenses/bsd
#include "system.h"
#include "block.h"
#include "constants.h"
-#include "generic.h"
#include "iter.h"
#include "record.h"
#include "reftable-error.h"
-#include "reftable-generic.h"
uint64_t block_source_size(struct reftable_block_source *source)
{
@@ -605,9 +603,9 @@ static void iterator_from_table_iter(struct reftable_iterator *it,
it->ops = &table_iter_vtable;
}
-static void reader_init_iter(struct reftable_reader *r,
- struct reftable_iterator *it,
- uint8_t typ)
+void reader_init_iter(struct reftable_reader *r,
+ struct reftable_iterator *it,
+ uint8_t typ)
{
struct reftable_reader_offsets *offs = reader_offsets_for(r, typ);
@@ -735,8 +733,6 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r,
*filter = empty;
strbuf_add(&filter->oid, oid, oid_len);
- reftable_table_from_reader(&filter->tab, r);
- filter->double_check = 0;
iterator_from_table_iter(&filter->it, ti);
iterator_from_filtering_ref_iterator(it, filter);
@@ -761,66 +757,6 @@ uint64_t reftable_reader_min_update_index(struct reftable_reader *r)
return r->min_update_index;
}
-/* generic table interface. */
-
-static void reftable_reader_init_iter_void(void *tab,
- struct reftable_iterator *it,
- uint8_t typ)
-{
- reader_init_iter(tab, it, typ);
-}
-
-static uint32_t reftable_reader_hash_id_void(void *tab)
-{
- return reftable_reader_hash_id(tab);
-}
-
-static uint64_t reftable_reader_min_update_index_void(void *tab)
-{
- return reftable_reader_min_update_index(tab);
-}
-
-static uint64_t reftable_reader_max_update_index_void(void *tab)
-{
- return reftable_reader_max_update_index(tab);
-}
-
-static struct reftable_table_vtable reader_vtable = {
- .init_iter = reftable_reader_init_iter_void,
- .hash_id = reftable_reader_hash_id_void,
- .min_update_index = reftable_reader_min_update_index_void,
- .max_update_index = reftable_reader_max_update_index_void,
-};
-
-void reftable_table_from_reader(struct reftable_table *tab,
- struct reftable_reader *reader)
-{
- assert(!tab->ops);
- tab->ops = &reader_vtable;
- tab->table_arg = reader;
-}
-
-
-int reftable_reader_print_file(const char *tablename)
-{
- struct reftable_block_source src = { NULL };
- int err = reftable_block_source_from_file(&src, tablename);
- struct reftable_reader *r = NULL;
- struct reftable_table tab = { NULL };
- if (err < 0)
- goto done;
-
- err = reftable_new_reader(&r, &src, tablename);
- if (err < 0)
- goto done;
-
- reftable_table_from_reader(&tab, r);
- err = reftable_table_print(&tab);
-done:
- reftable_reader_free(r);
- return err;
-}
-
int reftable_reader_print_blocks(const char *tablename)
{
struct {
diff --git a/reftable/reader.h b/reftable/reader.h
index e869165f23..a2c204d523 100644
--- a/reftable/reader.h
+++ b/reftable/reader.h
@@ -57,6 +57,10 @@ int init_reader(struct reftable_reader *r, struct reftable_block_source *source,
void reader_close(struct reftable_reader *r);
const char *reader_name(struct reftable_reader *r);
+void reader_init_iter(struct reftable_reader *r,
+ struct reftable_iterator *it,
+ uint8_t typ);
+
/* initialize a block reader to read from `r` */
int reader_init_block_reader(struct reftable_reader *r, struct block_reader *br,
uint64_t next_off, uint8_t want_typ);
diff --git a/reftable/record.c b/reftable/record.c
index 2ec0c6d346..6b5a075b92 100644
--- a/reftable/record.c
+++ b/reftable/record.c
@@ -259,58 +259,6 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec,
}
}
-static char hexdigit(int c)
-{
- if (c <= 9)
- return '0' + c;
- return 'a' + (c - 10);
-}
-
-static void hex_format(char *dest, const unsigned char *src, int hash_size)
-{
- assert(hash_size > 0);
- if (src) {
- int i = 0;
- for (i = 0; i < hash_size; i++) {
- dest[2 * i] = hexdigit(src[i] >> 4);
- dest[2 * i + 1] = hexdigit(src[i] & 0xf);
- }
- dest[2 * hash_size] = 0;
- }
-}
-
-static void reftable_ref_record_print_sz(const struct reftable_ref_record *ref,
- int hash_size)
-{
- char hex[GIT_MAX_HEXSZ + 1] = { 0 }; /* BUG */
- printf("ref{%s(%" PRIu64 ") ", ref->refname, ref->update_index);
- switch (ref->value_type) {
- case REFTABLE_REF_SYMREF:
- printf("=> %s", ref->value.symref);
- break;
- case REFTABLE_REF_VAL2:
- hex_format(hex, ref->value.val2.value, hash_size);
- printf("val 2 %s", hex);
- hex_format(hex, ref->value.val2.target_value,
- hash_size);
- printf("(T %s)", hex);
- break;
- case REFTABLE_REF_VAL1:
- hex_format(hex, ref->value.val1, hash_size);
- printf("val 1 %s", hex);
- break;
- case REFTABLE_REF_DELETION:
- printf("delete");
- break;
- }
- printf("}\n");
-}
-
-void reftable_ref_record_print(const struct reftable_ref_record *ref,
- uint32_t hash_id) {
- reftable_ref_record_print_sz(ref, hash_size(hash_id));
-}
-
static void reftable_ref_record_release_void(void *rec)
{
reftable_ref_record_release(rec);
@@ -480,12 +428,6 @@ static int reftable_ref_record_cmp_void(const void *_a, const void *_b)
return strcmp(a->refname, b->refname);
}
-static void reftable_ref_record_print_void(const void *rec,
- int hash_size)
-{
- reftable_ref_record_print_sz((struct reftable_ref_record *) rec, hash_size);
-}
-
static struct reftable_record_vtable reftable_ref_record_vtable = {
.key = &reftable_ref_record_key,
.type = BLOCK_TYPE_REF,
@@ -497,7 +439,6 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
.is_deletion = &reftable_ref_record_is_deletion_void,
.equal = &reftable_ref_record_equal_void,
.cmp = &reftable_ref_record_cmp_void,
- .print = &reftable_ref_record_print_void,
};
static void reftable_obj_record_key(const void *r, struct strbuf *dest)
@@ -516,21 +457,6 @@ static void reftable_obj_record_release(void *rec)
memset(obj, 0, sizeof(struct reftable_obj_record));
}
-static void reftable_obj_record_print(const void *rec, int hash_size UNUSED)
-{
- const struct reftable_obj_record *obj = rec;
- char hex[GIT_MAX_HEXSZ + 1] = { 0 };
- struct strbuf offset_str = STRBUF_INIT;
- int i;
-
- for (i = 0; i < obj->offset_len; i++)
- strbuf_addf(&offset_str, "%" PRIu64 " ", obj->offsets[i]);
- hex_format(hex, obj->hash_prefix, obj->hash_prefix_len);
- printf("prefix %s (len %d), offsets [%s]\n",
- hex, obj->hash_prefix_len, offset_str.buf);
- strbuf_release(&offset_str);
-}
-
static void reftable_obj_record_copy_from(void *rec, const void *src_rec,
int hash_size UNUSED)
{
@@ -703,41 +629,8 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
.is_deletion = &not_a_deletion,
.equal = &reftable_obj_record_equal_void,
.cmp = &reftable_obj_record_cmp_void,
- .print = &reftable_obj_record_print,
};
-static void reftable_log_record_print_sz(struct reftable_log_record *log,
- int hash_size)
-{
- char hex[GIT_MAX_HEXSZ + 1] = { 0 };
-
- switch (log->value_type) {
- case REFTABLE_LOG_DELETION:
- printf("log{%s(%" PRIu64 ") delete\n", log->refname,
- log->update_index);
- break;
- case REFTABLE_LOG_UPDATE:
- printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n",
- log->refname, log->update_index,
- log->value.update.name ? log->value.update.name : "",
- log->value.update.email ? log->value.update.email : "",
- log->value.update.time,
- log->value.update.tz_offset);
- hex_format(hex, log->value.update.old_hash, hash_size);
- printf("%s => ", hex);
- hex_format(hex, log->value.update.new_hash, hash_size);
- printf("%s\n\n%s\n}\n", hex,
- log->value.update.message ? log->value.update.message : "");
- break;
- }
-}
-
-void reftable_log_record_print(struct reftable_log_record *log,
- uint32_t hash_id)
-{
- reftable_log_record_print_sz(log, hash_size(hash_id));
-}
-
static void reftable_log_record_key(const void *r, struct strbuf *dest)
{
const struct reftable_log_record *rec =
@@ -1041,11 +934,6 @@ static int reftable_log_record_is_deletion_void(const void *p)
(const struct reftable_log_record *)p);
}
-static void reftable_log_record_print_void(const void *rec, int hash_size)
-{
- reftable_log_record_print_sz((struct reftable_log_record*)rec, hash_size);
-}
-
static struct reftable_record_vtable reftable_log_record_vtable = {
.key = &reftable_log_record_key,
.type = BLOCK_TYPE_LOG,
@@ -1057,7 +945,6 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
.is_deletion = &reftable_log_record_is_deletion_void,
.equal = &reftable_log_record_equal_void,
.cmp = &reftable_log_record_cmp_void,
- .print = &reftable_log_record_print_void,
};
static void reftable_index_record_key(const void *r, struct strbuf *dest)
@@ -1142,13 +1029,6 @@ static int reftable_index_record_cmp(const void *_a, const void *_b)
return strbuf_cmp(&a->last_key, &b->last_key);
}
-static void reftable_index_record_print(const void *rec, int hash_size UNUSED)
-{
- const struct reftable_index_record *idx = rec;
- /* TODO: escape null chars? */
- printf("\"%s\" %" PRIu64 "\n", idx->last_key.buf, idx->offset);
-}
-
static struct reftable_record_vtable reftable_index_record_vtable = {
.key = &reftable_index_record_key,
.type = BLOCK_TYPE_INDEX,
@@ -1160,7 +1040,6 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
.is_deletion = &not_a_deletion,
.equal = &reftable_index_record_equal,
.cmp = &reftable_index_record_cmp,
- .print = &reftable_index_record_print,
};
void reftable_record_key(struct reftable_record *rec, struct strbuf *dest)
@@ -1339,9 +1218,3 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ)
BUG("unhandled record type");
}
}
-
-void reftable_record_print(struct reftable_record *rec, int hash_size)
-{
- printf("'%c': ", rec->type);
- reftable_record_vtable(rec)->print(reftable_record_data(rec), hash_size);
-}
diff --git a/reftable/record.h b/reftable/record.h
index d778133e6e..5003bacdb0 100644
--- a/reftable/record.h
+++ b/reftable/record.h
@@ -136,7 +136,6 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ);
/* see struct record_vtable */
int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b);
int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
-void reftable_record_print(struct reftable_record *rec, int hash_size);
void reftable_record_key(struct reftable_record *rec, struct strbuf *dest);
void reftable_record_copy_from(struct reftable_record *rec,
struct reftable_record *src, int hash_size);
diff --git a/reftable/reftable-generic.h b/reftable/reftable-generic.h
deleted file mode 100644
index 65670ea093..0000000000
--- a/reftable/reftable-generic.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-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
-*/
-
-#ifndef REFTABLE_GENERIC_H
-#define REFTABLE_GENERIC_H
-
-#include "reftable-iterator.h"
-
-struct reftable_table_vtable;
-
-/*
- * Provides a unified API for reading tables, either merged tables, or single
- * readers. */
-struct reftable_table {
- struct reftable_table_vtable *ops;
- void *table_arg;
-};
-
-void reftable_table_init_ref_iter(struct reftable_table *tab,
- struct reftable_iterator *it);
-
-void reftable_table_init_log_iter(struct reftable_table *tab,
- struct reftable_iterator *it);
-
-/* returns the hash ID from a generic reftable_table */
-uint32_t reftable_table_hash_id(struct reftable_table *tab);
-
-/* returns the max update_index covered by this table. */
-uint64_t reftable_table_max_update_index(struct reftable_table *tab);
-
-/* returns the min update_index covered by this table. */
-uint64_t reftable_table_min_update_index(struct reftable_table *tab);
-
-/* convenience function to read a single ref. Returns < 0 for error, 0
- for success, and 1 if ref not found. */
-int reftable_table_read_ref(struct reftable_table *tab, const char *name,
- struct reftable_ref_record *ref);
-
-/* dump table contents onto stdout for debugging */
-int reftable_table_print(struct reftable_table *tab);
-
-#endif
diff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h
index 14d5fc9f05..16d19f8df2 100644
--- a/reftable/reftable-merged.h
+++ b/reftable/reftable-merged.h
@@ -26,16 +26,24 @@ https://developers.google.com/open-source/licenses/bsd
/* A merged table is implements seeking/iterating over a stack of tables. */
struct reftable_merged_table;
-/* A generic reftable; see below. */
-struct reftable_table;
+struct reftable_reader;
-/* reftable_new_merged_table creates a new merged table. It takes ownership of
- the stack array.
-*/
-int reftable_new_merged_table(struct reftable_merged_table **dest,
- struct reftable_table *stack, size_t n,
+/*
+ * reftable_merged_table_new creates a new merged table. The readers must be
+ * kept alive as long as the merged table is still in use.
+ */
+int reftable_merged_table_new(struct reftable_merged_table **dest,
+ struct reftable_reader **readers, size_t n,
uint32_t hash_id);
+/* Initialize a merged table iterator for reading refs. */
+void reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt,
+ struct reftable_iterator *it);
+
+/* Initialize a merged table iterator for reading logs. */
+void reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt,
+ struct reftable_iterator *it);
+
/* returns the max update_index covered by this merged table. */
uint64_t
reftable_merged_table_max_update_index(struct reftable_merged_table *mt);
@@ -50,8 +58,4 @@ void reftable_merged_table_free(struct reftable_merged_table *m);
/* return the hash ID of the merged table. */
uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *m);
-/* create a generic table from reftable_merged_table */
-void reftable_table_from_merged_table(struct reftable_table *tab,
- struct reftable_merged_table *table);
-
#endif
diff --git a/reftable/reftable-reader.h b/reftable/reftable-reader.h
index a32f31d648..69621c5b0f 100644
--- a/reftable/reftable-reader.h
+++ b/reftable/reftable-reader.h
@@ -23,9 +23,6 @@
/* The reader struct is a handle to an open reftable file. */
struct reftable_reader;
-/* Generic table. */
-struct reftable_table;
-
/* reftable_new_reader opens a reftable for reading. If successful,
* returns 0 code and sets pp. The name is used for creating a
* stack. Typically, it is the basename of the file. The block source
@@ -60,12 +57,6 @@ uint64_t reftable_reader_max_update_index(struct reftable_reader *r);
/* return the min_update_index for a table */
uint64_t reftable_reader_min_update_index(struct reftable_reader *r);
-/* creates a generic table from a file reader. */
-void reftable_table_from_reader(struct reftable_table *tab,
- struct reftable_reader *reader);
-
-/* print table onto stdout for debugging. */
-int reftable_reader_print_file(const char *tablename);
/* print blocks onto stdout for debugging. */
int reftable_reader_print_blocks(const char *tablename);
diff --git a/reftable/reftable-record.h b/reftable/reftable-record.h
index ff486eb1f7..2d42463c58 100644
--- a/reftable/reftable-record.h
+++ b/reftable/reftable-record.h
@@ -60,10 +60,6 @@ const unsigned char *reftable_ref_record_val2(const struct reftable_ref_record *
/* returns whether 'ref' represents a deletion */
int reftable_ref_record_is_deletion(const struct reftable_ref_record *ref);
-/* prints a reftable_ref_record onto stdout. Useful for debugging. */
-void reftable_ref_record_print(const struct reftable_ref_record *ref,
- uint32_t hash_id);
-
/* frees and nulls all pointer values inside `ref`. */
void reftable_ref_record_release(struct reftable_ref_record *ref);
@@ -111,8 +107,4 @@ void reftable_log_record_release(struct reftable_log_record *log);
int reftable_log_record_equal(const struct reftable_log_record *a,
const struct reftable_log_record *b, int hash_size);
-/* dumps a reftable_log_record on stdout, for debugging/testing. */
-void reftable_log_record_print(struct reftable_log_record *log,
- uint32_t hash_id);
-
#endif
diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h
index 09e97c9991..f4f8cabc7f 100644
--- a/reftable/reftable-stack.h
+++ b/reftable/reftable-stack.h
@@ -140,7 +140,4 @@ struct reftable_compaction_stats {
struct reftable_compaction_stats *
reftable_stack_compaction_stats(struct reftable_stack *st);
-/* print the entire stack represented by the directory */
-int reftable_stack_print_directory(const char *stackdir, uint32_t hash_id);
-
#endif
diff --git a/reftable/reftable-tests.h b/reftable/reftable-tests.h
index afe0103ad4..8d44ddc151 100644
--- a/reftable/reftable-tests.h
+++ b/reftable/reftable-tests.h
@@ -11,6 +11,5 @@ https://developers.google.com/open-source/licenses/bsd
int block_test_main(int argc, const char **argv);
int stack_test_main(int argc, const char **argv);
-int reftable_dump_main(int argc, char *const *argv);
#endif
diff --git a/reftable/stack.c b/reftable/stack.c
index 2071e428a8..d3a95d2f1d 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -14,7 +14,6 @@ https://developers.google.com/open-source/licenses/bsd
#include "merged.h"
#include "reader.h"
#include "reftable-error.h"
-#include "reftable-generic.h"
#include "reftable-record.h"
#include "reftable-merged.h"
#include "writer.h"
@@ -225,13 +224,11 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
const char **names,
int reuse_open)
{
- size_t cur_len = !st->merged ? 0 : st->merged->stack_len;
+ size_t cur_len = !st->merged ? 0 : st->merged->readers_len;
struct reftable_reader **cur = stack_copy_readers(st, cur_len);
size_t names_len = names_length(names);
struct reftable_reader **new_readers =
reftable_calloc(names_len, sizeof(*new_readers));
- struct reftable_table *new_tables =
- reftable_calloc(names_len, sizeof(*new_tables));
size_t new_readers_len = 0;
struct reftable_merged_table *new_merged = NULL;
struct strbuf table_path = STRBUF_INIT;
@@ -267,17 +264,15 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
}
new_readers[new_readers_len] = rd;
- reftable_table_from_reader(&new_tables[new_readers_len], rd);
new_readers_len++;
}
/* success! */
- err = reftable_new_merged_table(&new_merged, new_tables,
+ err = reftable_merged_table_new(&new_merged, new_readers,
new_readers_len, st->opts.hash_id);
if (err < 0)
goto done;
- new_tables = NULL;
st->readers_len = new_readers_len;
if (st->merged)
reftable_merged_table_free(st->merged);
@@ -309,7 +304,6 @@ done:
reftable_reader_free(new_readers[i]);
}
reftable_free(new_readers);
- reftable_free(new_tables);
reftable_free(cur);
strbuf_release(&table_path);
return err;
@@ -520,7 +514,7 @@ static int stack_uptodate(struct reftable_stack *st)
}
}
- if (names[st->merged->stack_len]) {
+ if (names[st->merged->readers_len]) {
err = 1;
goto done;
}
@@ -659,7 +653,7 @@ int reftable_addition_commit(struct reftable_addition *add)
if (add->new_tables_len == 0)
goto done;
- for (i = 0; i < add->stack->merged->stack_len; i++) {
+ for (i = 0; i < add->stack->merged->readers_len; i++) {
strbuf_addstr(&table_list, add->stack->readers[i]->name);
strbuf_addstr(&table_list, "\n");
}
@@ -839,7 +833,7 @@ done:
uint64_t reftable_stack_next_update_index(struct reftable_stack *st)
{
- int sz = st->merged->stack_len;
+ int sz = st->merged->readers_len;
if (sz > 0)
return reftable_reader_max_update_index(st->readers[sz - 1]) +
1;
@@ -906,30 +900,23 @@ static int stack_write_compact(struct reftable_stack *st,
size_t first, size_t last,
struct reftable_log_expiry_config *config)
{
- size_t subtabs_len = last - first + 1;
- struct reftable_table *subtabs = reftable_calloc(
- last - first + 1, sizeof(*subtabs));
struct reftable_merged_table *mt = NULL;
struct reftable_iterator it = { NULL };
struct reftable_ref_record ref = { NULL };
struct reftable_log_record log = { NULL };
+ size_t subtabs_len = last - first + 1;
uint64_t entries = 0;
int err = 0;
- for (size_t i = first, j = 0; i <= last; i++) {
- struct reftable_reader *t = st->readers[i];
- reftable_table_from_reader(&subtabs[j++], t);
- st->stats.bytes += t->size;
- }
+ for (size_t i = first; i <= last; i++)
+ st->stats.bytes += st->readers[i]->size;
reftable_writer_set_limits(wr, st->readers[first]->min_update_index,
st->readers[last]->max_update_index);
- err = reftable_new_merged_table(&mt, subtabs, subtabs_len,
+ err = reftable_merged_table_new(&mt, st->readers + first, subtabs_len,
st->opts.hash_id);
- if (err < 0) {
- reftable_free(subtabs);
+ if (err < 0)
goto done;
- }
merged_table_init_iter(mt, &it, BLOCK_TYPE_REF);
err = reftable_iterator_seek_ref(&it, "");
@@ -1207,7 +1194,7 @@ static int stack_compact_range(struct reftable_stack *st,
* have compacted them.
*/
for (size_t j = 1; j < last - first + 1; j++) {
- const char *old = first + j < st->merged->stack_len ?
+ const char *old = first + j < st->merged->readers_len ?
st->readers[first + j]->name : NULL;
const char *new = names[i + j];
@@ -1248,10 +1235,10 @@ static int stack_compact_range(struct reftable_stack *st,
* `fd_read_lines()` uses a `NULL` sentinel to indicate that
* the array is at its end. As we use `free_names()` to free
* the array, we need to include this sentinel value here and
- * thus have to allocate `stack_len + 1` many entries.
+ * thus have to allocate `readers_len + 1` many entries.
*/
- REFTABLE_CALLOC_ARRAY(names, st->merged->stack_len + 1);
- for (size_t i = 0; i < st->merged->stack_len; i++)
+ REFTABLE_CALLOC_ARRAY(names, st->merged->readers_len + 1);
+ for (size_t i = 0; i < st->merged->readers_len; i++)
names[i] = xstrdup(st->readers[i]->name);
first_to_replace = first;
last_to_replace = last;
@@ -1358,7 +1345,7 @@ static int stack_compact_range_stats(struct reftable_stack *st,
int reftable_stack_compact_all(struct reftable_stack *st,
struct reftable_log_expiry_config *config)
{
- size_t last = st->merged->stack_len ? st->merged->stack_len - 1 : 0;
+ size_t last = st->merged->readers_len ? st->merged->readers_len - 1 : 0;
return stack_compact_range_stats(st, 0, last, config, 0);
}
@@ -1449,9 +1436,9 @@ static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st)
int overhead = header_size(version) - 1;
uint64_t *sizes;
- REFTABLE_CALLOC_ARRAY(sizes, st->merged->stack_len);
+ REFTABLE_CALLOC_ARRAY(sizes, st->merged->readers_len);
- for (size_t i = 0; i < st->merged->stack_len; i++)
+ for (size_t i = 0; i < st->merged->readers_len; i++)
sizes[i] = st->readers[i]->size - overhead;
return sizes;
@@ -1461,7 +1448,7 @@ int reftable_stack_auto_compact(struct reftable_stack *st)
{
uint64_t *sizes = stack_table_sizes_for_compaction(st);
struct segment seg =
- suggest_compaction_segment(sizes, st->merged->stack_len,
+ suggest_compaction_segment(sizes, st->merged->readers_len,
st->opts.auto_compaction_factor);
reftable_free(sizes);
if (segment_size(&seg) > 0)
@@ -1480,9 +1467,28 @@ reftable_stack_compaction_stats(struct reftable_stack *st)
int reftable_stack_read_ref(struct reftable_stack *st, const char *refname,
struct reftable_ref_record *ref)
{
- struct reftable_table tab = { NULL };
- reftable_table_from_merged_table(&tab, reftable_stack_merged_table(st));
- return reftable_table_read_ref(&tab, refname, ref);
+ struct reftable_iterator it = { 0 };
+ int ret;
+
+ reftable_merged_table_init_ref_iterator(st->merged, &it);
+ ret = reftable_iterator_seek_ref(&it, refname);
+ if (ret)
+ goto out;
+
+ ret = reftable_iterator_next_ref(&it, ref);
+ if (ret)
+ goto out;
+
+ if (strcmp(ref->refname, refname) ||
+ reftable_ref_record_is_deletion(ref)) {
+ reftable_ref_record_release(ref);
+ ret = 1;
+ goto out;
+ }
+
+out:
+ reftable_iterator_destroy(&it);
+ return ret;
}
int reftable_stack_read_log(struct reftable_stack *st, const char *refname,
@@ -1596,23 +1602,3 @@ done:
reftable_addition_destroy(add);
return err;
}
-
-int reftable_stack_print_directory(const char *stackdir, uint32_t hash_id)
-{
- struct reftable_stack *stack = NULL;
- struct reftable_write_options opts = { .hash_id = hash_id };
- struct reftable_merged_table *merged = NULL;
- struct reftable_table table = { NULL };
-
- int err = reftable_new_stack(&stack, stackdir, &opts);
- if (err < 0)
- goto done;
-
- merged = reftable_stack_merged_table(stack);
- reftable_table_from_merged_table(&table, merged);
- err = reftable_table_print(&table);
-done:
- if (stack)
- reftable_stack_destroy(stack);
- return err;
-}
diff --git a/reftable/stack_test.c b/reftable/stack_test.c
index 1a638cd2e0..311ad759d2 100644
--- a/reftable/stack_test.c
+++ b/reftable/stack_test.c
@@ -179,13 +179,6 @@ static void test_reftable_stack_add_one(void)
EXPECT(0 == strcmp("master", dest.value.symref));
EXPECT(st->readers_len > 0);
- printf("testing print functionality:\n");
- err = reftable_stack_print_directory(dir, GIT_SHA1_FORMAT_ID);
- EXPECT_ERR(err);
-
- err = reftable_stack_print_directory(dir, GIT_SHA256_FORMAT_ID);
- EXPECT(err == REFTABLE_FORMAT_ERROR);
-
#ifndef GIT_WINDOWS_NATIVE
strbuf_addstr(&scratch, dir);
strbuf_addstr(&scratch, "/tables.list");
@@ -347,9 +340,9 @@ static void test_reftable_stack_transaction_api_performs_auto_compaction(void)
* all tables in the stack.
*/
if (i != n)
- EXPECT(st->merged->stack_len == i + 1);
+ EXPECT(st->merged->readers_len == i + 1);
else
- EXPECT(st->merged->stack_len == 1);
+ EXPECT(st->merged->readers_len == 1);
}
reftable_stack_destroy(st);
@@ -375,7 +368,7 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)
err = reftable_stack_add(st, write_test_ref, &ref);
EXPECT_ERR(err);
- EXPECT(st->merged->stack_len == 1);
+ EXPECT(st->merged->readers_len == 1);
EXPECT(st->stats.attempts == 0);
EXPECT(st->stats.failures == 0);
@@ -390,7 +383,7 @@ static void test_reftable_stack_auto_compaction_fails_gracefully(void)
ref.update_index = 2;
err = reftable_stack_add(st, write_test_ref, &ref);
EXPECT_ERR(err);
- EXPECT(st->merged->stack_len == 2);
+ EXPECT(st->merged->readers_len == 2);
EXPECT(st->stats.attempts == 1);
EXPECT(st->stats.failures == 1);
@@ -881,7 +874,7 @@ static void test_reftable_stack_auto_compaction(void)
err = reftable_stack_auto_compact(st);
EXPECT_ERR(err);
- EXPECT(i < 3 || st->merged->stack_len < 2 * fastlog2(i));
+ EXPECT(i < 3 || st->merged->readers_len < 2 * fastlog2(i));
}
EXPECT(reftable_stack_compaction_stats(st)->entries_written <
@@ -905,7 +898,7 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)
EXPECT_ERR(err);
write_n_ref_tables(st, 5);
- EXPECT(st->merged->stack_len == 5);
+ EXPECT(st->merged->readers_len == 5);
/*
* Given that all tables we have written should be roughly the same
@@ -925,7 +918,7 @@ static void test_reftable_stack_auto_compaction_with_locked_tables(void)
err = reftable_stack_auto_compact(st);
EXPECT_ERR(err);
EXPECT(st->stats.failures == 0);
- EXPECT(st->merged->stack_len == 4);
+ EXPECT(st->merged->readers_len == 4);
reftable_stack_destroy(st);
strbuf_release(&buf);
@@ -970,9 +963,9 @@ static void test_reftable_stack_add_performs_auto_compaction(void)
* all tables in the stack.
*/
if (i != n)
- EXPECT(st->merged->stack_len == i + 1);
+ EXPECT(st->merged->readers_len == i + 1);
else
- EXPECT(st->merged->stack_len == 1);
+ EXPECT(st->merged->readers_len == 1);
}
reftable_stack_destroy(st);
@@ -994,7 +987,7 @@ static void test_reftable_stack_compaction_with_locked_tables(void)
EXPECT_ERR(err);
write_n_ref_tables(st, 3);
- EXPECT(st->merged->stack_len == 3);
+ EXPECT(st->merged->readers_len == 3);
/* Lock one of the tables that we're about to compact. */
strbuf_reset(&buf);
@@ -1008,7 +1001,7 @@ static void test_reftable_stack_compaction_with_locked_tables(void)
err = reftable_stack_compact_all(st, NULL);
EXPECT(err == REFTABLE_LOCK_ERROR);
EXPECT(st->stats.failures == 1);
- EXPECT(st->merged->stack_len == 3);
+ EXPECT(st->merged->readers_len == 3);
reftable_stack_destroy(st);
strbuf_release(&buf);
diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c
index ded28ee5fb..1340db8aff 100644
--- a/t/helper/test-reftable.c
+++ b/t/helper/test-reftable.c
@@ -1,4 +1,11 @@
+#include "git-compat-util.h"
+#include "hash.h"
+#include "hex.h"
#include "reftable/system.h"
+#include "reftable/reftable-error.h"
+#include "reftable/reftable-merged.h"
+#include "reftable/reftable-reader.h"
+#include "reftable/reftable-stack.h"
#include "reftable/reftable-tests.h"
#include "test-tool.h"
@@ -10,7 +17,187 @@ int cmd__reftable(int argc, const char **argv)
return 0;
}
+static void print_help(void)
+{
+ printf("usage: dump [-st] arg\n\n"
+ "options: \n"
+ " -b dump blocks\n"
+ " -t dump table\n"
+ " -s dump stack\n"
+ " -6 sha256 hash format\n"
+ " -h this help\n"
+ "\n");
+}
+
+static int dump_table(struct reftable_merged_table *mt)
+{
+ struct reftable_iterator it = { NULL };
+ struct reftable_ref_record ref = { NULL };
+ struct reftable_log_record log = { NULL };
+ const struct git_hash_algo *algop;
+ int err;
+
+ reftable_merged_table_init_ref_iterator(mt, &it);
+ err = reftable_iterator_seek_ref(&it, "");
+ if (err < 0)
+ return err;
+
+ algop = &hash_algos[hash_algo_by_id(reftable_merged_table_hash_id(mt))];
+
+ while (1) {
+ err = reftable_iterator_next_ref(&it, &ref);
+ if (err > 0)
+ break;
+ if (err < 0)
+ return err;
+
+ printf("ref{%s(%" PRIu64 ") ", ref.refname, ref.update_index);
+ switch (ref.value_type) {
+ case REFTABLE_REF_SYMREF:
+ printf("=> %s", ref.value.symref);
+ break;
+ case REFTABLE_REF_VAL2:
+ printf("val 2 %s", hash_to_hex_algop(ref.value.val2.value, algop));
+ printf("(T %s)", hash_to_hex_algop(ref.value.val2.target_value, algop));
+ break;
+ case REFTABLE_REF_VAL1:
+ printf("val 1 %s", hash_to_hex_algop(ref.value.val1, algop));
+ break;
+ case REFTABLE_REF_DELETION:
+ printf("delete");
+ break;
+ }
+ printf("}\n");
+ }
+ reftable_iterator_destroy(&it);
+ reftable_ref_record_release(&ref);
+
+ reftable_merged_table_init_log_iterator(mt, &it);
+ err = reftable_iterator_seek_log(&it, "");
+ if (err < 0)
+ return err;
+
+ while (1) {
+ err = reftable_iterator_next_log(&it, &log);
+ if (err > 0)
+ break;
+ if (err < 0)
+ return err;
+
+ switch (log.value_type) {
+ case REFTABLE_LOG_DELETION:
+ printf("log{%s(%" PRIu64 ") delete\n", log.refname,
+ log.update_index);
+ break;
+ case REFTABLE_LOG_UPDATE:
+ printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n",
+ log.refname, log.update_index,
+ log.value.update.name ? log.value.update.name : "",
+ log.value.update.email ? log.value.update.email : "",
+ log.value.update.time,
+ log.value.update.tz_offset);
+ printf("%s => ", hash_to_hex_algop(log.value.update.old_hash, algop));
+ printf("%s\n\n%s\n}\n", hash_to_hex_algop(log.value.update.new_hash, algop),
+ log.value.update.message ? log.value.update.message : "");
+ break;
+ }
+ }
+ reftable_iterator_destroy(&it);
+ reftable_log_record_release(&log);
+ return 0;
+}
+
+static int dump_stack(const char *stackdir, uint32_t hash_id)
+{
+ struct reftable_stack *stack = NULL;
+ struct reftable_write_options opts = { .hash_id = hash_id };
+ struct reftable_merged_table *merged = NULL;
+
+ int err = reftable_new_stack(&stack, stackdir, &opts);
+ if (err < 0)
+ goto done;
+
+ merged = reftable_stack_merged_table(stack);
+ err = dump_table(merged);
+done:
+ if (stack)
+ reftable_stack_destroy(stack);
+ return err;
+}
+
+static int dump_reftable(const char *tablename)
+{
+ struct reftable_block_source src = { 0 };
+ struct reftable_merged_table *mt = NULL;
+ struct reftable_reader *r = NULL;
+ int err;
+
+ err = reftable_block_source_from_file(&src, tablename);
+ if (err < 0)
+ goto done;
+
+ err = reftable_new_reader(&r, &src, tablename);
+ if (err < 0)
+ goto done;
+
+ err = reftable_merged_table_new(&mt, &r, 1,
+ reftable_reader_hash_id(r));
+ if (err < 0)
+ goto done;
+
+ err = dump_table(mt);
+
+done:
+ reftable_merged_table_free(mt);
+ reftable_reader_free(r);
+ return err;
+}
+
int cmd__dump_reftable(int argc, const char **argv)
{
- return reftable_dump_main(argc, (char *const *)argv);
+ int err = 0;
+ int opt_dump_blocks = 0;
+ int opt_dump_table = 0;
+ int opt_dump_stack = 0;
+ uint32_t opt_hash_id = GIT_SHA1_FORMAT_ID;
+ const char *arg = NULL, *argv0 = argv[0];
+
+ for (; argc > 1; argv++, argc--)
+ if (*argv[1] != '-')
+ break;
+ else if (!strcmp("-b", argv[1]))
+ opt_dump_blocks = 1;
+ else if (!strcmp("-t", argv[1]))
+ opt_dump_table = 1;
+ else if (!strcmp("-6", argv[1]))
+ opt_hash_id = GIT_SHA256_FORMAT_ID;
+ else if (!strcmp("-s", argv[1]))
+ opt_dump_stack = 1;
+ else if (!strcmp("-?", argv[1]) || !strcmp("-h", argv[1])) {
+ print_help();
+ return 2;
+ }
+
+ if (argc != 2) {
+ fprintf(stderr, "need argument\n");
+ print_help();
+ return 2;
+ }
+
+ arg = argv[1];
+
+ if (opt_dump_blocks) {
+ err = reftable_reader_print_blocks(arg);
+ } else if (opt_dump_table) {
+ err = dump_reftable(arg);
+ } else if (opt_dump_stack) {
+ err = dump_stack(arg, opt_hash_id);
+ }
+
+ if (err < 0) {
+ fprintf(stderr, "%s: %s: %s\n", argv0, arg,
+ reftable_error_str(err));
+ return 1;
+ }
+ return 0;
}
diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c
index 99f8fcadfe..c9aff3f1ea 100644
--- a/t/unit-tests/t-reftable-merged.c
+++ b/t/unit-tests/t-reftable-merged.c
@@ -12,7 +12,6 @@ https://developers.google.com/open-source/licenses/bsd
#include "reftable/merged.h"
#include "reftable/reader.h"
#include "reftable/reftable-error.h"
-#include "reftable/reftable-generic.h"
#include "reftable/reftable-merged.h"
#include "reftable/reftable-writer.h"
@@ -94,10 +93,8 @@ merged_table_from_records(struct reftable_ref_record **refs,
struct strbuf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
- struct reftable_table *tabs;
int err;
- REFTABLE_CALLOC_ARRAY(tabs, n);
REFTABLE_CALLOC_ARRAY(*readers, n);
REFTABLE_CALLOC_ARRAY(*source, n);
@@ -108,10 +105,9 @@ merged_table_from_records(struct reftable_ref_record **refs,
err = reftable_new_reader(&(*readers)[i], &(*source)[i],
"name");
check(!err);
- reftable_table_from_reader(&tabs[i], (*readers)[i]);
}
- err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID);
check(!err);
return mt;
}
@@ -272,10 +268,8 @@ merged_table_from_log_records(struct reftable_log_record **logs,
struct strbuf *buf, const size_t n)
{
struct reftable_merged_table *mt = NULL;
- struct reftable_table *tabs;
int err;
- REFTABLE_CALLOC_ARRAY(tabs, n);
REFTABLE_CALLOC_ARRAY(*readers, n);
REFTABLE_CALLOC_ARRAY(*source, n);
@@ -286,10 +280,9 @@ merged_table_from_log_records(struct reftable_log_record **logs,
err = reftable_new_reader(&(*readers)[i], &(*source)[i],
"name");
check(!err);
- reftable_table_from_reader(&tabs[i], (*readers)[i]);
}
- err = reftable_new_merged_table(&mt, tabs, n, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID);
check(!err);
return mt;
}
@@ -418,7 +411,6 @@ static void t_default_write_opts(void)
};
int err;
struct reftable_block_source source = { 0 };
- struct reftable_table *tab = reftable_calloc(1, sizeof(*tab));
uint32_t hash_id;
struct reftable_reader *rd = NULL;
struct reftable_merged_table *merged = NULL;
@@ -440,10 +432,9 @@ static void t_default_write_opts(void)
hash_id = reftable_reader_hash_id(rd);
check_int(hash_id, ==, GIT_SHA1_FORMAT_ID);
- reftable_table_from_reader(&tab[0], rd);
- err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA256_FORMAT_ID);
+ err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA256_FORMAT_ID);
check_int(err, ==, REFTABLE_FORMAT_ERROR);
- err = reftable_new_merged_table(&merged, tab, 1, GIT_SHA1_FORMAT_ID);
+ err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA1_FORMAT_ID);
check(!err);
reftable_reader_free(rd);