Skip to content

Commit ad0986c

Browse files
pks-tgitster
authored andcommitted
refs/reftable: encapsulate reftable stack
The reftable ref store needs to keep track of multiple stacks, one for the main worktree and an arbitrary number of stacks for worktrees. This is done by storing pointers to `struct reftable_stack`, which we then access directly. Wrap the stack in a new `struct reftable_backend`. This will allow us to attach more data to each respective stack in subsequent commits. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b8558e6 commit ad0986c

File tree

1 file changed

+76
-59
lines changed

1 file changed

+76
-59
lines changed

refs/reftable-backend.c

Lines changed: 76 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,41 @@
3434
*/
3535
#define REF_UPDATE_VIA_HEAD (1 << 8)
3636

37+
struct reftable_backend {
38+
struct reftable_stack *stack;
39+
};
40+
41+
static int reftable_backend_init(struct reftable_backend *be,
42+
const char *path,
43+
const struct reftable_write_options *opts)
44+
{
45+
return reftable_new_stack(&be->stack, path, opts);
46+
}
47+
48+
static void reftable_backend_release(struct reftable_backend *be)
49+
{
50+
reftable_stack_destroy(be->stack);
51+
be->stack = NULL;
52+
}
53+
3754
struct reftable_ref_store {
3855
struct ref_store base;
3956

4057
/*
41-
* The main stack refers to the common dir and thus contains common
58+
* The main backend refers to the common dir and thus contains common
4259
* refs as well as refs of the main repository.
4360
*/
44-
struct reftable_stack *main_stack;
61+
struct reftable_backend main_backend;
4562
/*
46-
* The worktree stack refers to the gitdir in case the refdb is opened
63+
* The worktree backend refers to the gitdir in case the refdb is opened
4764
* via a worktree. It thus contains the per-worktree refs.
4865
*/
49-
struct reftable_stack *worktree_stack;
66+
struct reftable_backend worktree_backend;
5067
/*
51-
* Map of worktree stacks by their respective worktree names. The map
68+
* Map of worktree backends by their respective worktree names. The map
5269
* is populated lazily when we try to resolve `worktrees/$worktree` refs.
5370
*/
54-
struct strmap worktree_stacks;
71+
struct strmap worktree_backends;
5572
struct reftable_write_options write_options;
5673

5774
unsigned int store_flags;
@@ -97,21 +114,21 @@ static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_sto
97114
* like `worktrees/$worktree/refs/heads/foo` as worktree stacks will store
98115
* those references in their normalized form.
99116
*/
100-
static struct reftable_stack *stack_for(struct reftable_ref_store *store,
101-
const char *refname,
102-
const char **rewritten_ref)
117+
static struct reftable_backend *backend_for(struct reftable_ref_store *store,
118+
const char *refname,
119+
const char **rewritten_ref)
103120
{
104121
const char *wtname;
105122
int wtname_len;
106123

107124
if (!refname)
108-
return store->main_stack;
125+
return &store->main_backend;
109126

110127
switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) {
111128
case REF_WORKTREE_OTHER: {
112129
static struct strbuf wtname_buf = STRBUF_INIT;
113130
struct strbuf wt_dir = STRBUF_INIT;
114-
struct reftable_stack *stack;
131+
struct reftable_backend *be;
115132

116133
/*
117134
* We're using a static buffer here so that we don't need to
@@ -125,37 +142,39 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store,
125142
/*
126143
* There is an edge case here: when the worktree references the
127144
* current worktree, then we set up the stack once via
128-
* `worktree_stacks` and once via `worktree_stack`. This is
145+
* `worktree_backends` and once via `worktree_backend`. This is
129146
* wasteful, but in the reading case it shouldn't matter. And
130147
* in the writing case we would notice that the stack is locked
131148
* already and error out when trying to write a reference via
132149
* both stacks.
133150
*/
134-
stack = strmap_get(&store->worktree_stacks, wtname_buf.buf);
135-
if (!stack) {
151+
be = strmap_get(&store->worktree_backends, wtname_buf.buf);
152+
if (!be) {
136153
strbuf_addf(&wt_dir, "%s/worktrees/%s/reftable",
137154
store->base.repo->commondir, wtname_buf.buf);
138155

139-
store->err = reftable_new_stack(&stack, wt_dir.buf,
140-
&store->write_options);
156+
CALLOC_ARRAY(be, 1);
157+
store->err = reftable_backend_init(be, wt_dir.buf,
158+
&store->write_options);
141159
assert(store->err != REFTABLE_API_ERROR);
142-
strmap_put(&store->worktree_stacks, wtname_buf.buf, stack);
160+
161+
strmap_put(&store->worktree_backends, wtname_buf.buf, be);
143162
}
144163

145164
strbuf_release(&wt_dir);
146-
return stack;
165+
return be;
147166
}
148167
case REF_WORKTREE_CURRENT:
149168
/*
150169
* If there is no worktree stack then we're currently in the
151170
* main worktree. We thus return the main stack in that case.
152171
*/
153-
if (!store->worktree_stack)
154-
return store->main_stack;
155-
return store->worktree_stack;
172+
if (!store->worktree_backend.stack)
173+
return &store->main_backend;
174+
return &store->worktree_backend;
156175
case REF_WORKTREE_MAIN:
157176
case REF_WORKTREE_SHARED:
158-
return store->main_stack;
177+
return &store->main_backend;
159178
default:
160179
BUG("unhandled worktree reference type");
161180
}
@@ -292,7 +311,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
292311
umask(mask);
293312

294313
base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable);
295-
strmap_init(&refs->worktree_stacks);
314+
strmap_init(&refs->worktree_backends);
296315
refs->store_flags = store_flags;
297316
refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo);
298317

@@ -337,8 +356,8 @@ static struct ref_store *reftable_be_init(struct repository *repo,
337356
strbuf_realpath(&path, gitdir, 0);
338357
}
339358
strbuf_addstr(&path, "/reftable");
340-
refs->err = reftable_new_stack(&refs->main_stack, path.buf,
341-
&refs->write_options);
359+
refs->err = reftable_backend_init(&refs->main_backend, path.buf,
360+
&refs->write_options);
342361
if (refs->err)
343362
goto done;
344363

@@ -354,8 +373,8 @@ static struct ref_store *reftable_be_init(struct repository *repo,
354373
strbuf_reset(&path);
355374
strbuf_addf(&path, "%s/reftable", gitdir);
356375

357-
refs->err = reftable_new_stack(&refs->worktree_stack, path.buf,
358-
&refs->write_options);
376+
refs->err = reftable_backend_init(&refs->worktree_backend, path.buf,
377+
&refs->write_options);
359378
if (refs->err)
360379
goto done;
361380
}
@@ -374,19 +393,17 @@ static void reftable_be_release(struct ref_store *ref_store)
374393
struct strmap_entry *entry;
375394
struct hashmap_iter iter;
376395

377-
if (refs->main_stack) {
378-
reftable_stack_destroy(refs->main_stack);
379-
refs->main_stack = NULL;
380-
}
396+
if (refs->main_backend.stack)
397+
reftable_backend_release(&refs->main_backend);
398+
if (refs->worktree_backend.stack)
399+
reftable_backend_release(&refs->worktree_backend);
381400

382-
if (refs->worktree_stack) {
383-
reftable_stack_destroy(refs->worktree_stack);
384-
refs->worktree_stack = NULL;
401+
strmap_for_each_entry(&refs->worktree_backends, &iter, entry) {
402+
struct reftable_backend *be = entry->value;
403+
reftable_backend_release(be);
404+
free(be);
385405
}
386-
387-
strmap_for_each_entry(&refs->worktree_stacks, &iter, entry)
388-
reftable_stack_destroy(entry->value);
389-
strmap_clear(&refs->worktree_stacks, 0);
406+
strmap_clear(&refs->worktree_backends, 0);
390407
}
391408

392409
static int reftable_be_create_on_disk(struct ref_store *ref_store,
@@ -781,22 +798,22 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto
781798
required_flags |= REF_STORE_ODB;
782799
refs = reftable_be_downcast(ref_store, required_flags, "ref_iterator_begin");
783800

784-
main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix,
801+
main_iter = ref_iterator_for_stack(refs, refs->main_backend.stack, prefix,
785802
exclude_patterns, flags);
786803

787804
/*
788805
* The worktree stack is only set when we're in an actual worktree
789806
* right now. If we aren't, then we return the common reftable
790807
* iterator, only.
791808
*/
792-
if (!refs->worktree_stack)
809+
if (!refs->worktree_backend.stack)
793810
return &main_iter->base;
794811

795812
/*
796813
* Otherwise we merge both the common and the per-worktree refs into a
797814
* single iterator.
798815
*/
799-
worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix,
816+
worktree_iter = ref_iterator_for_stack(refs, refs->worktree_backend.stack, prefix,
800817
exclude_patterns, flags);
801818
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
802819
ref_iterator_select, NULL);
@@ -811,7 +828,7 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store,
811828
{
812829
struct reftable_ref_store *refs =
813830
reftable_be_downcast(ref_store, REF_STORE_READ, "read_raw_ref");
814-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
831+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
815832
int ret;
816833

817834
if (refs->err < 0)
@@ -838,7 +855,7 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store,
838855
{
839856
struct reftable_ref_store *refs =
840857
reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref");
841-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
858+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
842859
struct reftable_ref_record ref = {0};
843860
int ret;
844861

@@ -898,7 +915,7 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out,
898915
struct ref_update *update,
899916
struct strbuf *err)
900917
{
901-
struct reftable_stack *stack = stack_for(refs, update->refname, NULL);
918+
struct reftable_stack *stack = backend_for(refs, update->refname, NULL)->stack;
902919
struct write_transaction_table_arg *arg = NULL;
903920
size_t i;
904921
int ret;
@@ -1031,7 +1048,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
10311048
goto done;
10321049
}
10331050

1034-
ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD",
1051+
ret = read_ref_without_reload(refs, backend_for(refs, "HEAD", NULL)->stack, "HEAD",
10351052
&head_oid, &head_referent, &head_type);
10361053
if (ret < 0)
10371054
goto done;
@@ -1043,7 +1060,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
10431060
struct reftable_stack *stack;
10441061
const char *rewritten_ref;
10451062

1046-
stack = stack_for(refs, u->refname, &rewritten_ref);
1063+
stack = backend_for(refs, u->refname, &rewritten_ref)->stack;
10471064

10481065
/* Verify that the new object ID is valid. */
10491066
if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) &&
@@ -1525,9 +1542,9 @@ static int reftable_be_pack_refs(struct ref_store *ref_store,
15251542
if (refs->err)
15261543
return refs->err;
15271544

1528-
stack = refs->worktree_stack;
1545+
stack = refs->worktree_backend.stack;
15291546
if (!stack)
1530-
stack = refs->main_stack;
1547+
stack = refs->main_backend.stack;
15311548

15321549
if (opts->flags & PACK_REFS_AUTO)
15331550
ret = reftable_stack_auto_compact(stack);
@@ -1782,7 +1799,7 @@ static int reftable_be_rename_ref(struct ref_store *ref_store,
17821799
{
17831800
struct reftable_ref_store *refs =
17841801
reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref");
1785-
struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname);
1802+
struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack;
17861803
struct write_copy_arg arg = {
17871804
.refs = refs,
17881805
.stack = stack,
@@ -1814,7 +1831,7 @@ static int reftable_be_copy_ref(struct ref_store *ref_store,
18141831
{
18151832
struct reftable_ref_store *refs =
18161833
reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref");
1817-
struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname);
1834+
struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack;
18181835
struct write_copy_arg arg = {
18191836
.refs = refs,
18201837
.stack = stack,
@@ -1952,11 +1969,11 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store *
19521969
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_iterator_begin");
19531970
struct reftable_reflog_iterator *main_iter, *worktree_iter;
19541971

1955-
main_iter = reflog_iterator_for_stack(refs, refs->main_stack);
1956-
if (!refs->worktree_stack)
1972+
main_iter = reflog_iterator_for_stack(refs, refs->main_backend.stack);
1973+
if (!refs->worktree_backend.stack)
19571974
return &main_iter->base;
19581975

1959-
worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack);
1976+
worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_backend.stack);
19601977

19611978
return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base,
19621979
ref_iterator_select, NULL);
@@ -1995,7 +2012,7 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store,
19952012
{
19962013
struct reftable_ref_store *refs =
19972014
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse");
1998-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2015+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
19992016
struct reftable_log_record log = {0};
20002017
struct reftable_iterator it = {0};
20012018
int ret;
@@ -2035,7 +2052,7 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store,
20352052
{
20362053
struct reftable_ref_store *refs =
20372054
reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent");
2038-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2055+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
20392056
struct reftable_log_record *logs = NULL;
20402057
struct reftable_iterator it = {0};
20412058
size_t logs_alloc = 0, logs_nr = 0, i;
@@ -2084,7 +2101,7 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store,
20842101
{
20852102
struct reftable_ref_store *refs =
20862103
reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists");
2087-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2104+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
20882105
struct reftable_log_record log = {0};
20892106
struct reftable_iterator it = {0};
20902107
int ret;
@@ -2169,7 +2186,7 @@ static int reftable_be_create_reflog(struct ref_store *ref_store,
21692186
{
21702187
struct reftable_ref_store *refs =
21712188
reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_reflog");
2172-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2189+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
21732190
struct write_reflog_existence_arg arg = {
21742191
.refs = refs,
21752192
.stack = stack,
@@ -2243,7 +2260,7 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store,
22432260
{
22442261
struct reftable_ref_store *refs =
22452262
reftable_be_downcast(ref_store, REF_STORE_WRITE, "delete_reflog");
2246-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2263+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
22472264
struct write_reflog_delete_arg arg = {
22482265
.stack = stack,
22492266
.refname = refname,
@@ -2352,7 +2369,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store,
23522369
*/
23532370
struct reftable_ref_store *refs =
23542371
reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
2355-
struct reftable_stack *stack = stack_for(refs, refname, &refname);
2372+
struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack;
23562373
struct reftable_log_record *logs = NULL;
23572374
struct reftable_log_record *rewritten = NULL;
23582375
struct reftable_ref_record ref_record = {0};

0 commit comments

Comments
 (0)