Skip to content

Commit 5bf329d

Browse files
committed
migrates caching to dedicated class
Introduces `GitRepositoryCache` to centralize caching logic for branches, commits, tags, references, and remotes. Updates related classes to use `GitRepositoryCache` instead of directly maintaining individual cache dictionaries.
1 parent eb1960b commit 5bf329d

File tree

12 files changed

+81
-74
lines changed

12 files changed

+81
-74
lines changed

src/GitVersion.LibGit2Sharp/Git/Branch.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ namespace GitVersion.Git;
1010

1111
private readonly LibGit2Sharp.Branch innerBranch;
1212

13-
internal Branch(LibGit2Sharp.Branch branch, LibGit2Sharp.Diff diff, GitRepository repo)
13+
internal Branch(LibGit2Sharp.Branch branch, LibGit2Sharp.Diff diff, GitRepositoryCache repositoryCache)
1414
{
1515
diff.NotNull();
16-
repo.NotNull();
16+
repositoryCache.NotNull();
1717
this.innerBranch = branch.NotNull();
1818
Name = new(branch.CanonicalName);
1919

2020
var commit = this.innerBranch.Tip;
21-
Tip = commit is null ? null : repo.GetOrWrap(commit, diff);
21+
Tip = commit is null ? null : repositoryCache.GetOrWrap(commit, diff);
2222

2323
var commits = this.innerBranch.Commits;
24-
Commits = new CommitCollection(commits, diff, repo);
24+
Commits = new CommitCollection(commits, diff, repositoryCache);
2525
}
2626

2727
public ReferenceName Name { get; }

src/GitVersion.LibGit2Sharp/Git/BranchCollection.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ internal sealed class BranchCollection : IBranchCollection
88
private readonly LibGit2Sharp.BranchCollection innerCollection;
99
private readonly Lazy<IReadOnlyCollection<IBranch>> branches;
1010
private readonly Diff diff;
11-
private readonly GitRepository repo;
11+
private readonly GitRepositoryCache repositoryCache;
1212

13-
internal BranchCollection(LibGit2Sharp.BranchCollection collection, Diff diff, GitRepository repo)
13+
internal BranchCollection(LibGit2Sharp.BranchCollection collection, Diff diff, GitRepositoryCache repositoryCache)
1414
{
1515
this.innerCollection = collection.NotNull();
16-
this.branches = new Lazy<IReadOnlyCollection<IBranch>>(() => [.. this.innerCollection.Select(branch => repo.GetOrWrap(branch, diff))]);
16+
this.branches = new Lazy<IReadOnlyCollection<IBranch>>(() => [.. this.innerCollection.Select(branch => repositoryCache.GetOrWrap(branch, diff))]);
1717
this.diff = diff.NotNull();
18-
this.repo = repo.NotNull();
18+
this.repositoryCache = repositoryCache.NotNull();
1919
}
2020

2121
public IEnumerator<IBranch> GetEnumerator() => this.branches.Value.GetEnumerator();
@@ -28,7 +28,7 @@ public IBranch? this[string name]
2828
{
2929
name = name.NotNull();
3030
var branch = this.innerCollection[name];
31-
return branch is null ? null : this.repo.GetOrWrap(branch, this.diff);
31+
return branch is null ? null : this.repositoryCache.GetOrWrap(branch, this.diff);
3232
}
3333
}
3434

src/GitVersion.LibGit2Sharp/Git/Commit.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ namespace GitVersion.Git;
1414
private readonly LibGit2Sharp.Commit innerCommit;
1515
private readonly LibGit2Sharp.Diff repoDiff;
1616

17-
internal Commit(LibGit2Sharp.Commit innerCommit, LibGit2Sharp.Diff repoDiff, GitRepository repo)
17+
internal Commit(LibGit2Sharp.Commit innerCommit, LibGit2Sharp.Diff repoDiff, GitRepositoryCache repositoryCache)
1818
{
1919
repoDiff.NotNull();
20-
repo.NotNull();
20+
repositoryCache.NotNull();
2121
this.innerCommit = innerCommit.NotNull();
22-
this.parentsLazy = new(() => [.. innerCommit.Parents.Select(parent => repo.GetOrWrap(parent, repoDiff))]);
22+
this.parentsLazy = new(() => [.. innerCommit.Parents.Select(parent => repositoryCache.GetOrWrap(parent, repoDiff))]);
2323
Id = new ObjectId(innerCommit.Id);
2424
Sha = innerCommit.Sha;
2525
When = innerCommit.Committer.When;

src/GitVersion.LibGit2Sharp/Git/CommitCollection.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ internal sealed class CommitCollection : ICommitCollection
88
private readonly ICommitLog innerCollection;
99
private readonly Lazy<IReadOnlyCollection<ICommit>> commits;
1010
private readonly Diff diff;
11-
private readonly GitRepository repo;
11+
private readonly GitRepositoryCache repositoryCache;
1212

13-
internal CommitCollection(ICommitLog collection, Diff diff, GitRepository repo)
13+
internal CommitCollection(ICommitLog collection, Diff diff, GitRepositoryCache repositoryCache)
1414
{
1515
this.innerCollection = collection.NotNull();
16-
this.commits = new Lazy<IReadOnlyCollection<ICommit>>(() => [.. this.innerCollection.Select(commit => repo.GetOrWrap(commit, diff))]);
16+
this.commits = new Lazy<IReadOnlyCollection<ICommit>>(() => [.. this.innerCollection.Select(commit => repositoryCache.GetOrWrap(commit, diff))]);
1717
this.diff = diff.NotNull();
18-
this.repo = repo.NotNull();
18+
this.repositoryCache = repositoryCache.NotNull();
1919
}
2020

2121
public IEnumerator<ICommit> GetEnumerator() => this.commits.Value.GetEnumerator();
@@ -37,7 +37,7 @@ public IEnumerable<ICommit> QueryBy(CommitFilter commitFilter)
3737
SortBy = (LibGit2Sharp.CommitSortStrategies)commitFilter.SortBy
3838
};
3939
var commitLog = ((IQueryableCommitLog)this.innerCollection).QueryBy(filter);
40-
return new CommitCollection(commitLog, this.diff, this.repo);
40+
return new CommitCollection(commitLog, this.diff, this.repositoryCache);
4141

4242
static object? GetReacheableFrom(object? item) =>
4343
item switch

src/GitVersion.LibGit2Sharp/Git/GitRepository.cs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Collections.Concurrent;
21
using GitVersion.Extensions;
32
using GitVersion.Helpers;
43
using LibGit2Sharp;
@@ -8,13 +7,7 @@ namespace GitVersion.Git;
87
internal sealed partial class GitRepository
98
{
109
private Lazy<IRepository>? repositoryLazy;
11-
12-
private readonly ConcurrentDictionary<string, Branch> cachedBranches = new();
13-
private readonly ConcurrentDictionary<string, Commit> cachedCommits = new();
14-
private readonly ConcurrentDictionary<string, Tag> cachedTags = new();
15-
private readonly ConcurrentDictionary<string, Remote> cachedRemotes = new();
16-
private readonly ConcurrentDictionary<string, Reference> cachedReferences = new();
17-
private readonly ConcurrentDictionary<string, RefSpec> cachedRefSpecs = new();
10+
private readonly GitRepositoryCache repositoryCache = new();
1811

1912
private IRepository RepositoryInstance
2013
{
@@ -28,7 +21,7 @@ private IRepository RepositoryInstance
2821
public string WorkingDirectory => RepositoryInstance.Info.WorkingDirectory;
2922
public bool IsHeadDetached => RepositoryInstance.Info.IsHeadDetached;
3023
public bool IsShallow => RepositoryInstance.Info.IsShallow;
31-
public IBranch Head => GetOrWrap(RepositoryInstance.Head, RepositoryInstance.Diff);
24+
public IBranch Head => this.repositoryCache.GetOrWrap(RepositoryInstance.Head, RepositoryInstance.Diff);
3225

3326
public ITagCollection Tags => new TagCollection(RepositoryInstance.Tags, RepositoryInstance.Diff, this.repositoryCache);
3427
public IBranchCollection Branches => new BranchCollection(RepositoryInstance.Branches, RepositoryInstance.Diff, this.repositoryCache);
@@ -56,7 +49,7 @@ public void DiscoverRepository(string? gitDirectory)
5649
var first = (Commit)commit;
5750
var second = (Commit)otherCommit;
5851
var mergeBase = RepositoryInstance.ObjectDatabase.FindMergeBase(first, second);
59-
return mergeBase == null ? null : GetOrWrap(mergeBase, RepositoryInstance.Diff);
52+
return mergeBase == null ? null : this.repositoryCache.GetOrWrap(mergeBase, RepositoryInstance.Diff);
6053
});
6154
}
6255

@@ -66,29 +59,6 @@ public int UncommittedChangesCount()
6659
return retryAction.Execute(GetUncommittedChangesCountInternal);
6760
}
6861

69-
public Branch GetOrWrap(LibGit2Sharp.Branch innerBranch, Diff repoDiff)
70-
{
71-
var cacheKey = innerBranch.Tip is null
72-
? $"{innerBranch.RemoteName}/{innerBranch.CanonicalName}"
73-
: $"{innerBranch.RemoteName}/{innerBranch.CanonicalName}@{innerBranch.Tip.Sha}";
74-
return cachedBranches.GetOrAdd(cacheKey, _ => new Branch(innerBranch, repoDiff, this));
75-
}
76-
77-
public Commit GetOrWrap(LibGit2Sharp.Commit innerCommit, Diff repoDiff)
78-
=> cachedCommits.GetOrAdd(innerCommit.Sha, _ => new Commit(innerCommit, repoDiff, this));
79-
80-
public Tag GetOrWrap(LibGit2Sharp.Tag innerTag, Diff repoDiff)
81-
=> cachedTags.GetOrAdd(innerTag.CanonicalName, _ => new Tag(innerTag, repoDiff, this));
82-
83-
public Remote GetOrWrap(LibGit2Sharp.Remote innerRemote)
84-
=> cachedRemotes.GetOrAdd(innerRemote.Name, _ => new Remote(innerRemote, this));
85-
86-
public Reference GetOrWrap(LibGit2Sharp.Reference innerReference)
87-
=> cachedReferences.GetOrAdd(innerReference.CanonicalName, _ => new Reference(innerReference));
88-
89-
public RefSpec GetOrWrap(LibGit2Sharp.RefSpec innerRefSpec)
90-
=> cachedRefSpecs.GetOrAdd(innerRefSpec.Specification, _ => new RefSpec(innerRefSpec));
91-
9262
public void Dispose()
9363
{
9464
if (this.repositoryLazy is { IsValueCreated: true }) RepositoryInstance.Dispose();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.Concurrent;
2+
using LibGit2Sharp;
3+
4+
namespace GitVersion.Git;
5+
6+
internal class GitRepositoryCache
7+
{
8+
private readonly ConcurrentDictionary<string, Branch> cachedBranches = new();
9+
private readonly ConcurrentDictionary<string, Commit> cachedCommits = new();
10+
private readonly ConcurrentDictionary<string, Tag> cachedTags = new();
11+
private readonly ConcurrentDictionary<string, Remote> cachedRemotes = new();
12+
private readonly ConcurrentDictionary<string, Reference> cachedReferences = new();
13+
private readonly ConcurrentDictionary<string, RefSpec> cachedRefSpecs = new();
14+
15+
public Branch GetOrWrap(LibGit2Sharp.Branch innerBranch, Diff repoDiff)
16+
{
17+
var cacheKey = innerBranch.Tip is null
18+
? $"{innerBranch.RemoteName}/{innerBranch.CanonicalName}"
19+
: $"{innerBranch.RemoteName}/{innerBranch.CanonicalName}@{innerBranch.Tip.Sha}";
20+
return cachedBranches.GetOrAdd(cacheKey, _ => new Branch(innerBranch, repoDiff, this));
21+
}
22+
23+
public Commit GetOrWrap(LibGit2Sharp.Commit innerCommit, Diff repoDiff)
24+
=> cachedCommits.GetOrAdd(innerCommit.Sha, _ => new Commit(innerCommit, repoDiff, this));
25+
26+
public Tag GetOrWrap(LibGit2Sharp.Tag innerTag, Diff repoDiff)
27+
=> cachedTags.GetOrAdd(innerTag.CanonicalName, _ => new Tag(innerTag, repoDiff, this));
28+
29+
public Remote GetOrWrap(LibGit2Sharp.Remote innerRemote)
30+
=> cachedRemotes.GetOrAdd(innerRemote.Name, _ => new Remote(innerRemote, this));
31+
32+
public Reference GetOrWrap(LibGit2Sharp.Reference innerReference)
33+
=> cachedReferences.GetOrAdd(innerReference.CanonicalName, _ => new Reference(innerReference));
34+
35+
public RefSpec GetOrWrap(LibGit2Sharp.RefSpec innerRefSpec)
36+
=> cachedRefSpecs.GetOrAdd(innerRefSpec.Specification, _ => new RefSpec(innerRefSpec));
37+
}

src/GitVersion.LibGit2Sharp/Git/RefSpecCollection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ internal sealed class RefSpecCollection : IRefSpecCollection
66
{
77
private readonly Lazy<IReadOnlyCollection<IRefSpec>> refSpecs;
88

9-
internal RefSpecCollection(LibGit2Sharp.RefSpecCollection innerCollection, GitRepository repo)
9+
internal RefSpecCollection(LibGit2Sharp.RefSpecCollection innerCollection, GitRepositoryCache repositoryCache)
1010
{
1111
innerCollection = innerCollection.NotNull();
12-
this.refSpecs = new Lazy<IReadOnlyCollection<IRefSpec>>(() => [.. innerCollection.Select(repo.GetOrWrap)]);
12+
this.refSpecs = new Lazy<IReadOnlyCollection<IRefSpec>>(() => [.. innerCollection.Select(repositoryCache.GetOrWrap)]);
1313
}
1414

1515
public IEnumerator<IRefSpec> GetEnumerator() => this.refSpecs.Value.GetEnumerator();

src/GitVersion.LibGit2Sharp/Git/ReferenceCollection.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ namespace GitVersion.Git;
55
internal sealed class ReferenceCollection : IReferenceCollection
66
{
77
private readonly LibGit2Sharp.ReferenceCollection innerCollection;
8-
private readonly GitRepository repo;
8+
private readonly GitRepositoryCache repositoryCache;
99
private readonly Lazy<IReadOnlyCollection<IReference>> references;
1010

11-
internal ReferenceCollection(LibGit2Sharp.ReferenceCollection collection, GitRepository repo)
11+
internal ReferenceCollection(LibGit2Sharp.ReferenceCollection collection, GitRepositoryCache repositoryCache)
1212
{
1313
this.innerCollection = collection.NotNull();
14-
this.repo = repo.NotNull();
15-
this.references = new Lazy<IReadOnlyCollection<IReference>>(() => [.. this.innerCollection.Select(repo.GetOrWrap)]);
14+
this.repositoryCache = repositoryCache.NotNull();
15+
this.references = new Lazy<IReadOnlyCollection<IReference>>(() => [.. this.innerCollection.Select(repositoryCache.GetOrWrap)]);
1616
}
1717

1818
public IEnumerator<IReference> GetEnumerator() => this.references.Value.GetEnumerator();
@@ -30,13 +30,13 @@ public IReference? this[string name]
3030
get
3131
{
3232
var reference = this.innerCollection[name];
33-
return reference is null ? null : this.repo.GetOrWrap(reference);
33+
return reference is null ? null : this.repositoryCache.GetOrWrap(reference);
3434
}
3535
}
3636

3737
public IReference? this[ReferenceName referenceName] => this[referenceName.Canonical];
3838

3939
public IReference? Head => this["HEAD"];
4040

41-
public IEnumerable<IReference> FromGlob(string prefix) => this.innerCollection.FromGlob(prefix).Select(reference => (IReference)this.repo.GetOrWrap(reference));
41+
public IEnumerable<IReference> FromGlob(string prefix) => this.innerCollection.FromGlob(prefix).Select(reference => (IReference)this.repositoryCache.GetOrWrap(reference));
4242
}

src/GitVersion.LibGit2Sharp/Git/Remote.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ namespace GitVersion.Git;
99
private static readonly LambdaKeyComparer<IRemote, string> comparerHelper = new(x => x.Name);
1010

1111
private readonly LibGit2Sharp.Remote innerRemote;
12-
private readonly GitRepository repo;
12+
private readonly GitRepositoryCache repositoryCache;
1313

14-
internal Remote(LibGit2Sharp.Remote remote, GitRepository repo)
14+
internal Remote(LibGit2Sharp.Remote remote, GitRepositoryCache repositoryCache)
1515
{
1616
this.innerRemote = remote.NotNull();
17-
this.repo = repo.NotNull();
17+
this.repositoryCache = repositoryCache.NotNull();
1818
}
1919

2020
public int CompareTo(IRemote? other) => comparerHelper.Compare(this, other);
@@ -29,7 +29,7 @@ private IEnumerable<IRefSpec> RefSpecs
2929
var refSpecs = this.innerRemote.RefSpecs;
3030
return refSpecs is null
3131
? []
32-
: new RefSpecCollection((LibGit2Sharp.RefSpecCollection)refSpecs, repo);
32+
: new RefSpecCollection((LibGit2Sharp.RefSpecCollection)refSpecs, this.repositoryCache);
3333
}
3434
}
3535

src/GitVersion.LibGit2Sharp/Git/RemoteCollection.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ namespace GitVersion.Git;
55
internal sealed class RemoteCollection : IRemoteCollection
66
{
77
private readonly LibGit2Sharp.RemoteCollection innerCollection;
8-
private readonly GitRepository repo;
8+
private readonly GitRepositoryCache repositoryCache;
99
private readonly Lazy<IReadOnlyCollection<IRemote>> remotes;
1010

11-
internal RemoteCollection(LibGit2Sharp.RemoteCollection collection, GitRepository repo)
11+
internal RemoteCollection(LibGit2Sharp.RemoteCollection collection, GitRepositoryCache repositoryCache)
1212
{
1313
this.innerCollection = collection.NotNull();
14-
this.repo = repo.NotNull();
15-
this.remotes = new Lazy<IReadOnlyCollection<IRemote>>(() => [.. this.innerCollection.Select(repo.GetOrWrap)]);
14+
this.repositoryCache = repositoryCache.NotNull();
15+
this.remotes = new Lazy<IReadOnlyCollection<IRemote>>(() => [.. this.innerCollection.Select(repositoryCache.GetOrWrap)]);
1616
}
1717

1818
public IEnumerator<IRemote> GetEnumerator() => this.remotes.Value.GetEnumerator();
@@ -24,7 +24,7 @@ public IRemote? this[string name]
2424
get
2525
{
2626
var remote = this.innerCollection[name];
27-
return remote is null ? null : this.repo.GetOrWrap(remote);
27+
return remote is null ? null : this.repositoryCache.GetOrWrap(remote);
2828
}
2929
}
3030

0 commit comments

Comments
 (0)