aboutsummaryrefslogtreecommitdiffstats
path: root/reftable/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'reftable/stack.c')
-rw-r--r--reftable/stack.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/reftable/stack.c b/reftable/stack.c
index 984fd866d0..324cb27ce9 100644
--- a/reftable/stack.c
+++ b/reftable/stack.c
@@ -10,6 +10,7 @@ https://developers.google.com/open-source/licenses/bsd
#include "../write-or-die.h"
#include "system.h"
+#include "constants.h"
#include "merged.h"
#include "reader.h"
#include "reftable-error.h"
@@ -54,15 +55,17 @@ static int reftable_fd_flush(void *arg)
}
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
- struct reftable_write_options config)
+ const struct reftable_write_options *_opts)
{
struct reftable_stack *p = reftable_calloc(1, sizeof(*p));
struct strbuf list_file_name = STRBUF_INIT;
+ struct reftable_write_options opts = {0};
int err = 0;
- if (config.hash_id == 0) {
- config.hash_id = GIT_SHA1_FORMAT_ID;
- }
+ if (_opts)
+ opts = *_opts;
+ if (opts.hash_id == 0)
+ opts.hash_id = GIT_SHA1_FORMAT_ID;
*dest = NULL;
@@ -73,7 +76,7 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir,
p->list_file = strbuf_detach(&list_file_name, NULL);
p->list_fd = -1;
p->reftable_dir = xstrdup(dir);
- p->config = config;
+ p->opts = opts;
err = reftable_stack_reload_maybe_reuse(p, 1);
if (err < 0) {
@@ -130,6 +133,20 @@ int read_lines(const char *filename, char ***namesp)
return err;
}
+void reftable_stack_init_ref_iterator(struct reftable_stack *st,
+ struct reftable_iterator *it)
+{
+ merged_table_init_iter(reftable_stack_merged_table(st),
+ it, BLOCK_TYPE_REF);
+}
+
+void reftable_stack_init_log_iterator(struct reftable_stack *st,
+ struct reftable_iterator *it)
+{
+ merged_table_init_iter(reftable_stack_merged_table(st),
+ it, BLOCK_TYPE_LOG);
+}
+
struct reftable_merged_table *
reftable_stack_merged_table(struct reftable_stack *st)
{
@@ -255,7 +272,7 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
/* success! */
err = reftable_new_merged_table(&new_merged, new_tables,
- new_readers_len, st->config.hash_id);
+ new_readers_len, st->opts.hash_id);
if (err < 0)
goto done;
@@ -576,8 +593,8 @@ static int reftable_stack_init_addition(struct reftable_addition *add,
}
goto done;
}
- if (st->config.default_permissions) {
- if (chmod(add->lock_file->filename.buf, st->config.default_permissions) < 0) {
+ if (st->opts.default_permissions) {
+ if (chmod(add->lock_file->filename.buf, st->opts.default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
@@ -676,7 +693,7 @@ int reftable_addition_commit(struct reftable_addition *add)
if (err)
goto done;
- if (!add->stack->config.disable_auto_compact) {
+ if (!add->stack->opts.disable_auto_compact) {
/*
* Auto-compact the stack to keep the number of tables in
* control. It is possible that a concurrent writer is already
@@ -754,9 +771,9 @@ int reftable_addition_add(struct reftable_addition *add,
err = REFTABLE_IO_ERROR;
goto done;
}
- if (add->stack->config.default_permissions) {
+ if (add->stack->opts.default_permissions) {
if (chmod(get_tempfile_path(tab_file),
- add->stack->config.default_permissions)) {
+ add->stack->opts.default_permissions)) {
err = REFTABLE_IO_ERROR;
goto done;
}
@@ -764,7 +781,7 @@ int reftable_addition_add(struct reftable_addition *add,
tab_fd = get_tempfile_fd(tab_file);
wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd,
- &add->stack->config);
+ &add->stack->opts);
err = write_table(wr, arg);
if (err < 0)
goto done;
@@ -847,14 +864,14 @@ static int stack_compact_locked(struct reftable_stack *st,
}
tab_fd = get_tempfile_fd(tab_file);
- if (st->config.default_permissions &&
- chmod(get_tempfile_path(tab_file), st->config.default_permissions) < 0) {
+ if (st->opts.default_permissions &&
+ chmod(get_tempfile_path(tab_file), st->opts.default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush,
- &tab_fd, &st->config);
+ &tab_fd, &st->opts);
err = stack_write_compact(st, wr, first, last, config);
if (err < 0)
goto done;
@@ -902,13 +919,14 @@ static int stack_write_compact(struct reftable_stack *st,
st->readers[last]->max_update_index);
err = reftable_new_merged_table(&mt, subtabs, subtabs_len,
- st->config.hash_id);
+ st->opts.hash_id);
if (err < 0) {
reftable_free(subtabs);
goto done;
}
- err = reftable_merged_table_seek_ref(mt, &it, "");
+ merged_table_init_iter(mt, &it, BLOCK_TYPE_REF);
+ err = reftable_iterator_seek_ref(&it, "");
if (err < 0)
goto done;
@@ -932,7 +950,8 @@ static int stack_write_compact(struct reftable_stack *st,
}
reftable_iterator_destroy(&it);
- err = reftable_merged_table_seek_log(mt, &it, "");
+ merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG);
+ err = reftable_iterator_seek_log(&it, "");
if (err < 0)
goto done;
@@ -1090,9 +1109,9 @@ static int stack_compact_range(struct reftable_stack *st,
goto done;
}
- if (st->config.default_permissions) {
+ if (st->opts.default_permissions) {
if (chmod(get_lock_file_path(&tables_list_lock),
- st->config.default_permissions) < 0) {
+ st->opts.default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
@@ -1206,12 +1225,16 @@ static int segment_size(struct segment *s)
return s->end - s->start;
}
-struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
+struct segment suggest_compaction_segment(uint64_t *sizes, size_t n,
+ uint8_t factor)
{
struct segment seg = { 0 };
uint64_t bytes;
size_t i;
+ if (!factor)
+ factor = DEFAULT_GEOMETRIC_FACTOR;
+
/*
* If there are no tables or only a single one then we don't have to
* compact anything. The sequence is geometric by definition already.
@@ -1243,7 +1266,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
* 64, 32, 16, 8, 4, 3, 1
*/
for (i = n - 1; i > 0; i--) {
- if (sizes[i - 1] < sizes[i] * 2) {
+ if (sizes[i - 1] < sizes[i] * factor) {
seg.end = i + 1;
bytes = sizes[i];
break;
@@ -1269,7 +1292,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n)
uint64_t curr = bytes;
bytes += sizes[i - 1];
- if (sizes[i - 1] < curr * 2) {
+ if (sizes[i - 1] < curr * factor) {
seg.start = i - 1;
seg.bytes = bytes;
}
@@ -1282,7 +1305,7 @@ static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st)
{
uint64_t *sizes =
reftable_calloc(st->merged->stack_len, sizeof(*sizes));
- int version = (st->config.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2;
+ int version = (st->opts.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2;
int overhead = header_size(version) - 1;
int i = 0;
for (i = 0; i < st->merged->stack_len; i++) {
@@ -1295,7 +1318,8 @@ 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->stack_len,
+ st->opts.auto_compaction_factor);
reftable_free(sizes);
if (segment_size(&seg) > 0)
return stack_compact_range_stats(st, seg.start, seg.end - 1,
@@ -1321,9 +1345,11 @@ int reftable_stack_read_ref(struct reftable_stack *st, const char *refname,
int reftable_stack_read_log(struct reftable_stack *st, const char *refname,
struct reftable_log_record *log)
{
- struct reftable_iterator it = { NULL };
- struct reftable_merged_table *mt = reftable_stack_merged_table(st);
- int err = reftable_merged_table_seek_log(mt, &it, refname);
+ struct reftable_iterator it = {0};
+ int err;
+
+ reftable_stack_init_log_iterator(st, &it);
+ err = reftable_iterator_seek_log(&it, refname);
if (err)
goto done;
@@ -1431,11 +1457,11 @@ done:
int reftable_stack_print_directory(const char *stackdir, uint32_t hash_id)
{
struct reftable_stack *stack = NULL;
- struct reftable_write_options cfg = { .hash_id = hash_id };
+ 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, cfg);
+ int err = reftable_new_stack(&stack, stackdir, &opts);
if (err < 0)
goto done;