From: "Derrick Stolee via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: peff@peff.net, newren@gmail.com,
Junio C Hamano <gitster@pobox.com>,
Derrick Stolee <dstolee@microsoft.com>
Subject: [PATCH 3/3] remote: make add_missing_tags() linear
Date: Tue, 30 Oct 2018 07:16:07 -0700 (PDT) [thread overview]
Message-ID: <ecbed3de5c704a5d54a910a527b60eb79f0d252e.1540908961.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.60.git.gitgitgadget@gmail.com>
From: Derrick Stolee <dstolee@microsoft.com>
The add_missing_tags() method currently has quadratic behavior.
This is due to a linear number (based on number of tags T) of
calls to in_merge_bases_many, which has linear performance (based
on number of commits C in the repository).
Replace this O(T * C) algorithm with an O(T + C) algorithm by
using get_reachable_subset(). We ignore the return list and focus
instead on the reachable_flag assigned to the commits we care
about, because we need to interact with the tag ref and not just
the commit object.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
remote.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/remote.c b/remote.c
index 81f4f01b0..b850f2feb 100644
--- a/remote.c
+++ b/remote.c
@@ -1205,9 +1205,36 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
* sent to the other side.
*/
if (sent_tips.nr) {
+ const int reachable_flag = 1;
+ struct commit_list *found_commits;
+ struct commit **src_commits;
+ int nr_src_commits = 0, alloc_src_commits = 16;
+ ALLOC_ARRAY(src_commits, alloc_src_commits);
+
for_each_string_list_item(item, &src_tag) {
struct ref *ref = item->util;
+ struct commit *commit;
+
+ if (is_null_oid(&ref->new_oid))
+ continue;
+ commit = lookup_commit_reference_gently(the_repository,
+ &ref->new_oid,
+ 1);
+ if (!commit)
+ /* not pushing a commit, which is not an error */
+ continue;
+
+ ALLOC_GROW(src_commits, nr_src_commits + 1, alloc_src_commits);
+ src_commits[nr_src_commits++] = commit;
+ }
+
+ found_commits = get_reachable_subset(sent_tips.tip, sent_tips.nr,
+ src_commits, nr_src_commits,
+ reachable_flag);
+
+ for_each_string_list_item(item, &src_tag) {
struct ref *dst_ref;
+ struct ref *ref = item->util;
struct commit *commit;
if (is_null_oid(&ref->new_oid))
@@ -1223,7 +1250,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
* Is this tag, which they do not have, reachable from
* any of the commits we are sending?
*/
- if (!in_merge_bases_many(commit, sent_tips.nr, sent_tips.tip))
+ if (!(commit->object.flags & reachable_flag))
continue;
/* Add it in */
@@ -1231,7 +1258,12 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
oidcpy(&dst_ref->new_oid, &ref->new_oid);
dst_ref->peer_ref = copy_ref(ref);
}
+
+ clear_commit_marks_many(nr_src_commits, src_commits, reachable_flag);
+ free(src_commits);
+ free_commit_list(found_commits);
}
+
string_list_clear(&src_tag, 0);
free(sent_tips.tip);
}
--
gitgitgadget
next prev parent reply other threads:[~2018-10-30 14:16 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-30 14:16 [PATCH 0/3] Make add_missing_tags() linear Derrick Stolee via GitGitGadget
2018-10-30 14:16 ` [PATCH 1/3] commit-reach: implement get_reachable_subset Derrick Stolee via GitGitGadget
2018-10-31 3:35 ` Junio C Hamano
2018-10-31 12:01 ` Derrick Stolee
2018-11-02 1:51 ` Junio C Hamano
2018-10-31 6:07 ` Elijah Newren
2018-10-31 11:54 ` Derrick Stolee
2018-10-30 14:16 ` [PATCH 2/3] test-reach: test get_reachable_subset Derrick Stolee via GitGitGadget
2018-10-30 14:16 ` Derrick Stolee via GitGitGadget [this message]
2018-10-31 3:05 ` [PATCH 0/3] Make add_missing_tags() linear Junio C Hamano
2018-10-31 6:04 ` Elijah Newren
2018-10-31 12:05 ` Derrick Stolee
2018-11-01 6:52 ` Elijah Newren
2018-11-01 12:32 ` Derrick Stolee
2018-11-01 18:57 ` Elijah Newren
2018-11-01 19:02 ` Derrick Stolee
2018-11-02 14:58 ` Elijah Newren
2018-11-02 15:38 ` Derrick Stolee
2018-11-02 13:14 ` [PATCH v2 " Derrick Stolee via GitGitGadget
2018-11-02 13:14 ` [PATCH v2 1/3] commit-reach: implement get_reachable_subset Derrick Stolee via GitGitGadget
2018-11-02 13:14 ` [PATCH v2 2/3] test-reach: test get_reachable_subset Derrick Stolee via GitGitGadget
2018-11-02 13:14 ` [PATCH v2 3/3] remote: make add_missing_tags() linear Derrick Stolee via GitGitGadget
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=ecbed3de5c704a5d54a910a527b60eb79f0d252e.1540908961.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=dstolee@microsoft.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=newren@gmail.com \
--cc=peff@peff.net \
/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).