git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Christian Couder <christian.couder@gmail.com>,
	Jonathan Tan <jonathantanmy@google.com>,
	Elijah Newren <newren@gmail.com>
Subject: [PATCH v2 5/7] refs: add interface to iterate over queued transactional updates
Date: Thu, 17 Feb 2022 14:04:32 +0100	[thread overview]
Message-ID: <fac2e3555a4ce976252697e7898e125b5e521bdf.1645102965.git.ps@pks.im> (raw)
In-Reply-To: <cover.1645102965.git.ps@pks.im>

[-- Attachment #1: Type: text/plain, Size: 3399 bytes --]

There is no way for a caller to see whether a reference update has
already been queued up for a given reference transaction. There are
multiple alternatives to provide this functionality:

    - We may add a function that simply tells us whether a specific
      reference has already been queued. If implemented naively then
      this would potentially be quadratic in runtime behaviour if this
      question is asked repeatedly because we have to iterate over all
      references every time. The alternative would be to add a hashmap
      of all queued reference updates to speed up the lookup, but this
      adds overhead to all callers.

    - We may add a flag to `ref_transaction_add_update()` that causes it
      to skip duplicates, but this has the same runtime concerns as the
      first alternative.

    - We may add an interface which lets callers collect all updates
      which have already been queued such that he can avoid re-adding
      them. This is the most flexible approach and puts the burden on
      the caller, but also allows us to not impact any of the existing
      callsites which don't need this information.

This commit implements the last approach: it allows us to compute the
map of already-queued updates once up front such that we can then skip
all subsequent references which are already part of this map.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 refs.c | 16 ++++++++++++++++
 refs.h | 14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/refs.c b/refs.c
index d680de3bc0..35d4e69687 100644
--- a/refs.c
+++ b/refs.c
@@ -2417,6 +2417,22 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
 	return refs->be->initial_transaction_commit(refs, transaction, err);
 }
 
+void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
+					    ref_transaction_for_each_queued_update_fn cb,
+					    void *cb_data)
+{
+	int i;
+
+	for (i = 0; i < transaction->nr; i++) {
+		struct ref_update *update = transaction->updates[i];
+
+		cb(update->refname,
+		   (update->flags & REF_HAVE_OLD) ? &update->old_oid : NULL,
+		   (update->flags & REF_HAVE_NEW) ? &update->new_oid : NULL,
+		   cb_data);
+	}
+}
+
 int refs_delete_refs(struct ref_store *refs, const char *logmsg,
 		     struct string_list *refnames, unsigned int flags)
 {
diff --git a/refs.h b/refs.h
index ff859d5951..1ae12c410a 100644
--- a/refs.h
+++ b/refs.h
@@ -776,6 +776,20 @@ int ref_transaction_abort(struct ref_transaction *transaction,
 int initial_ref_transaction_commit(struct ref_transaction *transaction,
 				   struct strbuf *err);
 
+/*
+ * Execute the given callback function for each of the reference updates which
+ * have been queued in the given transaction. `old_oid` and `new_oid` may be
+ * `NULL` pointers depending on whether the update has these object IDs set or
+ * not.
+ */
+typedef void ref_transaction_for_each_queued_update_fn(const char *refname,
+						       const struct object_id *old_oid,
+						       const struct object_id *new_oid,
+						       void *cb_data);
+void ref_transaction_for_each_queued_update(struct ref_transaction *transaction,
+					    ref_transaction_for_each_queued_update_fn cb,
+					    void *cb_data);
+
 /*
  * Free `*transaction` and all associated data.
  */
-- 
2.35.1


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2022-02-17 13:05 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-17 13:04 [PATCH v2 0/7] fetch: improve atomicity of `--atomic` flag Patrick Steinhardt
2022-02-17 13:04 ` [PATCH v2 1/7] fetch: increase test coverage of fetches Patrick Steinhardt
2022-02-17 15:18   ` Christian Couder
2022-02-21  7:57     ` Patrick Steinhardt
2022-02-17 20:41   ` Junio C Hamano
2022-02-17 22:43     ` Junio C Hamano
2022-02-18  6:49     ` Patrick Steinhardt
2022-02-18 16:59       ` Junio C Hamano
2022-03-03  0:25   ` Junio C Hamano
2022-03-03  6:47     ` Patrick Steinhardt
2022-02-17 13:04 ` [PATCH v2 2/7] fetch: backfill tags before setting upstream Patrick Steinhardt
2022-02-17 22:07   ` Junio C Hamano
2022-02-17 13:04 ` [PATCH v2 3/7] fetch: control lifecycle of FETCH_HEAD in a single place Patrick Steinhardt
2022-02-17 22:12   ` Junio C Hamano
2022-02-17 13:04 ` [PATCH v2 4/7] fetch: report errors when backfilling tags fails Patrick Steinhardt
2022-02-17 22:16   ` Junio C Hamano
2022-02-17 13:04 ` Patrick Steinhardt [this message]
2022-02-17 13:04 ` [PATCH v2 6/7] fetch: make `--atomic` flag cover backfilling of tags Patrick Steinhardt
2022-02-17 22:27   ` Junio C Hamano
2022-02-17 13:04 ` [PATCH v2 7/7] fetch: make `--atomic` flag cover pruning of refs Patrick Steinhardt
2022-02-17 15:50 ` [PATCH v2 0/7] fetch: improve atomicity of `--atomic` flag Christian Couder
2022-02-17 22:30   ` Junio C Hamano
2022-02-21  8:02 ` [PATCH v3 " Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 1/7] fetch: increase test coverage of fetches Patrick Steinhardt
2022-03-03  0:30     ` Junio C Hamano
2022-03-03  0:32       ` Junio C Hamano
2022-03-03  6:43         ` Patrick Steinhardt
2022-03-03  6:49           ` Junio C Hamano
2022-03-03  6:51             ` Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 2/7] fetch: backfill tags before setting upstream Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 3/7] fetch: control lifecycle of FETCH_HEAD in a single place Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 4/7] fetch: report errors when backfilling tags fails Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 5/7] refs: add interface to iterate over queued transactional updates Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 6/7] fetch: make `--atomic` flag cover backfilling of tags Patrick Steinhardt
2022-02-21  8:02   ` [PATCH v3 7/7] fetch: make `--atomic` flag cover pruning of refs Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fac2e3555a4ce976252697e7898e125b5e521bdf.1645102965.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jonathantanmy@google.com \
    --cc=newren@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).