From patchwork Mon Nov 25 07:38:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884469 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E837512EBEA for ; Mon, 25 Nov 2024 07:38:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520324; cv=none; b=UHqaPvGleIr7P4FAZ7/NLJXNKZu6auRCaZC+COfFbYKSS6/iJQ1tnYsPoQYKTxbwgqy2DbxXP5e4pE8vbL+j8nHoOG0E7ZfSVad/BQMUVXBIC3RpP1omm3fawxC1KRX1Ae9BWqR/IAPEVnXslYYlvCzXUj9DB6zzl6m6t2aqLRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520324; c=relaxed/simple; bh=vfHMikX1INr1cseP7T3+OU71oTW7AFMCBKLYLFGi3NY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dOHsbktEAdV3Xr7QHhTrmfqNv7a6yF+2PBtW0ix6E6CJgqD6VSAR7nX3h0ZKgcd/kDg8hapM+lmTfmTDJKhTVcG2HBtzsDptZd2M+dytIzx/zeBAxQOMlnRDW2L33Kj1wyHdfERAGYRw+e6L6d61QTx24PP/eq6kftVtYgEVs2o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=C7Q9wyp/; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=sWL3MBm9; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="C7Q9wyp/"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="sWL3MBm9" Received: from phl-compute-08.internal (phl-compute-08.phl.internal [10.202.2.48]) by mailfhigh.stl.internal (Postfix) with ESMTP id D3D822540175; Mon, 25 Nov 2024 02:38:40 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-08.internal (MEProxy); Mon, 25 Nov 2024 02:38:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520320; x=1732606720; bh=3Z+YJsHbLsKZXsjx3N4vjFXgL5wWcRDByWkCB8i1yF8=; b= C7Q9wyp/lVnqQU9cRM6RZxoWocXkqL+UKvPwyBxJWcn5Ek5vuIsGM3V/VuCWjsb5 L1oimdx5JRaL2b+SGSaGPHgwwpqDwZyckW7vw+AZj+8VZqTJwxKlKz7/qgRd+qFO 5At8YXNeGS141+gA8E/ib6QRtxvDQbCUZZxH4yR/+5v1QkfHwuiekISnC8MTnbWJ C8L7Qockv7FzAmu5M7qmjAiOEoQOtNs6+1RZdVRBuKaT/nnFFjtys8KeJvG9kmTT fpLmeRx/DewojuP8Medz/1AcqbeCUSzGmKfM0+4PsJm0GypFiNoiZmrK2AAvawyJ S0z2mjQ9AfyJhI/+qBKpcw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520320; x= 1732606720; bh=3Z+YJsHbLsKZXsjx3N4vjFXgL5wWcRDByWkCB8i1yF8=; b=s WL3MBm9FYLZJUthhvkWqdkxj6t9qNI8233pXf9s7kosak9sRvJoFy+6hw81e7s2F eBRfn6qDTukopavUB8HNJ9WxO/cLsCd/5BD25pk9WbbH0GnTMkraUFboRpHU3KoJ 982vvmHK62KrZNAnEQV7LyLh3+eFRucyNCMpw6nbmEBfuhwXmr+Kwpt0AvulDS92 EZacJmYRnIW0qjQNSNsft9QYRa0fa8joiVmF1CBS71wmdgB25VBnXROog7pldDzD owIHkzgbYJHnZzxWUZ4DCatWj8kmuPNfMa0IsiMGy5Qgh9eMUp6R/nKM3pblGU2k IKGZVCGMcioCUl2Y08cAA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhgpd hrtghpthhtohepghhithhsthgvrhesphhosghogidrtghomhdprhgtphhtthhopehkrghr thhhihhkrddukeeksehgmhgrihhlrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:39 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 9cd1b6f8 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:37 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:23 +0100 Subject: [PATCH v3 1/9] refs/reftable: encapsulate reftable stack Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-1-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 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 --- refs/reftable-backend.c | 135 +++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 59 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index f560bc2b67857d785294e6b5699383a256f30813..acd26f8928d18396f78a2d39ad0e0c1796d5a409 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -34,24 +34,41 @@ */ #define REF_UPDATE_VIA_HEAD (1 << 8) +struct reftable_backend { + struct reftable_stack *stack; +}; + +static int reftable_backend_init(struct reftable_backend *be, + const char *path, + const struct reftable_write_options *opts) +{ + return reftable_new_stack(&be->stack, path, opts); +} + +static void reftable_backend_release(struct reftable_backend *be) +{ + reftable_stack_destroy(be->stack); + be->stack = NULL; +} + struct reftable_ref_store { struct ref_store base; /* - * The main stack refers to the common dir and thus contains common + * The main backend refers to the common dir and thus contains common * refs as well as refs of the main repository. */ - struct reftable_stack *main_stack; + struct reftable_backend main_backend; /* - * The worktree stack refers to the gitdir in case the refdb is opened + * The worktree backend refers to the gitdir in case the refdb is opened * via a worktree. It thus contains the per-worktree refs. */ - struct reftable_stack *worktree_stack; + struct reftable_backend worktree_backend; /* - * Map of worktree stacks by their respective worktree names. The map + * Map of worktree backends by their respective worktree names. The map * is populated lazily when we try to resolve `worktrees/$worktree` refs. */ - struct strmap worktree_stacks; + struct strmap worktree_backends; struct reftable_write_options write_options; unsigned int store_flags; @@ -97,21 +114,21 @@ static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_sto * like `worktrees/$worktree/refs/heads/foo` as worktree stacks will store * those references in their normalized form. */ -static struct reftable_stack *stack_for(struct reftable_ref_store *store, - const char *refname, - const char **rewritten_ref) +static struct reftable_backend *backend_for(struct reftable_ref_store *store, + const char *refname, + const char **rewritten_ref) { const char *wtname; int wtname_len; if (!refname) - return store->main_stack; + return &store->main_backend; switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) { case REF_WORKTREE_OTHER: { static struct strbuf wtname_buf = STRBUF_INIT; struct strbuf wt_dir = STRBUF_INIT; - struct reftable_stack *stack; + struct reftable_backend *be; /* * 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, /* * There is an edge case here: when the worktree references the * current worktree, then we set up the stack once via - * `worktree_stacks` and once via `worktree_stack`. This is + * `worktree_backends` and once via `worktree_backend`. This is * wasteful, but in the reading case it shouldn't matter. And * in the writing case we would notice that the stack is locked * already and error out when trying to write a reference via * both stacks. */ - stack = strmap_get(&store->worktree_stacks, wtname_buf.buf); - if (!stack) { + be = strmap_get(&store->worktree_backends, wtname_buf.buf); + if (!be) { strbuf_addf(&wt_dir, "%s/worktrees/%s/reftable", store->base.repo->commondir, wtname_buf.buf); - store->err = reftable_new_stack(&stack, wt_dir.buf, - &store->write_options); + CALLOC_ARRAY(be, 1); + store->err = reftable_backend_init(be, wt_dir.buf, + &store->write_options); assert(store->err != REFTABLE_API_ERROR); - strmap_put(&store->worktree_stacks, wtname_buf.buf, stack); + + strmap_put(&store->worktree_backends, wtname_buf.buf, be); } strbuf_release(&wt_dir); - return stack; + return be; } case REF_WORKTREE_CURRENT: /* * If there is no worktree stack then we're currently in the * main worktree. We thus return the main stack in that case. */ - if (!store->worktree_stack) - return store->main_stack; - return store->worktree_stack; + if (!store->worktree_backend.stack) + return &store->main_backend; + return &store->worktree_backend; case REF_WORKTREE_MAIN: case REF_WORKTREE_SHARED: - return store->main_stack; + return &store->main_backend; default: BUG("unhandled worktree reference type"); } @@ -292,7 +311,7 @@ static struct ref_store *reftable_be_init(struct repository *repo, umask(mask); base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable); - strmap_init(&refs->worktree_stacks); + strmap_init(&refs->worktree_backends); refs->store_flags = store_flags; refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo); @@ -337,8 +356,8 @@ static struct ref_store *reftable_be_init(struct repository *repo, strbuf_realpath(&path, gitdir, 0); } strbuf_addstr(&path, "/reftable"); - refs->err = reftable_new_stack(&refs->main_stack, path.buf, - &refs->write_options); + refs->err = reftable_backend_init(&refs->main_backend, path.buf, + &refs->write_options); if (refs->err) goto done; @@ -354,8 +373,8 @@ static struct ref_store *reftable_be_init(struct repository *repo, strbuf_reset(&path); strbuf_addf(&path, "%s/reftable", gitdir); - refs->err = reftable_new_stack(&refs->worktree_stack, path.buf, - &refs->write_options); + refs->err = reftable_backend_init(&refs->worktree_backend, path.buf, + &refs->write_options); if (refs->err) goto done; } @@ -374,19 +393,17 @@ static void reftable_be_release(struct ref_store *ref_store) struct strmap_entry *entry; struct hashmap_iter iter; - if (refs->main_stack) { - reftable_stack_destroy(refs->main_stack); - refs->main_stack = NULL; - } + if (refs->main_backend.stack) + reftable_backend_release(&refs->main_backend); + if (refs->worktree_backend.stack) + reftable_backend_release(&refs->worktree_backend); - if (refs->worktree_stack) { - reftable_stack_destroy(refs->worktree_stack); - refs->worktree_stack = NULL; + strmap_for_each_entry(&refs->worktree_backends, &iter, entry) { + struct reftable_backend *be = entry->value; + reftable_backend_release(be); + free(be); } - - strmap_for_each_entry(&refs->worktree_stacks, &iter, entry) - reftable_stack_destroy(entry->value); - strmap_clear(&refs->worktree_stacks, 0); + strmap_clear(&refs->worktree_backends, 0); } static int reftable_be_create_on_disk(struct ref_store *ref_store, @@ -781,7 +798,7 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto required_flags |= REF_STORE_ODB; refs = reftable_be_downcast(ref_store, required_flags, "ref_iterator_begin"); - main_iter = ref_iterator_for_stack(refs, refs->main_stack, prefix, + main_iter = ref_iterator_for_stack(refs, refs->main_backend.stack, prefix, exclude_patterns, flags); /* @@ -789,14 +806,14 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto * right now. If we aren't, then we return the common reftable * iterator, only. */ - if (!refs->worktree_stack) + if (!refs->worktree_backend.stack) return &main_iter->base; /* * Otherwise we merge both the common and the per-worktree refs into a * single iterator. */ - worktree_iter = ref_iterator_for_stack(refs, refs->worktree_stack, prefix, + worktree_iter = ref_iterator_for_stack(refs, refs->worktree_backend.stack, prefix, exclude_patterns, flags); return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, ref_iterator_select, NULL); @@ -811,7 +828,7 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; int ret; if (refs->err < 0) @@ -838,7 +855,7 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_ref_record ref = {0}; int ret; @@ -898,7 +915,7 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, struct ref_update *update, struct strbuf *err) { - struct reftable_stack *stack = stack_for(refs, update->refname, NULL); + struct reftable_stack *stack = backend_for(refs, update->refname, NULL)->stack; struct write_transaction_table_arg *arg = NULL; size_t i; int ret; @@ -1031,7 +1048,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } - ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD", + ret = read_ref_without_reload(refs, backend_for(refs, "HEAD", NULL)->stack, "HEAD", &head_oid, &head_referent, &head_type); if (ret < 0) goto done; @@ -1043,7 +1060,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, struct reftable_stack *stack; const char *rewritten_ref; - stack = stack_for(refs, u->refname, &rewritten_ref); + stack = backend_for(refs, u->refname, &rewritten_ref)->stack; /* Verify that the new object ID is valid. */ 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, if (refs->err) return refs->err; - stack = refs->worktree_stack; + stack = refs->worktree_backend.stack; if (!stack) - stack = refs->main_stack; + stack = refs->main_backend.stack; if (opts->flags & PACK_REFS_AUTO) ret = reftable_stack_auto_compact(stack); @@ -1782,7 +1799,7 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref"); - struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname); + struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack; struct write_copy_arg arg = { .refs = refs, .stack = stack, @@ -1814,7 +1831,7 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref"); - struct reftable_stack *stack = stack_for(refs, newrefname, &newrefname); + struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack; struct write_copy_arg arg = { .refs = refs, .stack = stack, @@ -1952,11 +1969,11 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store * reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_iterator_begin"); struct reftable_reflog_iterator *main_iter, *worktree_iter; - main_iter = reflog_iterator_for_stack(refs, refs->main_stack); - if (!refs->worktree_stack) + main_iter = reflog_iterator_for_stack(refs, refs->main_backend.stack); + if (!refs->worktree_backend.stack) return &main_iter->base; - worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack); + worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_backend.stack); return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, ref_iterator_select, NULL); @@ -1995,7 +2012,7 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; int ret; @@ -2035,7 +2052,7 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record *logs = NULL; struct reftable_iterator it = {0}; size_t logs_alloc = 0, logs_nr = 0, i; @@ -2084,7 +2101,7 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; int ret; @@ -2169,7 +2186,7 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_reflog"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct write_reflog_existence_arg arg = { .refs = refs, .stack = stack, @@ -2243,7 +2260,7 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "delete_reflog"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct write_reflog_delete_arg arg = { .stack = stack, .refname = refname, @@ -2352,7 +2369,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, */ struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire"); - struct reftable_stack *stack = stack_for(refs, refname, &refname); + struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record *logs = NULL; struct reftable_log_record *rewritten = NULL; struct reftable_ref_record ref_record = {0}; From patchwork Mon Nov 25 07:38:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884470 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5107614375C for ; Mon, 25 Nov 2024 07:38:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520325; cv=none; b=DbZoUGbF+pLo5Lbz61ocKInp8A5B9oDG57oonwmSdGx4lrNzP0MfithIM+ahlVA87VU0evfLtG/SujnJ002RxaXHEM168sWFJ/s5SlmWmMRmd63mHuK97V+crwPWiJyQgdrRJk7Oeh22/+HXM/pHAoEUv0HpuAIfYlhZmJKftQA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520325; c=relaxed/simple; bh=djinglvGjGUjMyozJsNU9/ud5PlE+1+eTYZ4F9T7nKA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=InMgmGjSSr/hbjv9ZH7VSKMVF5mmKhF+WwY8cQfrjLGZqyBTajo1YY4+rN3FVqBUxfeQb+3VOfFQ6iKTcaP8rBMjSr3Ki4+9YTsKBfIo8kQgcNtAj4LkBeAGJVMdyJyKGNWFlyIZrZ3A/Uf/7rZILHF2DZN0x5/bDYV6LgrnQiA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=EaSZ4LVJ; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=IKtiZ2bz; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="EaSZ4LVJ"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="IKtiZ2bz" Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfhigh.stl.internal (Postfix) with ESMTP id 518182540118; Mon, 25 Nov 2024 02:38:42 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Mon, 25 Nov 2024 02:38:42 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520322; x=1732606722; bh=g0PLolSF2eKo9g5kXgNeG88ogXaZdr7ijAEaPkFBQqQ=; b= EaSZ4LVJasECZ47zNaZddqd4Mbx+xIdUlgUamiujWprX4aHdKKSf6aIfyeqbbMGb xY0uJ+1i89EleqlnHpsWSgdjAEyOPH6pN4YSVof0Fmd93MRyIJecPbd//Cewb0gy yQICrzAR8OwxUZ+kq+NPrmjX04WKq5JzU7FIUbi8deLBtX2P6EI5XUOwbMz8ieMb 7E5sMdhOY0f6uENSAox7QyJBZn96sQGX94mMWhmtQYq/YoAOum3BkAVfybkJIi68 fqnqEYkZp4jIDPYxA0w9c7H9eEcAa6Nopq13Uhtq9AdR+bl1jlSXMGJO1Y/qf5Fc rYJZJbt3uFu9Ebf1DUrCCQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520322; x= 1732606722; bh=g0PLolSF2eKo9g5kXgNeG88ogXaZdr7ijAEaPkFBQqQ=; b=I KtiZ2bzKjF7TnodEtB9jnO6BSZ5pUaCVXJQUT7FPkSMgUp+IUFqwJ5fmi3dglD/h C1vMdeGfQGWnqF6hTOu9q7reRpKiD74gBeOqgsmoRJP76YWd7uXPTMcUo4oEZ5io e51Ueob+2maRB82kT5PBYKF4XE5eAZ0S95zcqI9DLHI9iAFsCzbS2XOPCL7DgfCA PSl8KMwA48cTCbCIl4aVqt1SpQNS/kHYYwm79FIxbmvMYO0hYfuJqiRT3J4vU3Ql IGZt4r6zRl7XRDOsyDoVR+7e/EJDyDTOO/CxkLAYTVUsI4l73y0oWlD/BGSg0VpC ZZxD5uZnFXbtagcsreoIA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtshhtvghrsehpohgsohigrdgtohhmpdhrtg hpthhtohepghhithesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthhopehkrghr thhhihhkrddukeeksehgmhgrihhlrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:41 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 98ca0c99 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:38 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:24 +0100 Subject: [PATCH v3 2/9] refs/reftable: handle reloading stacks in the reftable backend Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-2-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 When accessing a stack we almost always have to reload the stack before reading data from it. This is mostly because Git does not have a notification mechanism for when underlying data has been changed, and thus we are forced to opportunistically reload the stack every single time to account for any changes that may have happened concurrently. Handle the reload internally in `backend_for()`. For one this forces callsites to think about whether or not they need to reload the stack. But second this makes the logic to access stacks more self-contained by letting the `struct reftable_backend` manage themselves. Update callsites where we don't reload the stack to document why we don't. In some cases it's unclear whether it is the right thing to do in the first place, but fixing that is outside of the scope of this patch series. Signed-off-by: Patrick Steinhardt --- refs/reftable-backend.c | 184 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 58 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index acd26f8928d18396f78a2d39ad0e0c1796d5a409..64fe8fd02d8ec932f7980cdb7d7d5223c3c83b73 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -114,21 +114,25 @@ static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_sto * like `worktrees/$worktree/refs/heads/foo` as worktree stacks will store * those references in their normalized form. */ -static struct reftable_backend *backend_for(struct reftable_ref_store *store, - const char *refname, - const char **rewritten_ref) +static int backend_for(struct reftable_backend **out, + struct reftable_ref_store *store, + const char *refname, + const char **rewritten_ref, + int reload) { + struct reftable_backend *be; const char *wtname; int wtname_len; - if (!refname) - return &store->main_backend; + if (!refname) { + be = &store->main_backend; + goto out; + } switch (parse_worktree_ref(refname, &wtname, &wtname_len, rewritten_ref)) { case REF_WORKTREE_OTHER: { static struct strbuf wtname_buf = STRBUF_INIT; struct strbuf wt_dir = STRBUF_INIT; - struct reftable_backend *be; /* * We're using a static buffer here so that we don't need to @@ -162,7 +166,7 @@ static struct reftable_backend *backend_for(struct reftable_ref_store *store, } strbuf_release(&wt_dir); - return be; + goto out; } case REF_WORKTREE_CURRENT: /* @@ -170,14 +174,27 @@ static struct reftable_backend *backend_for(struct reftable_ref_store *store, * main worktree. We thus return the main stack in that case. */ if (!store->worktree_backend.stack) - return &store->main_backend; - return &store->worktree_backend; + be = &store->main_backend; + else + be = &store->worktree_backend; + goto out; case REF_WORKTREE_MAIN: case REF_WORKTREE_SHARED: - return &store->main_backend; + be = &store->main_backend; + goto out; default: BUG("unhandled worktree reference type"); } + +out: + if (reload) { + int ret = reftable_stack_reload(be->stack); + if (ret) + return ret; + } + *out = be; + + return 0; } static int should_write_log(struct reftable_ref_store *refs, const char *refname) @@ -828,17 +845,17 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "read_raw_ref"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; + struct reftable_backend *be; int ret; if (refs->err < 0) return refs->err; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = read_ref_without_reload(refs, stack, refname, oid, referent, type); + ret = read_ref_without_reload(refs, be->stack, refname, oid, referent, type); if (ret < 0) return ret; if (ret > 0) { @@ -855,15 +872,15 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_ref_record ref = {0}; + struct reftable_backend *be; int ret; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = reftable_stack_read_ref(stack, refname, &ref); + ret = reftable_stack_read_ref(be->stack, refname, &ref); if (ret == 0 && ref.value_type == REFTABLE_REF_SYMREF) strbuf_addstr(referent, ref.value.symref); else @@ -880,7 +897,7 @@ struct reftable_transaction_update { struct write_transaction_table_arg { struct reftable_ref_store *refs; - struct reftable_stack *stack; + struct reftable_backend *be; struct reftable_addition *addition; struct reftable_transaction_update *updates; size_t updates_nr; @@ -915,27 +932,37 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, struct ref_update *update, struct strbuf *err) { - struct reftable_stack *stack = backend_for(refs, update->refname, NULL)->stack; struct write_transaction_table_arg *arg = NULL; + struct reftable_backend *be; size_t i; int ret; + /* + * This function gets called in a loop, and we don't want to repeatedly + * reload the stack for every single ref update. Instead, we manually + * reload further down in the case where we haven't yet prepared the + * specific `reftable_backend`. + */ + ret = backend_for(&be, refs, update->refname, NULL, 0); + if (ret) + return ret; + /* * Search for a preexisting stack update. If there is one then we add * the update to it, otherwise we set up a new stack update. */ for (i = 0; !arg && i < tx_data->args_nr; i++) - if (tx_data->args[i].stack == stack) + if (tx_data->args[i].be == be) arg = &tx_data->args[i]; if (!arg) { struct reftable_addition *addition; - ret = reftable_stack_reload(stack); + ret = reftable_stack_reload(be->stack); if (ret) return ret; - ret = reftable_stack_new_addition(&addition, stack, + ret = reftable_stack_new_addition(&addition, be->stack, REFTABLE_STACK_NEW_ADDITION_RELOAD); if (ret) { if (ret == REFTABLE_LOCK_ERROR) @@ -947,7 +974,7 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, tx_data->args_alloc); arg = &tx_data->args[tx_data->args_nr++]; arg->refs = refs; - arg->stack = stack; + arg->be = be; arg->addition = addition; arg->updates = NULL; arg->updates_nr = 0; @@ -1002,6 +1029,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, struct strbuf referent = STRBUF_INIT, head_referent = STRBUF_INIT; struct string_list affected_refnames = STRING_LIST_INIT_NODUP; struct reftable_transaction_data *tx_data = NULL; + struct reftable_backend *be; struct object_id head_oid; unsigned int head_type = 0; size_t i; @@ -1048,7 +1076,22 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } - ret = read_ref_without_reload(refs, backend_for(refs, "HEAD", NULL)->stack, "HEAD", + /* + * TODO: it's dubious whether we should reload the stack that "HEAD" + * belongs to or not. In theory, it may happen that we only modify + * stacks which are _not_ part of the "HEAD" stack. In that case we + * wouldn't have prepared any transaction for its stack and would not + * have reloaded it, which may mean that it is stale. + * + * On the other hand, reloading that stack without locking it feels + * wrong to, as the value of "HEAD" could be modified concurrently at + * any point in time. + */ + ret = backend_for(&be, refs, "HEAD", NULL, 0); + if (ret) + goto done; + + ret = read_ref_without_reload(refs, be->stack, "HEAD", &head_oid, &head_referent, &head_type); if (ret < 0) goto done; @@ -1057,10 +1100,18 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, for (i = 0; i < transaction->nr; i++) { struct ref_update *u = transaction->updates[i]; struct object_id current_oid = {0}; - struct reftable_stack *stack; const char *rewritten_ref; - stack = backend_for(refs, u->refname, &rewritten_ref)->stack; + /* + * There is no need to reload the respective backends here as + * we have already reloaded them when preparing the transaction + * update. And given that the stacks have been locked there + * shouldn't have been any concurrent modifications of the + * stack. + */ + ret = backend_for(&be, refs, u->refname, &rewritten_ref, 0); + if (ret) + goto done; /* Verify that the new object ID is valid. */ if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) && @@ -1116,7 +1167,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, string_list_insert(&affected_refnames, new_update->refname); } - ret = read_ref_without_reload(refs, stack, rewritten_ref, + ret = read_ref_without_reload(refs, be->stack, rewritten_ref, ¤t_oid, &referent, &u->type); if (ret < 0) goto done; @@ -1318,7 +1369,7 @@ static int transaction_update_cmp(const void *a, const void *b) static int write_transaction_table(struct reftable_writer *writer, void *cb_data) { struct write_transaction_table_arg *arg = cb_data; - uint64_t ts = reftable_stack_next_update_index(arg->stack); + uint64_t ts = reftable_stack_next_update_index(arg->be->stack); struct reftable_log_record *logs = NULL; struct ident_split committer_ident = {0}; size_t logs_nr = 0, logs_alloc = 0, i; @@ -1354,7 +1405,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; - ret = reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); if (ret < 0) goto done; @@ -1799,10 +1850,9 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref"); - struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack; + struct reftable_backend *be; struct write_copy_arg arg = { .refs = refs, - .stack = stack, .oldname = oldrefname, .newname = newrefname, .logmsg = logmsg, @@ -1814,10 +1864,11 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(stack, &write_copy_table, &arg); + arg.stack = be->stack; + ret = reftable_stack_add(be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); @@ -1831,10 +1882,9 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref"); - struct reftable_stack *stack = backend_for(refs, newrefname, &newrefname)->stack; + struct reftable_backend *be; struct write_copy_arg arg = { .refs = refs, - .stack = stack, .oldname = oldrefname, .newname = newrefname, .logmsg = logmsg, @@ -1845,10 +1895,11 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(stack, &write_copy_table, &arg); + arg.stack = be->stack; + ret = reftable_stack_add(be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); @@ -2012,15 +2063,23 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent_reverse"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; + struct reftable_backend *be; int ret; if (refs->err < 0) return refs->err; - ret = reftable_stack_init_log_iterator(stack, &it); + /* + * TODO: we should adapt this callsite to reload the stack. There is no + * obvious reason why we shouldn't. + */ + ret = backend_for(&be, refs, refname, &refname, 0); + if (ret) + goto done; + + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2052,16 +2111,24 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "for_each_reflog_ent"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record *logs = NULL; struct reftable_iterator it = {0}; + struct reftable_backend *be; size_t logs_alloc = 0, logs_nr = 0, i; int ret; if (refs->err < 0) return refs->err; - ret = reftable_stack_init_log_iterator(stack, &it); + /* + * TODO: we should adapt this callsite to reload the stack. There is no + * obvious reason why we shouldn't. + */ + ret = backend_for(&be, refs, refname, &refname, 0); + if (ret) + goto done; + + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2101,20 +2168,20 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "reflog_exists"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; + struct reftable_backend *be; int ret; ret = refs->err; if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret < 0) goto done; - ret = reftable_stack_init_log_iterator(stack, &it); + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2186,10 +2253,9 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "create_reflog"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; + struct reftable_backend *be; struct write_reflog_existence_arg arg = { .refs = refs, - .stack = stack, .refname = refname, }; int ret; @@ -2198,11 +2264,12 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) goto done; + arg.stack = be->stack; - ret = reftable_stack_add(stack, &write_reflog_existence_table, &arg); + ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg); done: return ret; @@ -2260,17 +2327,18 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "delete_reflog"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; + struct reftable_backend *be; struct write_reflog_delete_arg arg = { - .stack = stack, .refname = refname, }; int ret; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = reftable_stack_add(stack, &write_reflog_delete_table, &arg); + arg.stack = be->stack; + + ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg); assert(ret != REFTABLE_API_ERROR); return ret; @@ -2369,13 +2437,13 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, */ struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire"); - struct reftable_stack *stack = backend_for(refs, refname, &refname)->stack; struct reftable_log_record *logs = NULL; struct reftable_log_record *rewritten = NULL; struct reftable_ref_record ref_record = {0}; struct reftable_iterator it = {0}; struct reftable_addition *add = NULL; struct reflog_expiry_arg arg = {0}; + struct reftable_backend *be; struct object_id oid = {0}; uint8_t *last_hash = NULL; size_t logs_nr = 0, logs_alloc = 0, i; @@ -2384,11 +2452,11 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (refs->err < 0) return refs->err; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret < 0) goto done; - ret = reftable_stack_init_log_iterator(stack, &it); + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2396,11 +2464,11 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_new_addition(&add, stack, 0); + ret = reftable_stack_new_addition(&add, be->stack, 0); if (ret < 0) goto done; - ret = reftable_stack_read_ref(stack, refname, &ref_record); + ret = reftable_stack_read_ref(be->stack, refname, &ref_record); if (ret < 0) goto done; if (reftable_ref_record_val1(&ref_record)) @@ -2479,8 +2547,8 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, arg.refs = refs; arg.records = rewritten; arg.len = logs_nr; - arg.stack = stack, - arg.refname = refname, + arg.stack = be->stack; + arg.refname = refname; ret = reftable_addition_add(add, &write_reflog_expiry_table, &arg); if (ret < 0) From patchwork Mon Nov 25 07:38:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884471 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59E9F156962 for ; Mon, 25 Nov 2024 07:38:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520326; cv=none; b=gChDl8pxyxUkIGgiLy0e932aGYIUbUbObj4UgNPIK59zXwH8K/si/kZY7AR/g9d0lwumMzAKNd3EqVASil0743/fkJWKvmjlSHNzuPUm0wQOcBwUVcWlfG14GDRWLUzU1k9Ljl6Q4zdYHsCXXYBhnulYIUmtEgzAY9QjRIkAxa4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520326; c=relaxed/simple; bh=2Rm9xcvrSTgwGXx8aCNJwTScZvlM08EuxhXBA5XDbkM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gx+9oYCXysVA/SaDdMUcYWFMXg3qNN6rGzHJP+/v9wtxGyKOPdBSQ2aRjE76HuOczHyMk198EIMEP61jES/gxbe9oEvs2WGbabcCvO+hgvBrjYnOX23f8ONEhTE16cEIQ9n3UWUqQFyPEU+EYuFnhYDmI6u/n/uk5wOnkoz5+Kw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=NRg4EXd6; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=4aaB+exU; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="NRg4EXd6"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="4aaB+exU" Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfhigh.stl.internal (Postfix) with ESMTP id B21FE254014F; Mon, 25 Nov 2024 02:38:43 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Mon, 25 Nov 2024 02:38:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520323; x=1732606723; bh=ivSZWOWOqQv1UUtMjhF6dBS6AMIjSLXOF5mg/ipOg2k=; b= NRg4EXd6iv8BBEJvZM5FiOoim7OEQV0SoqRgkEV3JBnR17OHrbZNrVrCCfGDy0F+ AbHxiyXIq2yvl9syiyyJq04pKVIFI0ML4Z3GVA5L2+0i8VyK4kN0r+6UwbvWlv8S wFAMdZ8yLI44MjuucdpdBuQaQst298tNZmMVgeFC7a5PUKQuu1j3C27HL7XO9lgx LHJO84vTzcemkEeJ7/eFdpxNHpdp4U6mUxmZHUPeg8GodUm8/qMGsUtVWPDaftsZ UsFJT4d++PdNwMz0N8QJ/ZFz+H7uISZA1O7xOCK71ND1/XgRQ0b1Gbg8Tdd+eCwy BWb3X2POYtpYBL8w8AFtZw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520323; x= 1732606723; bh=ivSZWOWOqQv1UUtMjhF6dBS6AMIjSLXOF5mg/ipOg2k=; b=4 aaB+exU02hJC9v/xFEY5vP9E9Iiv09UHSB7WJ/jZO78VxXnJh9TbmuLIrU5Piyky dhpMVeZlB7e0V/MNsEfEXPObrnpFSwmUDetZP0oj6bJtmowcgi0L0YHFF/US9RFg U/eyEJqE3gz6UuXzy60BJ6WqD5rlNQcgD/nywFbD2dqXFpas4RAT68HfJtM2Ie36 DVElNT0CF/aYHrKXucyEwRHJS0csK2+eswyKEEfrvQeT8YJlZ7OBF+wJkxBdTt5Z J81wBHNTCbGwmzE1X7/YObRZ4UN4NcgypHRpGbH8UYjQCAgywsy0uwCNcNhkkIfp SNhLP55BpwhExX0pn+KAA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtshhtvghrsehpohgsohigrdgtohhmpdhrtg hpthhtohepkhgrrhhthhhikhdrudekkeesghhmrghilhdrtghomhdprhgtphhtthhopehg ihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhg X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:42 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id cc2b93ca (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:39 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:25 +0100 Subject: [PATCH v3 3/9] reftable/stack: add accessor for the hash ID Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-3-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 Add an accessor function that allows callers to access the hash ID of a reftable stack. This function will be used in a subsequent commit. Signed-off-by: Patrick Steinhardt --- reftable/reftable-stack.h | 3 +++ reftable/stack.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h index 54787f2ef530406a7970db058c3a0cf456897978..ae14270ea74108cd4c314ec38e7d5c9a4e731481 100644 --- a/reftable/reftable-stack.h +++ b/reftable/reftable-stack.h @@ -149,4 +149,7 @@ struct reftable_compaction_stats { struct reftable_compaction_stats * reftable_stack_compaction_stats(struct reftable_stack *st); +/* Return the hash of the stack. */ +enum reftable_hash reftable_stack_hash_id(struct reftable_stack *st); + #endif diff --git a/reftable/stack.c b/reftable/stack.c index 1fffd75630266c0d3d1e4a2d037b5cf90455529d..d97b64a40d4ad05cfd9e6f33e8ba1e713281ef6d 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -1791,3 +1791,8 @@ int reftable_stack_clean(struct reftable_stack *st) reftable_addition_destroy(add); return err; } + +enum reftable_hash reftable_stack_hash_id(struct reftable_stack *st) +{ + return reftable_merged_table_hash_id(st->merged); +} From patchwork Mon Nov 25 07:38:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884472 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 051EB12EBEA for ; Mon, 25 Nov 2024 07:38:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520327; cv=none; b=RKgnQCwQOo90p091+9CBkd9SFODt4rGjgB8pFEqP4K1JWL6G4p+dJz/5pQhGYXPmSMp+eFSqSVaGiuMvhVBxUTG1QpHquRqkMk/e5Zznn92Q4lKSUR3fXW6QU4IilRo0LgfhI6LsZOTvJtO0hm/+0F0E2/krB0Etsd2uLtvf6yk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520327; c=relaxed/simple; bh=rx8Zo1xiQZb7rRA9FLLTpIPA2wLrlSUPMetrQV/Ikls=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RYDcUw/Ej+ZCKlO1gf+qXSo8fAIEzOlRCS48GmQnDDdOjyS29Pds8kI3bvEvBRatGz2YpgHja5oMh5rCEtEDATHGYXtsXx3xICzVcYYh0VChOZCzdk2kw31msoKQAyYb10+T4R2xVNLxGhXditRRZUkJvMdfzcEXb68G9SJNMpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=Ne5IbyUQ; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=A/t+E1fp; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="Ne5IbyUQ"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="A/t+E1fp" Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 18F671140155; Mon, 25 Nov 2024 02:38:45 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Mon, 25 Nov 2024 02:38:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520324; x=1732606724; bh=OLA5H9133sZlQstEH4+LOJYQjs8G6WHWYCl8wFlpn3Q=; b= Ne5IbyUQXjf+xJb7z6FltOUT4dxwWPVzm80g8j60pOHbBOFBVDmVJ4WybaOVg6Ww ViZEA3ylwAEvjECzg9XNttUQappng1hS7ucm3eRtWsag7aS3bF/Z7t+8mPyb9FiA ed0iMlL5stO/84qWuOJKEGA+3H0KdjeDYXLlAut/nlr63RrAVADvajpLTvmicKzl VfuXOqAtmMwaOyF2riIYCoF7uJs20u+F8aWOpwJvUfjqRygjY6PpTlG1r6boBuuf aTFzS1pI/q0YIQhUKR0jmJAgM3kL15WDHj9HWEfBxbnRmEkiEO6onO3d7R9Cfbsk w4fPZRWRuda+JEbO38bkSQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520324; x= 1732606724; bh=OLA5H9133sZlQstEH4+LOJYQjs8G6WHWYCl8wFlpn3Q=; b=A /t+E1fpqUDuOLlXcPsmWN3aOFYjGNbQu0QScMFgJu6HgBfIWwjDTExK1IoEopDQa /rFwUc5D8NWiCd0G3sVA30pECzm1KMbs+gtItRgi/PKHqjXP8vE4ISKrmTPmRG/p vcJvuAcz8Jtk8KcEwyApZDY0aJve72rWL0b1Re9V+m7Dfyb90LbiwpsWMquDi8wZ oLS0/vPrbpduD34uVMZFdsTiHnVaqV924NrNWD36Z+4naWE0XlrBWFBPSDOmk0NN X0zhrZ6KB7e6lL3WbkgCN+BNJrRzb04Njr28qfiVyjBqKYym7wDNQfUpKXFvHNWp jrRvO/fXHGmW02S8b9rAg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpefhfeeiveffudfhjedvveffhfdukefhvdekveevgeeu ieetteevgeelgffhvedtgfenucffohhmrghinhepuhhpuggrthgvrdhtiienucevlhhush htvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm pdhnsggprhgtphhtthhopeefpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehgih htshhtvghrsehpohgsohigrdgtohhmpdhrtghpthhtohepghhithesvhhgvghrrdhkvghr nhgvlhdrohhrghdprhgtphhtthhopehkrghrthhhihhkrddukeeksehgmhgrihhlrdgtoh hm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:43 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 632cbfa8 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:40 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:26 +0100 Subject: [PATCH v3 4/9] refs/reftable: read references via `struct reftable_backend` Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-4-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 Refactor `read_ref_without_reload()` to accept a `struct reftable_stack` as input instead of accepting a `struct reftable_stack`. This allows us to implement an additional caching layer when reading refs where we can reuse reftable iterators. Signed-off-by: Patrick Steinhardt --- refs/reftable-backend.c | 110 ++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 64fe8fd02d8ec932f7980cdb7d7d5223c3c83b73..5933c561f5c422d12b616514ed76b75c52a13477 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -51,6 +51,50 @@ static void reftable_backend_release(struct reftable_backend *be) be->stack = NULL; } +static int reftable_backend_read_ref(struct reftable_backend *be, + const char *refname, + struct object_id *oid, + struct strbuf *referent, + unsigned int *type) +{ + struct reftable_ref_record ref = {0}; + int ret; + + ret = reftable_stack_read_ref(be->stack, refname, &ref); + if (ret) + goto done; + + if (ref.value_type == REFTABLE_REF_SYMREF) { + strbuf_reset(referent); + strbuf_addstr(referent, ref.value.symref); + *type |= REF_ISSYMREF; + } else if (reftable_ref_record_val1(&ref)) { + unsigned int hash_id; + + switch (reftable_stack_hash_id(be->stack)) { + case REFTABLE_HASH_SHA1: + hash_id = GIT_HASH_SHA1; + break; + case REFTABLE_HASH_SHA256: + hash_id = GIT_HASH_SHA256; + break; + default: + BUG("unhandled hash ID %d", reftable_stack_hash_id(be->stack)); + } + + oidread(oid, reftable_ref_record_val1(&ref), + &hash_algos[hash_id]); + } else { + /* We got a tombstone, which should not happen. */ + BUG("unhandled reference value type %d", ref.value_type); + } + +done: + assert(ret != REFTABLE_API_ERROR); + reftable_ref_record_release(&ref); + return ret; +} + struct reftable_ref_store { struct ref_store base; @@ -243,38 +287,6 @@ static void fill_reftable_log_record(struct reftable_log_record *log, const stru log->value.update.tz_offset = sign * atoi(tz_begin); } -static int read_ref_without_reload(struct reftable_ref_store *refs, - struct reftable_stack *stack, - const char *refname, - struct object_id *oid, - struct strbuf *referent, - unsigned int *type) -{ - struct reftable_ref_record ref = {0}; - int ret; - - ret = reftable_stack_read_ref(stack, refname, &ref); - if (ret) - goto done; - - if (ref.value_type == REFTABLE_REF_SYMREF) { - strbuf_reset(referent); - strbuf_addstr(referent, ref.value.symref); - *type |= REF_ISSYMREF; - } else if (reftable_ref_record_val1(&ref)) { - oidread(oid, reftable_ref_record_val1(&ref), - refs->base.repo->hash_algo); - } else { - /* We got a tombstone, which should not happen. */ - BUG("unhandled reference value type %d", ref.value_type); - } - -done: - assert(ret != REFTABLE_API_ERROR); - reftable_ref_record_release(&ref); - return ret; -} - static int reftable_be_config(const char *var, const char *value, const struct config_context *ctx, void *_opts) @@ -855,7 +867,7 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store, if (ret) return ret; - ret = read_ref_without_reload(refs, be->stack, refname, oid, referent, type); + ret = reftable_backend_read_ref(be, refname, oid, referent, type); if (ret < 0) return ret; if (ret > 0) { @@ -1091,8 +1103,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, if (ret) goto done; - ret = read_ref_without_reload(refs, be->stack, "HEAD", - &head_oid, &head_referent, &head_type); + ret = reftable_backend_read_ref(be, "HEAD", &head_oid, + &head_referent, &head_type); if (ret < 0) goto done; ret = 0; @@ -1167,8 +1179,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, string_list_insert(&affected_refnames, new_update->refname); } - ret = read_ref_without_reload(refs, be->stack, rewritten_ref, - ¤t_oid, &referent, &u->type); + ret = reftable_backend_read_ref(be, rewritten_ref, + ¤t_oid, &referent, &u->type); if (ret < 0) goto done; if (ret > 0 && !ref_update_expects_existing_old_ref(u)) { @@ -1626,7 +1638,7 @@ struct write_create_symref_arg { struct write_copy_arg { struct reftable_ref_store *refs; - struct reftable_stack *stack; + struct reftable_backend *be; const char *oldname; const char *newname; const char *logmsg; @@ -1651,7 +1663,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) if (split_ident_line(&committer_ident, committer_info, strlen(committer_info))) BUG("failed splitting committer info"); - if (reftable_stack_read_ref(arg->stack, arg->oldname, &old_ref)) { + if (reftable_stack_read_ref(arg->be->stack, arg->oldname, &old_ref)) { ret = error(_("refname %s not found"), arg->oldname); goto done; } @@ -1690,7 +1702,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) * the old branch and the creation of the new branch, and we cannot do * two changes to a reflog in a single update. */ - deletion_ts = creation_ts = reftable_stack_next_update_index(arg->stack); + deletion_ts = creation_ts = reftable_stack_next_update_index(arg->be->stack); if (arg->delete_old) creation_ts++; reftable_writer_set_limits(writer, deletion_ts, creation_ts); @@ -1733,8 +1745,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ); logs_nr++; - ret = read_ref_without_reload(arg->refs, arg->stack, "HEAD", &head_oid, - &head_referent, &head_type); + ret = reftable_backend_read_ref(arg->be, "HEAD", &head_oid, + &head_referent, &head_type); if (ret < 0) goto done; append_head_reflog = (head_type & REF_ISSYMREF) && !strcmp(head_referent.buf, arg->oldname); @@ -1777,7 +1789,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) * copy over all log entries from the old reflog. Last but not least, * when renaming we also have to delete all the old reflog entries. */ - ret = reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); if (ret < 0) goto done; @@ -1850,7 +1862,6 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "rename_ref"); - struct reftable_backend *be; struct write_copy_arg arg = { .refs = refs, .oldname = oldrefname, @@ -1864,11 +1875,10 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = backend_for(&be, refs, newrefname, &newrefname, 1); + ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - arg.stack = be->stack; - ret = reftable_stack_add(be->stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); @@ -1882,7 +1892,6 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_WRITE, "copy_ref"); - struct reftable_backend *be; struct write_copy_arg arg = { .refs = refs, .oldname = oldrefname, @@ -1895,11 +1904,10 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = backend_for(&be, refs, newrefname, &newrefname, 1); + ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - arg.stack = be->stack; - ret = reftable_stack_add(be->stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); From patchwork Mon Nov 25 07:38:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884473 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34AD8188724 for ; Mon, 25 Nov 2024 07:38:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520328; cv=none; b=gcm85q9zVjxAqW+tCIXPzC3jmBFh9F8PxjODbmuispqNiPgeYhcAiLTmfMa5MlhwedR5EEefHr/T0ztRgegouCoj8UWGXGGNv3E37YjnPeKA/8lkEYjOukDgJJSbCNw+etcuJYBoLSaoejDJGMrzz9ZN8phddOD/9hxs92KEupw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520328; c=relaxed/simple; bh=dzTZYbdXfJGgPC2+q9cfMPJ2sp3jfoAoXkQFEecljJ0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C6h8IpJ4YNtv2Tr3PPPCWw1Gje/yXz9rAdkfjGXKZrFbr5K1hfpi23SiboocZ0FqLbNDalSH0xzixoW4gft65j0hdo2qAv+fiGtwLfZJ8XyQ84k2qmsr8/eQYAHB2DozlXQv8B1ALyHeeXg393cLeUP7Uf50X0ak7OgtecngAOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ctGDTrMi; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=OlO2vDIJ; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ctGDTrMi"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="OlO2vDIJ" Received: from phl-compute-08.internal (phl-compute-08.phl.internal [10.202.2.48]) by mailfhigh.stl.internal (Postfix) with ESMTP id 792022540118; Mon, 25 Nov 2024 02:38:46 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-08.internal (MEProxy); Mon, 25 Nov 2024 02:38:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520326; x=1732606726; bh=qqxcr8+HTD+Uw1FqkzOn5QuDehXNhSEgv282g9j9V3g=; b= ctGDTrMijuGzP66W+D6t9rdhWjtfdK8RDCVy6Etg1w4DYr/VQ92L5Bay9VcADXqL CnKp3BMnPBEv8IyLy4wCL9pkHgcOecxKyzF9ITOV26Hn4NuBfibUvmegFhaRwlNc 2fm6sjeLsdr9+xpIsxtrVD9EuZ/lsxAdhMRz0OvAcy35kirwzeXNwshm/0TkmqwT N/2Rwj+NGyKLeL+HMs7UNacPRZCXZ/ru2ogSEVIHgAFzYB24bRc+E8M5kGlQxGzU M5ARNSKcFwCYfODchgwtFT+ln1UC0/O69WphPeqtS4rY6ippNadLIgNvViytNEPP jm9mZUDBRoZmjTejPW5VvA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520326; x= 1732606726; bh=qqxcr8+HTD+Uw1FqkzOn5QuDehXNhSEgv282g9j9V3g=; b=O lO2vDIJlvcJiKjQTeFXIZnDVwJge7RuT30VRmE7BheNQ0/QObDJi/aOAj8Looow3 ONAsJrYEafwDiTPsepMBtHqFwRoZXTbJwNKCV3STtDBsy3nbpaliGlaj4UZ3F/F5 I3dG5bAUkeHE4ZTNPLMQeBarKatMFc3IEyr6twpX6g6a9VNi4Pb81KluRpIMMM3k b4UCGJAwsfMgZOcEUFityb0Bx6H91vsCRqkqhGfpZah6SqONoOZYGfY6Gaj2pZ0n ZOf5Zim2azT6kdThzS4qaPe2yOBNcXv44GODS7YVyew4Rw3EkwIKyGzJwvYmj7Sh 04XGfUnivrMqhVWwEaHGQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehkrghrthhhihhkrddukeeksehgmhgrihhlrdgtoh hmpdhrtghpthhtohepghhithesvhhgvghrrdhkvghrnhgvlhdrohhrghdprhgtphhtthho pehgihhtshhtvghrsehpohgsohigrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:45 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 01a4f567 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:41 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:27 +0100 Subject: [PATCH v3 5/9] refs/reftable: refactor reading symbolic refs to use reftable backend Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-5-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 Refactor the callback function that reads symbolic references in the reftable backend to use `reftable_backend_read_ref()` instead of accessing the reftable stack directly. This ensures that the function will benefit from the new caching layer that we're about to introduce. Signed-off-by: Patrick Steinhardt --- refs/reftable-backend.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 5933c561f5c422d12b616514ed76b75c52a13477..498bc9f932673e6089bd3b27e1bb7ed8d0e36a4c 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -884,21 +884,18 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, { struct reftable_ref_store *refs = reftable_be_downcast(ref_store, REF_STORE_READ, "read_symbolic_ref"); - struct reftable_ref_record ref = {0}; struct reftable_backend *be; + struct object_id oid; + unsigned int type = 0; int ret; ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = reftable_stack_read_ref(be->stack, refname, &ref); - if (ret == 0 && ref.value_type == REFTABLE_REF_SYMREF) - strbuf_addstr(referent, ref.value.symref); - else + ret = reftable_backend_read_ref(be, refname, &oid, referent, &type); + if (type != REF_ISSYMREF) ret = -1; - - reftable_ref_record_release(&ref); return ret; } From patchwork Mon Nov 25 07:38:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884474 Received: from fhigh-b4-smtp.messagingengine.com (fhigh-b4-smtp.messagingengine.com [202.12.124.155]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6BA6188CCA for ; Mon, 25 Nov 2024 07:38:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.155 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520330; cv=none; b=FDO3Dfputzx5VOcD65mYxilNiWST//wLd9v5uSIGoli2klBJnkcW8YzqWo09bC7Rvj7dljioSKngPig9gHqrG9sQYoQclQWYcMZdCWt8eYy9PU64rNXzL6MOuPPvGEPUOsxpQQFWn1j1sRdbTEVh5jP09iNIc+dTJCKO51enfE0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520330; c=relaxed/simple; bh=M6aJcj4kFvfAsTo0npLzgkF8AJ5eOitwn3rM2JHssdk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u43C1NBFOuS8NWbtY6ZJKSV+ZstYJf4TZJjcpGxBZSmdmfDp9NZT3wdySUvXPFxDqQMEphojNXi/Wp3rsMWQ96nAEQBMg04ibXmHiSFKe6ZZNFJsZVSdGlJrtNuMDWBAP1Fac3J0O7P5u0eUTxR3k36yJj7oP3J+FJcJiy5av/w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=V+48pYiq; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=jBQS/v8E; arc=none smtp.client-ip=202.12.124.155 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="V+48pYiq"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="jBQS/v8E" Received: from phl-compute-04.internal (phl-compute-04.phl.internal [10.202.2.44]) by mailfhigh.stl.internal (Postfix) with ESMTP id 041332540175; Mon, 25 Nov 2024 02:38:47 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-04.internal (MEProxy); Mon, 25 Nov 2024 02:38:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520327; x=1732606727; bh=WiGssL56dwrzpnEExMIP/xfZluIHa7DItOGEEB9CE24=; b= V+48pYiq5nruBhtwH1TK8AEKsmukONyvs4gESsqX44sPWbi41eMTRBXSVRyFn4kB QLbMe02ySHOX2SeZsJ9gxVVZ9c7bJ40/sowclhgPDiOBYCVkNgsw6Nq4GYaTSHNP SmU/DcNaW8o6XpsEYjwDgw0zSIV+DueNjgQ/OowqpjZ+fqdOGGKeTAYPKTZQlEuV ZDaFMLUhVmfoL8jw1qjLaMtC/j7AtAhpabx8/Od4yACgegSJc1ZbirMrgFyCwhzz xO4NbVgQxJukKmm9Xc6ZYnYwNvtMfB/EdT3fbB6d8SY8YcK+jOAe4Clc1Ol/iHCR KDh3cviqQjHsWTN/I/JB3w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520327; x= 1732606727; bh=WiGssL56dwrzpnEExMIP/xfZluIHa7DItOGEEB9CE24=; b=j BQS/v8Ec7rgj+hm+uqsSCXHIJhRk0TRwblVn/njp4rDfi5LBfi2q//fRYCrAP+Xa u1UsLgZpM7qFS72ul+i/7ZKnq9VX2leg0+u7FTb62GcQIFUXFr2xioCc0suJNq/F F6+jz+S3bnaw0W6l3shCkaPR8l6arLC7fYQbS/eJEc3E6DBJ0YZ1V0RaRBg5qq2c sO/osjP5zV6k4rO12UW66whT4gRx/qdYIg2wpBJapBwZT5FLVVQMGlvkOabdeVWq i0cD/DlGEjkdQvAUiT9zzd50o7iZIpQNQzJM8kjrIa2DryGPM1/LOK0gizyANyi+ lE1xkfw19Jto8dbzyCCNA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhgpd hrtghpthhtohepkhgrrhhthhhikhdrudekkeesghhmrghilhdrtghomhdprhgtphhtthho pehgihhtshhtvghrsehpohgsohigrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:46 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 6c9b69f6 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:42 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:28 +0100 Subject: [PATCH v3 6/9] refs/reftable: refactor reflog expiry to use reftable backend Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-6-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 Refactor the callback function that expires reflog entries in the reftable backend to use `reftable_backend_read_ref()` instead of accessing the reftable stack directly. This ensures that the function will benefit from the new caching layer that we're about to introduce. Signed-off-by: Patrick Steinhardt --- refs/reftable-backend.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 498bc9f932673e6089bd3b27e1bb7ed8d0e36a4c..ff49c27a6a0f4cb1e5b3bfaa3d34d3302c1bdb2e 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -2444,14 +2444,15 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, reftable_be_downcast(ref_store, REF_STORE_WRITE, "reflog_expire"); struct reftable_log_record *logs = NULL; struct reftable_log_record *rewritten = NULL; - struct reftable_ref_record ref_record = {0}; struct reftable_iterator it = {0}; struct reftable_addition *add = NULL; struct reflog_expiry_arg arg = {0}; struct reftable_backend *be; struct object_id oid = {0}; + struct strbuf referent = STRBUF_INIT; uint8_t *last_hash = NULL; size_t logs_nr = 0, logs_alloc = 0, i; + unsigned int type = 0; int ret; if (refs->err < 0) @@ -2473,12 +2474,9 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_read_ref(be->stack, refname, &ref_record); + ret = reftable_backend_read_ref(be, refname, &oid, &referent, &type); if (ret < 0) goto done; - if (reftable_ref_record_val1(&ref_record)) - oidread(&oid, reftable_ref_record_val1(&ref_record), - ref_store->repo->hash_algo); prepare_fn(refname, &oid, policy_cb_data); while (1) { @@ -2545,8 +2543,7 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, } } - if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && - reftable_ref_record_val1(&ref_record)) + if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && !is_null_oid(&oid)) oidread(&arg.update_oid, last_hash, ref_store->repo->hash_algo); arg.refs = refs; @@ -2571,11 +2568,11 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, cleanup_fn(policy_cb_data); assert(ret != REFTABLE_API_ERROR); - reftable_ref_record_release(&ref_record); reftable_iterator_destroy(&it); reftable_addition_destroy(add); for (i = 0; i < logs_nr; i++) reftable_log_record_release(&logs[i]); + strbuf_release(&referent); free(logs); free(rewritten); return ret; From patchwork Mon Nov 25 07:38:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884475 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4550F18A6C1 for ; Mon, 25 Nov 2024 07:38:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520331; cv=none; b=tB34np1ftRT0xKq3t/FL9P1B9q/yTLkp1LRyjS9iyY5B73XTwJz4qrbmauLzqydi72W1k63+bJxyuqKDHRN4vWtaQKYzVygxYdlgYck1+DKEYq1pYOantLkSS2Tw8qQVD7Udm3TBt0nmnjzAnejkfar3C3uYtUitaoehlMk9bHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520331; c=relaxed/simple; bh=98VJGSXFesCywwiZLYL7xEMrsR8kF0GOkWH7oksUGIk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=alm29nmnaAcZ/VhF9yWNL0UXV64UAz35PcG8fB8DzCyJKtxS3V21tHF9wE3kcq2ZxZVAvzRjTWxKs/WhIOdsJ/3ulAnCxMEngUkfoXA5+KfHf2/F7cf8DD8OYmBwymaZ9k/LRepol93rUHX3qZdD0GpUF9FyHxNMnwrSqT6uI5U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=CgN5kRc/; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Ht393JSP; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="CgN5kRc/"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Ht393JSP" Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 726BC1140166; Mon, 25 Nov 2024 02:38:49 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Mon, 25 Nov 2024 02:38:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520329; x=1732606729; bh=DY2czddyHJeCOFmz4pgFQLiMfzW0D9GHX2fXky+hNjw=; b= CgN5kRc/TQxA1nM602IGpZ69SHRaVV5BiRR79DR9u195Y59AyIO5d7Sejva+aiY9 nKrdB2etmQvDV0kDVM2zpU9B54dlCeISVKejV0GtOWiCxUuF1xWRHI35Hsisw220 m1zt2YCrjkziLXiePH1N06a8Hxo6n4PPu5POc/QV4YoGMbkjTtE3I/3a53deA+Qy 6nzBDvjlc0RNjmEAdkrv9Xr0ss/x/FYUEuf75A4/GFyxXgx/BdPy+MWM0N1wvVSC EKn7jS2Fa0rBisAZvgrQYPjY08jgBgQkm5qT2Dx3DCDVS8DBvqoT+Wt9VEFLaEZz 2JFqJ4rvB5Pb4sKvCJHMTw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520329; x= 1732606729; bh=DY2czddyHJeCOFmz4pgFQLiMfzW0D9GHX2fXky+hNjw=; b=H t393JSP1p8Hmy99FuMsR0342KTJRZnNl+r5nCFqPTnAHv3frrBV/CBlJoBUuSTIv 1syXLSfNLjxHKrnjRLGMISUpgywTQ3bDKH5nWPnZ/p+9/45ep6TK0vbph4jd2sY6 GFDqf78MHbsQ17EkX5Kkq3pUFrv8xb2A7Yg/g+eyAkdXvPEZtCNp6WzjTaUiWBH+ rrgGCUivL6XzE1dsbx/a9TQ8OuKnYmw56oRIV2uoEDsyu3JQkiZmez0I1O2iZla8 u63ZlKuykamuCMjUbZ7GFGqr2777nsdOW2mxQWFkVFQioGbHSThIxSgkKrT8rdNv ddyp1Zj9ZFZi7ReKCUjyg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtshhtvghrsehpohgsohigrdgtohhmpdhrtg hpthhtohepkhgrrhhthhhikhdrudekkeesghhmrghilhdrtghomhdprhgtphhtthhopehg ihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhg X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:48 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id f8ef9e8c (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:42 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:29 +0100 Subject: [PATCH v3 7/9] reftable/stack: add mechanism to notify callers on reload Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-7-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 Reftable stacks are reloaded in two cases: - When calling `reftable_stack_reload()`, if the stat-cache tells us that the stack has been modified. - When committing a reftable addition. While callers can figure out the second case, they do not have a mechanism to figure out whether `reftable_stack_reload()` led to an actual reload of the on-disk data. All they can do is thus to assume that data is always being reloaded in that case. Improve the situation by introducing a new `on_reload()` callback to the reftable options. If provided, the function will be invoked every time the stack has indeed been reloaded. This allows callers to invalidate data that depends on the current stack data. Signed-off-by: Patrick Steinhardt --- reftable/reftable-writer.h | 9 +++++++++ reftable/stack.c | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h index c85ef5a5bd14595d75f99457fef4407040e197c5..5f9afa620bb00de66c311765fb0ae8c6f56401ae 100644 --- a/reftable/reftable-writer.h +++ b/reftable/reftable-writer.h @@ -68,6 +68,15 @@ struct reftable_write_options { * fsync(3P) when unset. */ int (*fsync)(int fd); + + /* + * Callback function to execute whenever the stack is being reloaded. + * This can be used e.g. to discard cached information that relies on + * the old stack's data. The payload data will be passed as argument to + * the callback. + */ + void (*on_reload)(void *payload); + void *on_reload_payload; }; /* reftable_block_stats holds statistics for a single block type */ diff --git a/reftable/stack.c b/reftable/stack.c index d97b64a40d4ad05cfd9e6f33e8ba1e713281ef6d..5384ca9de0d1f064aebcb09308a74cc397b37463 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -548,6 +548,10 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, close(fd); free_names(names); free_names(names_after); + + if (st->opts.on_reload) + st->opts.on_reload(st->opts.on_reload_payload); + return err; } From patchwork Mon Nov 25 07:38:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884476 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E55E615383D for ; Mon, 25 Nov 2024 07:38:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520332; cv=none; b=aOEvHKC1kHsJ+7aiPy3sXugJvixPiJaJ9Rxfaw657dk3g1OEetEDN+geMExQ4w99hastzeiieMg14+taXFDGlZszdaYY9/Q8smbx9kEMmoxxxnVG+K4ps38xUEYem5CGIrftT89dRlCk39lMo9Hy/k4ZLfvgKZY+tPyUh/3Em+c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520332; c=relaxed/simple; bh=XFjnjSRlCgp96YgYgVf2q27MaHH5jZ1Kxxnvdj3IHFQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DMvBZkEKlA4TI3IEbeu+mgzZrbeDcs1JLBhsrbXxMPVN6s160PtevL+l9rL9AewLCqXgWnl4nn74b3PXsD7OHhqLJGJyYbMIYfkjXEn3zpmMwVLIif5+9Jh+JsweYiga1caGzsw0Wu396bp2+OBNJZiCORRBdDH5h+7+xn2b6Ds= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=hZIJ6/h/; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=28teOlES; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="hZIJ6/h/"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="28teOlES" Received: from phl-compute-04.internal (phl-compute-04.phl.internal [10.202.2.44]) by mailfout.stl.internal (Postfix) with ESMTP id 461C4114016B; Mon, 25 Nov 2024 02:38:50 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-04.internal (MEProxy); Mon, 25 Nov 2024 02:38:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520330; x=1732606730; bh=dJYwA6RcdVf0tz64LFuu7NwOsT/M7px/2LV6VSnbSkw=; b= hZIJ6/h/9R/vN+QCWS/IlpbLXRarHGOlL5o/e+Ag2O1yD/X+rJrTwipkBCCrIgkT 7dXEIVgnZQkvvuq3AE7G0E4MQnqQNmUbNM7KRc2F/XtKY6tZVaIpQSSFf/++CVoL GsDbxc9A0f2A65nxTbC5iXYTEpZovGcSSHNN4i7iCWmpQrl35aKmNtiD1iyS+/xT aIDYq0xuoH1rPtJUcY/FnwsUoYXUvW0xcogiUZQJZNhLiv+M/Vo3uIypKh0g1Q7q RWr4ytUxFVEwK7Xk0bqhe9FArlMUDRCaTpjkBpCD7YdeSUvigGr44xzaSha9v7M6 wK1FP62LfozRh7YyQ/F5ow== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520330; x= 1732606730; bh=dJYwA6RcdVf0tz64LFuu7NwOsT/M7px/2LV6VSnbSkw=; b=2 8teOlESyC2yZgeU60QrR2t2qAlyDM3xVxI/fkVx3WEodpMQU1RKGDqFihaoTYbH3 3JhXb/7ter0eF+s2JJKMqzlv8ahD57zG6oQgetNHoHRBdfEudRMMO2W+l2oJL6YQ 1cLnsaCRExkPCUQIPeuJkHVLBPG9huK7qhSR6SooCtnqa5Xu1oE2K0rQVEA7UngG ruD9ZQ7dZUSiyS6VcbSBF9wFbUPPu28T5bhqSxWKWrgRwPBtHrg+F35ydE+om54F SvyRozAQ8yKCjHcKMa61953h051M97HcNBskhiXFOwkF916xN2Vtsz6XMLExafsa FlmVaseNKwrgZzregCQSg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtjeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeffueeiudejvdekheeuvdekfeffiedvueelteekudeh jeetkeegvddugfdtgfeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhgpd hrtghpthhtohepkhgrrhhthhhikhdrudekkeesghhmrghilhdrtghomhdprhgtphhtthho pehgihhtshhtvghrsehpohgsohigrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:49 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id 010009ce (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:43 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:30 +0100 Subject: [PATCH v3 8/9] reftable/merged: drain priority queue on reseek Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-8-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 In 5bf96e0c39 (reftable/generic: move seeking of records into the iterator, 2024-05-13) we have refactored the reftable codebase such that iterators can be initialized once and then re-seeked multiple times. This feature is used by 1869525066 (refs/reftable: wire up support for exclude patterns, 2024-09-16) in order to skip records based on exclude patterns provided by the caller. The logic to re-seek the merged iterator is insufficient though because we don't drain the priority queue on a re-seek. This means that the queue may contain stale entries and thus reading the next record in the queue will return the wrong entry. While this is an obvious bug, it is harmless in the context of above exclude patterns: - If the queue contained stale entries that match the pattern then the caller would already know to filter out such refs. This is because our codebase is prepared to handle backends that don't have a way to efficiently implement exclude patterns. - If the queue contained stale entries that don't match the pattern we'd eventually filter out any duplicates. This is because the reftable code discards items with the same ref name and sorts any remaining entries properly. So things happen to work in this context regardless of the bug, and there is no other use case yet where we re-seek iterators. We're about to introduce a caching mechanism though where iterators are reused by the reftable backend, and that will expose the bug. Fix the issue by draining the priority queue when seeking and add a testcase that surfaces the issue. Signed-off-by: Patrick Steinhardt --- reftable/merged.c | 2 ++ t/unit-tests/t-reftable-merged.c | 73 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/reftable/merged.c b/reftable/merged.c index 5b93e20f42945300abbc1a036bbdf067fced7854..bb0836e3443271f9c0d5ba5582c78694d437ddc2 100644 --- a/reftable/merged.c +++ b/reftable/merged.c @@ -66,6 +66,8 @@ static int merged_iter_seek(struct merged_iter *mi, struct reftable_record *want int err; mi->advance_index = -1; + while (!merged_iter_pqueue_is_empty(mi->pq)) + merged_iter_pqueue_remove(&mi->pq); for (size_t i = 0; i < mi->subiters_len; i++) { err = iterator_seek(&mi->subiters[i].iter, want); diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index 2591b5e59745536a205271491f747875e04c5a3f..a12bd0e1a3bdeda82bcbc6259e679df4f232e3e2 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -273,6 +273,78 @@ static void t_merged_seek_multiple_times(void) reftable_free(sources); } +static void t_merged_seek_multiple_times_without_draining(void) +{ + struct reftable_ref_record r1[] = { + { + .refname = (char *) "a", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 1 }, + }, + { + .refname = (char *) "c", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 2 }, + } + }; + struct reftable_ref_record r2[] = { + { + .refname = (char *) "b", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 3 }, + }, + { + .refname = (char *) "d", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 4 }, + }, + }; + struct reftable_ref_record *refs[] = { + r1, r2, + }; + size_t sizes[] = { + ARRAY_SIZE(r1), ARRAY_SIZE(r2), + }; + struct reftable_buf bufs[] = { + REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, + }; + struct reftable_block_source *sources = NULL; + struct reftable_reader **readers = NULL; + struct reftable_ref_record rec = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_merged_table *mt; + int err; + + mt = merged_table_from_records(refs, &sources, &readers, sizes, bufs, 2); + merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + + err = reftable_iterator_seek_ref(&it, "b"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r2[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + err = reftable_iterator_seek_ref(&it, "a"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r1[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) + reftable_buf_release(&bufs[i]); + readers_destroy(readers, ARRAY_SIZE(refs)); + reftable_ref_record_release(&rec); + reftable_iterator_destroy(&it); + reftable_merged_table_free(mt); + reftable_free(sources); +} + static struct reftable_merged_table * merged_table_from_log_records(struct reftable_log_record **logs, struct reftable_block_source **source, @@ -467,6 +539,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); TEST(t_merged_refs(), "merged table with multiple updates to same ref"); TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times"); + TEST(t_merged_seek_multiple_times_without_draining(), "merged table can seek multiple times without draining"); TEST(t_merged_single_record(), "ref occurring in only one record can be fetched"); return test_done(); From patchwork Mon Nov 25 07:38:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13884477 Received: from fout-b2-smtp.messagingengine.com (fout-b2-smtp.messagingengine.com [202.12.124.145]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9895B18A92C for ; Mon, 25 Nov 2024 07:38:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=202.12.124.145 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520333; cv=none; b=IUSFyOPg28m2xUfab8jqHvUAsMUauE7cAKmL6ad0j/cCmLCcNBF+KiMgv2JgrsIqsca/Wr7ncHof4Kfa6JPPSbAEl7/n5Eponxh1gXvKCT1HOkaPl8DO+7noREk57tgNeZDhjtJKr5DopGP+3h9cYKzUpkBPFOZ9aHfE8BDPP/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732520333; c=relaxed/simple; bh=lIpTbedklKiZsItMocsK2jBEmsjBnr3cGbGor9gaw7M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=REpU2LjenocJLxDgO0+90IqIvnsve0cVQoe/vzOU8f3UCAtWfoS9MBoqzoQO+EYzdEMRo3/K3xCcS8cJ708cgTLJnkZNzr2Vwo5HIUkLGgcs9SJVhgh2fDpthTtDRGHzKGz38KF9dSOycBRjTbyCl3TGxrkq1Gaa+Chnr0JQ/Rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=O6WraDgS; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=AHHK+w3Z; arc=none smtp.client-ip=202.12.124.145 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="O6WraDgS"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="AHHK+w3Z" Received: from phl-compute-11.internal (phl-compute-11.phl.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id D78291140155; Mon, 25 Nov 2024 02:38:50 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Mon, 25 Nov 2024 02:38:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1732520330; x=1732606730; bh=AgrFld2v28c0QUbERNG4s1aCFV6WCm1uEcrRufjPsUM=; b= O6WraDgSRWoTguY8obdLE/s4HgeafDhGoYnbzfvsifJAhr9O0gK6gN8DNp+7GBj9 2U7mBGgw9uV99tlu0Yts5I91+sh6OrwaRvsefSkry7NoszdsjRoFSksMdlE9HYYb ax8/I/vtvEYhRbJA2lqqEuqnxXJAYm0FLBh+p2Q9sy5jfa/I/QJ0hF/wueMNECxP jOte2+m3m8/b7/0sstQzVwWF0cbuPdEolEFE0yY9QSScKBEKm3OMxoXMBX4IOQBL 3zSScMbb9h0ZC4Iul6TjRMnNVjd+x/x9JLmbvQGOAJb7CoMoRoV0/4/xFVQSos9b 1zNsc2kxC9zjYTnD4/SMGA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1732520330; x= 1732606730; bh=AgrFld2v28c0QUbERNG4s1aCFV6WCm1uEcrRufjPsUM=; b=A HHK+w3ZvLUan232IQJEKi5c9ELBB6veSgOh8fTccLG+rXccPFzVsu51RHWI5SoOt T3d2eNp/o5OTvV2zayoMeeICigHX8sxGXIVciu7tjQasgz+0Sl6/r3dAMAeFj890 fI2JbPR93BQUCUi/7RCwpb1pwP7U5gzykK2+5Ullfer5ENjBOvVYd1ujOicj8QAn aBb7+0rRG2pesEOGXSsnGeSfxY32dUfdeTiNdX+VTjIZopkR/BDBzgrOl/VlKr3H Ox3dE1buVOAZEJ/FB7JDYxBb2JqUc1l8LcX0nrRCuxTj9iGvG2UbfRId5Dqa+3ln NdF7PHV8WkpKXENdjiAxg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrgeeggddutdekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhephfffufggtgfgkfhfjgfvvefosehtkeertdertdej necuhfhrohhmpefrrghtrhhitghkucfuthgvihhnhhgrrhguthcuoehpshesphhkshdrih hmqeenucggtffrrghtthgvrhhnpeefhfeugeelheefjeektdffhedvhfdvteefgfdtudff udevveetgeeuuedtkefhgeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehpshesphhkshdrihhmpdhnsggprhgtphhtthhopeefpdhmohguvgep shhmthhpohhuthdprhgtphhtthhopehgihhtsehvghgvrhdrkhgvrhhnvghlrdhorhhgpd hrtghpthhtohepghhithhsthgvrhesphhosghogidrtghomhdprhgtphhtthhopehkrghr thhhihhkrddukeeksehgmhgrihhlrdgtohhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 25 Nov 2024 02:38:49 -0500 (EST) Received: by vm-mail (OpenSMTPD) with ESMTPSA id af82c93e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 25 Nov 2024 07:37:44 +0000 (UTC) From: Patrick Steinhardt Date: Mon, 25 Nov 2024 08:38:31 +0100 Subject: [PATCH v3 9/9] refs/reftable: reuse iterators when reading refs Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20241125-pks-reftable-backend-reuse-iter-v3-9-1d7b658e3e9e@pks.im> References: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> In-Reply-To: <20241125-pks-reftable-backend-reuse-iter-v3-0-1d7b658e3e9e@pks.im> To: git@vger.kernel.org Cc: karthik nayak , Junio C Hamano X-Mailer: b4 0.14.2 When reading references the reftable backend has to: 1. Create a new ref iterator. 2. Seek the iterator to the record we're searching for. 3. Read the record. We cannot really avoid the last two steps, but re-creating the iterator every single time we want to read a reference is kind of expensive and a waste of resources. We couldn't help it in the past though because it was not possible to reuse iterators. But starting with 5bf96e0c39 (reftable/generic: move seeking of records into the iterator, 2024-05-13) we have split up the iterator lifecycle such that creating the iterator and seeking are two different concerns. Refactor the code such that we cache iterators in the reftable backend. This cache is invalidated whenever the respective stack is reloaded such that we know to recreate the iterator in that case. This leads to a sizeable speedup when creating many refs, which requires a lot of random reference reads: Benchmark 1: update-ref: create many refs (refcount = 100000, revision = master) Time (mean ± σ): 1.793 s ± 0.010 s [User: 0.954 s, System: 0.835 s] Range (min … max): 1.781 s … 1.811 s 10 runs Benchmark 2: update-ref: create many refs (refcount = 100000, revision = HEAD) Time (mean ± σ): 1.680 s ± 0.013 s [User: 0.846 s, System: 0.831 s] Range (min … max): 1.664 s … 1.702 s 10 runs Summary update-ref: create many refs (refcount = 100000, revision = HEAD) ran 1.07 ± 0.01 times faster than update-ref: create many refs (refcount = 100000, revision = master) While 7% is not a huge win, you have to consider that the benchmark is _writing_ data, so _reading_ references is only one part of what we do. Flame graphs show that we spend around 40% of our time reading refs, so the speedup when reading refs is approximately ~2.5x that. I could not find better benchmarks where we perform a lot of random ref reads. You can also see a sizeable impact on memory usage when creating 100k references. Before this change: HEAP SUMMARY: in use at exit: 19,112,538 bytes in 200,170 blocks total heap usage: 8,400,426 allocs, 8,200,256 frees, 454,367,048 bytes allocated After this change: HEAP SUMMARY: in use at exit: 674,416 bytes in 169 blocks total heap usage: 7,929,872 allocs, 7,929,703 frees, 281,509,985 bytes allocated As an additional factor, this refactoring opens up the possibility for more performance optimizations in how we re-seek iterators. Any change that allows us to optimize re-seeking by e.g. reusing data structures would thus also directly speed up random reads. Signed-off-by: Patrick Steinhardt --- refs/reftable-backend.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index ff49c27a6a0f4cb1e5b3bfaa3d34d3302c1bdb2e..417c6c4955672ef69fe956e2e6dd8dbd1dd15a3c 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -36,19 +36,30 @@ struct reftable_backend { struct reftable_stack *stack; + struct reftable_iterator it; }; +static void reftable_backend_on_reload(void *payload) +{ + struct reftable_backend *be = payload; + reftable_iterator_destroy(&be->it); +} + static int reftable_backend_init(struct reftable_backend *be, const char *path, - const struct reftable_write_options *opts) + const struct reftable_write_options *_opts) { - return reftable_new_stack(&be->stack, path, opts); + struct reftable_write_options opts = *_opts; + opts.on_reload = reftable_backend_on_reload; + opts.on_reload_payload = be; + return reftable_new_stack(&be->stack, path, &opts); } static void reftable_backend_release(struct reftable_backend *be) { reftable_stack_destroy(be->stack); be->stack = NULL; + reftable_iterator_destroy(&be->it); } static int reftable_backend_read_ref(struct reftable_backend *be, @@ -60,10 +71,25 @@ static int reftable_backend_read_ref(struct reftable_backend *be, struct reftable_ref_record ref = {0}; int ret; - ret = reftable_stack_read_ref(be->stack, refname, &ref); + if (!be->it.ops) { + ret = reftable_stack_init_ref_iterator(be->stack, &be->it); + if (ret) + goto done; + } + + ret = reftable_iterator_seek_ref(&be->it, refname); if (ret) goto done; + ret = reftable_iterator_next_ref(&be->it, &ref); + if (ret) + goto done; + + if (strcmp(ref.refname, refname)) { + ret = 1; + goto done; + } + if (ref.value_type == REFTABLE_REF_SYMREF) { strbuf_reset(referent); strbuf_addstr(referent, ref.value.symref);