Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 3, 2023. It is now read-only.

Commit abb3587

Browse files
committed
Improve performance of refs.ReachableFrom()
1 parent 9d57983 commit abb3587

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,12 @@ internal static extern int git_diff_find_similar(
496496
[DllImport(libgit2)]
497497
internal static extern int git_graph_ahead_behind(out UIntPtr ahead, out UIntPtr behind, RepositorySafeHandle repo, ref GitOid one, ref GitOid two);
498498

499+
[DllImport(libgit2)]
500+
internal static extern int git_graph_descendant_of(
501+
RepositorySafeHandle repo,
502+
ref GitOid commit,
503+
ref GitOid ancestor);
504+
499505
[DllImport(libgit2)]
500506
internal static extern int git_ignore_add_rule(
501507
RepositorySafeHandle repo,

LibGit2Sharp/Core/Proxy.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,21 @@ public static GitDiffDelta git_diff_get_delta(DiffSafeHandle diff, int idx)
754754
}
755755
}
756756

757+
public static bool git_graph_descendant_of(RepositorySafeHandle repo, ObjectId commitId, ObjectId ancestorId)
758+
{
759+
GitOid oid1 = commitId.Oid;
760+
GitOid oid2 = ancestorId.Oid;
761+
762+
using (ThreadAffinity())
763+
{
764+
int res = NativeMethods.git_graph_descendant_of(repo, ref oid1, ref oid2);
765+
766+
Ensure.BooleanResult(res);
767+
768+
return (res == 1);
769+
}
770+
}
771+
757772
#endregion
758773

759774
#region git_ignore_

LibGit2Sharp/ReferenceCollectionExtensions.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -295,27 +295,40 @@ public static IEnumerable<Reference> ReachableFrom(
295295
return Enumerable.Empty<Reference>();
296296
}
297297

298-
var targetsSet = new HashSet<Commit>(targets);
298+
List<ObjectId> targetsSet = targets.Select(c => c.Id).Distinct().ToList();
299299
if (targetsSet.Count == 0)
300300
{
301301
return Enumerable.Empty<Reference>();
302302
}
303303

304-
var allCommits = refsColl.repo.Commits;
305-
306304
var result = new List<Reference>();
307305

308306
foreach (var reference in refs)
309307
{
310-
foreach (var commit in allCommits.QueryBy(new CommitFilter { Since = reference }))
308+
var peeledTargetCommit = reference
309+
.ResolveToDirectReference()
310+
.Target.DereferenceToCommit(false);
311+
312+
if (peeledTargetCommit == null)
313+
{
314+
continue;
315+
}
316+
317+
var commitId = peeledTargetCommit.Id;
318+
319+
foreach (var potentialAncestorId in targetsSet)
311320
{
312-
if (!targetsSet.Contains(commit))
321+
if (potentialAncestorId == commitId)
313322
{
314-
continue;
323+
result.Add(reference);
324+
break;
315325
}
316326

317-
result.Add(reference);
318-
break;
327+
if (Proxy.git_graph_descendant_of(refsColl.repo.Handle, commitId, potentialAncestorId))
328+
{
329+
result.Add(reference);
330+
break;
331+
}
319332
}
320333
}
321334

0 commit comments

Comments
 (0)