}
int reftable_new_stack(struct reftable_stack **dest, const char *dir,
- const struct reftable_write_options *_opts)
+ const struct reftable_stack_options *_opts)
{
struct reftable_buf list_file_name = REFTABLE_BUF_INIT;
- struct reftable_write_options opts = { 0 };
+ struct reftable_stack_options opts = { 0 };
struct reftable_stack *p;
int err;
struct reftable_addition {
struct reftable_flock tables_list_lock;
struct reftable_stack *stack;
+ struct reftable_write_options opts;
char **new_tables;
size_t new_tables_len, new_tables_cap;
static int reftable_stack_init_addition(struct reftable_addition *add,
struct reftable_stack *st,
+ const struct reftable_write_options *opts,
unsigned int flags)
{
struct reftable_buf lock_file_name = REFTABLE_BUF_INIT;
memset(add, 0, sizeof(*add));
add->stack = st;
+ if (opts)
+ add->opts = *opts;
err = flock_acquire(&add->tables_list_lock, st->list_file,
- st->opts.lock_timeout_ms);
+ add->opts.lock_timeout_ms);
if (err < 0)
goto done;
- if (st->opts.default_permissions) {
+ if (add->opts.default_permissions) {
if (chmod(add->tables_list_lock.path,
- st->opts.default_permissions) < 0) {
+ add->opts.default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
static int stack_try_add(struct reftable_stack *st,
int (*write_table)(struct reftable_writer *wr,
void *arg),
- void *arg, unsigned flags)
+ void *arg,
+ const struct reftable_write_options *opts,
+ unsigned flags)
{
struct reftable_addition add;
int err;
- err = reftable_stack_init_addition(&add, st, flags);
+ err = reftable_stack_init_addition(&add, st, opts, flags);
if (err < 0)
goto done;
int reftable_stack_add(struct reftable_stack *st,
int (*write)(struct reftable_writer *wr, void *arg),
- void *arg, unsigned flags)
+ void *arg,
+ const struct reftable_write_options *opts,
+ unsigned flags)
{
- int err = stack_try_add(st, write, arg, flags);
+ int err = stack_try_add(st, write, arg, opts, flags);
if (err < 0) {
if (err == REFTABLE_OUTDATED_ERROR) {
/* Ignore error return, we want to propagate
if (err)
goto done;
- if (!add->stack->opts.disable_auto_compact) {
+ if (!add->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
* concurrent writer, which causes `REFTABLE_OUTDATED_ERROR`.
* Both of these errors are benign, so we simply ignore them.
*/
- err = reftable_stack_auto_compact(add->stack);
+ err = reftable_stack_auto_compact(add->stack, &add->opts);
if (err < 0 && err != REFTABLE_LOCK_ERROR &&
err != REFTABLE_OUTDATED_ERROR)
goto done;
int reftable_stack_new_addition(struct reftable_addition **dest,
struct reftable_stack *st,
+ const struct reftable_write_options *opts,
unsigned int flags)
{
int err;
if (!*dest)
return REFTABLE_OUT_OF_MEMORY_ERROR;
- err = reftable_stack_init_addition(*dest, st, flags);
+ err = reftable_stack_init_addition(*dest, st, opts, flags);
if (err) {
reftable_free(*dest);
*dest = NULL;
struct reftable_writer *wr = NULL;
struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT;
struct fd_writer writer = {
- .opts = &add->stack->opts,
+ .opts = &add->opts,
};
int err = 0;
err = tmpfile_from_pattern(&tab_file, temp_tab_file_name.buf);
if (err < 0)
goto done;
- if (add->stack->opts.default_permissions) {
+ if (add->opts.default_permissions) {
if (chmod(tab_file.path,
- add->stack->opts.default_permissions)) {
+ add->opts.default_permissions)) {
err = REFTABLE_IO_ERROR;
goto done;
}
writer.fd = tab_file.fd;
err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
- &writer, &add->stack->opts);
+ &writer, add->stack->opts.hash_id, &add->opts);
if (err < 0)
goto done;
static int stack_compact_locked(struct reftable_stack *st,
size_t first, size_t last,
struct reftable_log_expiry_config *config,
+ const struct reftable_write_options *opts,
struct reftable_tmpfile *tab_file_out)
{
struct reftable_buf next_name = REFTABLE_BUF_INIT;
struct reftable_buf tab_file_path = REFTABLE_BUF_INIT;
struct reftable_writer *wr = NULL;
struct fd_writer writer= {
- .opts = &st->opts,
+ .opts = opts,
};
struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT;
int err = 0;
if (err < 0)
goto done;
- if (st->opts.default_permissions &&
- chmod(tab_file.path, st->opts.default_permissions) < 0) {
+ if (opts->default_permissions &&
+ chmod(tab_file.path, opts->default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
writer.fd = tab_file.fd;
err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush,
- &writer, &st->opts);
+ &writer, st->opts.hash_id, opts);
if (err < 0)
goto done;
static int stack_compact_range(struct reftable_stack *st,
size_t first, size_t last,
struct reftable_log_expiry_config *expiry,
+ const struct reftable_write_options *opts,
unsigned int flags)
{
struct reftable_buf tables_list_buf = REFTABLE_BUF_INIT;
* Hold the lock so that we can read "tables.list" and lock all tables
* which are part of the user-specified range.
*/
- err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
+ err = flock_acquire(&tables_list_lock, st->list_file, opts->lock_timeout_ms);
if (err < 0)
goto done;
* these tables may end up with an empty new table in case tombstones
* end up cancelling out all refs in that range.
*/
- err = stack_compact_locked(st, first, last, expiry, &new_table);
+ err = stack_compact_locked(st, first, last, expiry, opts, &new_table);
if (err < 0) {
if (err != REFTABLE_EMPTY_TABLE_ERROR)
goto done;
* "tables.list". We'll then replace the compacted range of tables with
* the new table.
*/
- err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms);
+ err = flock_acquire(&tables_list_lock, st->list_file, opts->lock_timeout_ms);
if (err < 0)
goto done;
- if (st->opts.default_permissions) {
+ if (opts->default_permissions) {
if (chmod(tables_list_lock.path,
- st->opts.default_permissions) < 0) {
+ opts->default_permissions) < 0) {
err = REFTABLE_IO_ERROR;
goto done;
}
}
int reftable_stack_compact_all(struct reftable_stack *st,
+ const struct reftable_write_options *opts,
struct reftable_log_expiry_config *config)
{
+ struct reftable_write_options opts_default = { 0 };
size_t last = st->merged->tables_len ? st->merged->tables_len - 1 : 0;
- return stack_compact_range(st, 0, last, config, 0);
+
+ if (!opts)
+ opts = &opts_default;
+
+ return stack_compact_range(st, 0, last, config, opts, 0);
}
static int segment_size(struct segment *s)
}
static int stack_segments_for_compaction(struct reftable_stack *st,
+ const struct reftable_write_options *opts,
struct segment *seg)
{
int version = (st->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2;
sizes[i] = st->tables[i]->size - overhead;
*seg = suggest_compaction_segment(sizes, st->merged->tables_len,
- st->opts.auto_compaction_factor);
+ opts->auto_compaction_factor);
reftable_free(sizes);
return 0;
}
static int update_segment_if_compaction_required(struct reftable_stack *st,
+ const struct reftable_write_options *opts,
struct segment *seg,
bool use_geometric,
bool *required)
return 0;
}
- err = stack_segments_for_compaction(st, seg);
+ err = stack_segments_for_compaction(st, opts, seg);
if (err)
return err;
}
int reftable_stack_compaction_required(struct reftable_stack *st,
+ const struct reftable_write_options *opts,
bool use_heuristics,
bool *required)
{
+ struct reftable_write_options opts_default = { 0 };
struct segment seg;
- return update_segment_if_compaction_required(st, &seg, use_heuristics,
- required);
+
+ if (!opts)
+ opts = &opts_default;
+
+ return update_segment_if_compaction_required(st, opts, &seg,
+ use_heuristics, required);
}
-int reftable_stack_auto_compact(struct reftable_stack *st)
+int reftable_stack_auto_compact(struct reftable_stack *st,
+ const struct reftable_write_options *opts)
{
+ struct reftable_write_options opts_default = { 0 };
struct segment seg;
bool required;
int err;
- err = update_segment_if_compaction_required(st, &seg, true, &required);
+ if (!opts)
+ opts = &opts_default;
+
+ err = update_segment_if_compaction_required(st, opts, &seg, true,
+ &required);
if (err)
return err;
if (required)
return stack_compact_range(st, seg.start, seg.end - 1,
- NULL, STACK_COMPACT_RANGE_BEST_EFFORT);
+ NULL, opts,
+ STACK_COMPACT_RANGE_BEST_EFFORT);
return 0;
}
int reftable_stack_clean(struct reftable_stack *st)
{
struct reftable_addition *add = NULL;
- int err = reftable_stack_new_addition(&add, st, 0);
+ int err = reftable_stack_new_addition(&add, st, NULL, 0);
if (err < 0) {
goto done;
}
static void write_n_ref_tables(struct reftable_stack *st,
size_t n)
{
- int disable_auto_compact;
-
- disable_auto_compact = st->opts.disable_auto_compact;
- st->opts.disable_auto_compact = 1;
+ struct reftable_write_options opts = {
+ .disable_auto_compact = 1,
+ };
for (size_t i = 0; i < n; i++) {
struct reftable_ref_record ref = {
cl_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1);
cl_assert_equal_i(reftable_stack_add(st,
- &write_test_ref, &ref, 0), 0);
+ &write_test_ref, &ref, &opts, 0), 0);
}
-
- st->opts.disable_auto_compact = disable_auto_compact;
}
struct write_log_arg {
struct stat stat_result = { 0 };
int err;
- err = reftable_new_stack(&st, dir, &opts);
+ err = reftable_new_stack(&st, dir, NULL);
cl_assert(!err);
- err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ err = reftable_stack_add(st, write_test_ref, &ref, &opts, 0);
cl_assert(!err);
err = reftable_stack_read_ref(st, ref.refname, &dest);
void test_reftable_stack__uptodate(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL;
struct reftable_stack *st2 = NULL;
char *dir = get_tmp_dir(__LINE__);
/* simulate multi-process access to the same stack
by creating two stacks for the same directory.
*/
- cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
- cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_add(st1, write_test_ref,
- &ref1, 0), 0);
+ &ref1, NULL, 0), 0);
cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
- &ref2, 0), REFTABLE_OUTDATED_ERROR);
+ &ref2, NULL, 0), REFTABLE_OUTDATED_ERROR);
cl_assert_equal_i(reftable_stack_reload(st2), 0);
cl_assert_equal_i(reftable_stack_add(st2, write_test_ref,
- &ref2, 0), 0);
+ &ref2, NULL, 0), 0);
reftable_stack_destroy(st1);
reftable_stack_destroy(st2);
clear_dir(dir);
void test_reftable_stack__transaction_api(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_addition *add = NULL;
};
struct reftable_ref_record dest = { 0 };
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
reftable_addition_destroy(add);
- cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st, NULL, 0), 0);
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
&ref), 0);
cl_assert_equal_i(reftable_addition_commit(add), 0);
cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
- cl_assert_equal_i(reftable_stack_new_addition(&add, st1, 0), 0);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st1, NULL, 0), 0);
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
&refs[0]), 0);
cl_assert_equal_i(reftable_addition_commit(add), 0);
* create the addition and lock the stack by default, but allow the
* reload to happen when REFTABLE_STACK_NEW_ADDITION_RELOAD is set.
*/
- cl_assert_equal_i(reftable_stack_new_addition(&add, st2, 0),
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st2, NULL, 0),
REFTABLE_OUTDATED_ERROR);
- cl_assert_equal_i(reftable_stack_new_addition(&add, st2,
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st2, NULL,
REFTABLE_STACK_NEW_ADDITION_RELOAD), 0);
cl_assert_equal_i(reftable_addition_add(add, write_test_ref,
&refs[1]), 0);
void test_reftable_stack__transaction_api_performs_auto_compaction(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = {0};
struct reftable_addition *add = NULL;
struct reftable_stack *st = NULL;
size_t n = 20;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (size_t i = 0; i <= n; i++) {
struct reftable_ref_record ref = {
.value.symref = (char *) "master",
};
char name[100];
+ struct reftable_write_options write_opts = {
+ .disable_auto_compact = (i != n),
+ };
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
ref.refname = name;
* we can ensure that we indeed honor this setting and have
* better control over when exactly auto compaction runs.
*/
- st->opts.disable_auto_compact = i != n;
-
cl_assert_equal_i(reftable_stack_new_addition(&add,
- st, 0), 0);
+ st, &write_opts, 0), 0);
cl_assert_equal_i(reftable_addition_add(add,
write_test_ref, &ref), 0);
cl_assert_equal_i(reftable_addition_commit(add), 0);
.value_type = REFTABLE_REF_VAL1,
.value.val1 = {0x01},
};
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st;
struct reftable_buf table_path = REFTABLE_BUF_INIT;
char *dir = get_tmp_dir(__LINE__);
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &ref, 0), 0);
+ &ref, NULL, 0), 0);
cl_assert_equal_i(st->merged->tables_len, 1);
cl_assert_equal_i(st->stats.attempts, 0);
cl_assert_equal_i(st->stats.failures, 0);
write_file_buf(table_path.buf, "", 0);
ref.update_index = 2;
- err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ err = reftable_stack_add(st, write_test_ref, &ref, NULL, 0);
cl_assert(!err);
cl_assert_equal_i(st->merged->tables_len, 2);
cl_assert_equal_i(st->stats.attempts, 1);
void test_reftable_stack__update_index_check(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_ref_record ref1 = {
.refname = (char *) "name1",
.value.symref = (char *) "master",
};
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &ref1, 0), 0);
+ &ref1, NULL, 0), 0);
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &ref2, 0), REFTABLE_API_ERROR);
+ &ref2, NULL, 0), REFTABLE_API_ERROR);
reftable_stack_destroy(st);
clear_dir(dir);
}
void test_reftable_stack__lock_failure(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
int i;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--)
cl_assert_equal_i(reftable_stack_add(st, write_error,
- &i, 0), i);
+ &i, NULL, 0), i);
reftable_stack_destroy(st);
clear_dir(dir);
size_t i, N = ARRAY_SIZE(refs);
int err = 0;
- err = reftable_new_stack(&st, dir, &opts);
+ err = reftable_new_stack(&st, dir, NULL);
cl_assert(!err);
for (i = 0; i < N; i++) {
for (i = 0; i < N; i++)
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &refs[i], 0), 0);
+ &refs[i], &opts, 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
.update_index = reftable_stack_next_update_index(st),
};
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, &opts, 0), 0);
}
- cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, &opts, NULL), 0);
for (i = 0; i < N; i++) {
struct reftable_ref_record dest = { 0 };
void test_reftable_stack__iterator(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
struct reftable_ref_record refs[10] = { 0 };
size_t N = ARRAY_SIZE(refs), i;
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (i = 0; i < N; i++) {
refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i);
for (i = 0; i < N; i++)
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &refs[i], 0), 0);
+ &refs[i], NULL, 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
};
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, NULL, 0), 0);
}
reftable_stack_init_ref_iterator(st, &it);
void test_reftable_stack__log_normalize(void)
{
- struct reftable_write_options opts = {
- 0,
- };
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
struct reftable_log_record input = {
.update_index = 1,
};
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
input.value.update.message = (char *) "one\ntwo";
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), REFTABLE_API_ERROR);
+ &arg, NULL, 0), REFTABLE_API_ERROR);
input.value.update.message = (char *) "one";
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, NULL, 0), 0);
cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
&dest), 0);
cl_assert_equal_s(dest.value.update.message, "one\n");
input.value.update.message = (char *) "two\n";
arg.update_index = 2;
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, NULL, 0), 0);
cl_assert_equal_i(reftable_stack_read_log(st, input.refname,
&dest), 0);
cl_assert_equal_s(dest.value.update.message, "two\n");
void test_reftable_stack__tombstone(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_ref_record refs[2] = { 0 };
struct reftable_log_record logs[2] = { 0 };
struct reftable_ref_record dest = { 0 };
struct reftable_log_record log_dest = { 0 };
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
/* even entries add the refs, odd entries delete them. */
for (i = 0; i < N; i++) {
}
for (i = 0; i < N; i++)
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &refs[i], 0), 0);
+ &refs[i], NULL, 0), 0);
for (i = 0; i < N; i++) {
struct write_log_arg arg = {
.update_index = reftable_stack_next_update_index(st),
};
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, NULL, 0), 0);
}
cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
&log_dest), 1);
reftable_log_record_release(&log_dest);
- cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL, NULL), 0);
cl_assert_equal_i(reftable_stack_read_ref(st, "branch",
&dest), 1);
cl_assert_equal_i(reftable_stack_read_log(st, "branch",
void test_reftable_stack__hash_id(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_ref_record ref = {
.value.symref = (char *) "target",
.update_index = 1,
};
- struct reftable_write_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 };
+ struct reftable_stack_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 };
struct reftable_stack *st32 = NULL;
- struct reftable_write_options opts_default = { 0 };
struct reftable_stack *st_default = NULL;
struct reftable_ref_record dest = { 0 };
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &ref, 0), 0);
+ &ref, NULL, 0), 0);
/* can't read it with the wrong hash ID. */
cl_assert_equal_i(reftable_new_stack(&st32, dir,
/* check that we can read it back with default opts too. */
cl_assert_equal_i(reftable_new_stack(&st_default, dir,
- &opts_default), 0);
+ NULL), 0);
cl_assert_equal_i(reftable_stack_read_ref(st_default, "master",
&dest), 0);
cl_assert(reftable_ref_record_equal(&ref, &dest,
void test_reftable_stack__reflog_expire(void)
{
char *dir = get_tmp_dir(__LINE__);
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_log_record logs[20] = { 0 };
size_t i, N = ARRAY_SIZE(logs) - 1;
};
struct reftable_log_record log = { 0 };
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (i = 1; i <= N; i++) {
char buf[256];
.update_index = reftable_stack_next_update_index(st),
};
cl_assert_equal_i(reftable_stack_add(st, write_test_log,
- &arg, 0), 0);
+ &arg, NULL, 0), 0);
}
- cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0);
- cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL, &expiry), 0);
cl_assert_equal_i(reftable_stack_read_log(st, logs[9].refname,
&log), 1);
cl_assert_equal_i(reftable_stack_read_log(st, logs[11].refname,
&log), 0);
expiry.min_update_index = 15;
- cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st, NULL, &expiry), 0);
cl_assert_equal_i(reftable_stack_read_log(st, logs[14].refname,
&log), 1);
cl_assert_equal_i(reftable_stack_read_log(st, logs[16].refname,
void test_reftable_stack__empty_add(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
struct reftable_stack *st2 = NULL;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_add(st, write_nothing,
- NULL, 0), 0);
- cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
+ NULL, NULL, 0), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
clear_dir(dir);
reftable_stack_destroy(st);
reftable_stack_destroy(st2);
size_t i, N = 100;
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (i = 0; i < N; i++) {
char name[100];
};
snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
- err = reftable_stack_add(st, write_test_ref, &ref, 0);
+ err = reftable_stack_add(st, write_test_ref, &ref, &opts, 0);
cl_assert(!err);
- err = reftable_stack_auto_compact(st);
+ err = reftable_stack_auto_compact(st, &opts);
cl_assert(!err);
cl_assert(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2));
}
size_t N = 100;
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (size_t i = 0; i < N; i++) {
char name[20];
};
xsnprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i);
- err = reftable_stack_add(st, &write_test_ref, &ref, 0);
+ err = reftable_stack_add(st, &write_test_ref, &ref, &opts, 0);
cl_assert(!err);
cl_assert(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5));
char *dir = get_tmp_dir(__LINE__);
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
write_n_ref_tables(st, 5);
cl_assert_equal_i(st->merged->tables_len, 5);
* would in theory compact all tables, due to the preexisting lock we
* only compact the newest two tables.
*/
- err = reftable_stack_auto_compact(st);
+ err = reftable_stack_auto_compact(st, &opts);
cl_assert(!err);
cl_assert_equal_i(st->stats.failures, 0);
cl_assert_equal_i(st->merged->tables_len, 4);
void test_reftable_stack__add_performs_auto_compaction(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
char *dir = get_tmp_dir(__LINE__);
size_t i, n = 20;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
for (i = 0; i <= n; i++) {
struct reftable_ref_record ref = {
.value_type = REFTABLE_REF_SYMREF,
.value.symref = (char *) "master",
};
+ struct reftable_write_options write_opts = {
+ .disable_auto_compact = (i != n),
+ };
bool required = false;
char buf[128];
* we can ensure that we indeed honor this setting and have
* better control over when exactly auto compaction runs.
*/
- st->opts.disable_auto_compact = i != n;
-
snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i);
ref.refname = buf;
cl_assert_equal_i(reftable_stack_add(st, write_test_ref,
- &ref, 0), 0);
+ &ref, &write_opts, 0), 0);
/*
* The stack length should grow continuously for all runs where
* auto compaction is disabled. When enabled, we should merge
* all tables in the stack.
*/
- cl_assert_equal_i(reftable_stack_compaction_required(st, true, &required), 0);
+ cl_assert_equal_i(reftable_stack_compaction_required(st, NULL, true, &required), 0);
if (i != n) {
cl_assert_equal_i(st->merged->tables_len, i + 1);
if (i < 1)
char *dir = get_tmp_dir(__LINE__);
int err;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
write_n_ref_tables(st, 3);
cl_assert_equal_i(st->merged->tables_len, 3);
* Compaction is expected to fail given that we were not able to
* compact all tables.
*/
- err = reftable_stack_compact_all(st, NULL);
+ err = reftable_stack_compact_all(st, &opts, NULL);
cl_assert_equal_i(err, REFTABLE_LOCK_ERROR);
cl_assert_equal_i(st->stats.failures, 1);
cl_assert_equal_i(st->merged->tables_len, 3);
void test_reftable_stack__compaction_concurrent(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL;
char *dir = get_tmp_dir(__LINE__);
- cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
write_n_ref_tables(st1, 3);
- cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
- cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st1, NULL, NULL), 0);
reftable_stack_destroy(st1);
reftable_stack_destroy(st2);
void test_reftable_stack__compaction_concurrent_clean(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL;
char *dir = get_tmp_dir(__LINE__);
- cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
write_n_ref_tables(st1, 3);
- cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0);
- cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0);
+ cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0);
+ cl_assert_equal_i(reftable_stack_compact_all(st1, NULL, NULL), 0);
unclean_stack_close(st1);
unclean_stack_close(st2);
- cl_assert_equal_i(reftable_new_stack(&st3, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st3, dir, NULL), 0);
cl_assert_equal_i(reftable_stack_clean(st3), 0);
cl_assert_equal_i(count_dir_entries(dir), 2);
void test_reftable_stack__read_across_reload(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st1 = NULL, *st2 = NULL;
struct reftable_ref_record rec = { 0 };
struct reftable_iterator it = { 0 };
int err;
/* Create a first stack and set up an iterator for it. */
- cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0);
write_n_ref_tables(st1, 2);
cl_assert_equal_i(st1->merged->tables_len, 2);
reftable_stack_init_ref_iterator(st1, &it);
cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0);
/* Set up a second stack for the same directory and compact it. */
- err = reftable_new_stack(&st2, dir, &opts);
+ err = reftable_new_stack(&st2, dir, NULL);
cl_assert(!err);
cl_assert_equal_i(st2->merged->tables_len, 2);
- err = reftable_stack_compact_all(st2, NULL);
+ err = reftable_stack_compact_all(st2, NULL, NULL);
cl_assert(!err);
cl_assert_equal_i(st2->merged->tables_len, 1);
void test_reftable_stack__reload_with_missing_table(void)
{
- struct reftable_write_options opts = { 0 };
struct reftable_stack *st = NULL;
struct reftable_ref_record rec = { 0 };
struct reftable_iterator it = { 0 };
int err;
/* Create a first stack and set up an iterator for it. */
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
write_n_ref_tables(st, 2);
cl_assert_equal_i(st->merged->tables_len, 2);
reftable_stack_init_ref_iterator(st, &it);
char *dir = get_tmp_dir(__LINE__);
struct reftable_stack *st = NULL;
- cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0);
+ cl_assert_equal_i(reftable_new_stack(&st, dir, NULL), 0);
reftable_addition_destroy(add);
- cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0);
+ cl_assert_equal_i(reftable_stack_new_addition(&add, st, &opts, 0), 0);
/*
* write_limits_after_ref also updates the update indexes after adding