diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs b/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs index 8b0934285..6a6592c42 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs @@ -178,9 +178,14 @@ public Stream GetObject(long offset, string objectType) } #endif - if (this.cache.TryOpen(offset, out Stream? stream)) + if (this.cache.TryOpen(offset, out (Stream ContentStream, string ObjectType)? hit)) { - return stream!; + if (hit.Value.ObjectType != objectType) + { + throw new GitException($"An object of type {objectType} could not be located at offset {offset}.") { ErrorCode = GitException.ErrorCodes.ObjectNotFound }; + } + + return hit.Value.ContentStream; } GitPackObjectType packObjectType; @@ -216,7 +221,7 @@ public Stream GetObject(long offset, string objectType) throw; } - return this.cache.Add(offset, objectStream); + return this.cache.Add(offset, objectStream, objectType); } /// diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitPackCache.cs b/src/NerdBank.GitVersioning/ManagedGit/GitPackCache.cs index 50e054abe..eaefca928 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitPackCache.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitPackCache.cs @@ -22,14 +22,14 @@ public abstract class GitPackCache : IDisposable /// /// The offset of the Git object in the Git pack. /// - /// - /// A which will be set to the cached Git object. + /// + /// A (, ContentType) tuple which will be set to the cached data if found. /// /// /// if the object was found in cache; otherwise, /// . /// - public abstract bool TryOpen(long offset, [NotNullWhen(true)] out Stream? stream); + public abstract bool TryOpen(long offset, [NotNullWhen(true)] out (Stream ContentStream, string ObjectType)? hit); /// /// Gets statistics about the cache usage. @@ -49,10 +49,11 @@ public abstract class GitPackCache : IDisposable /// A which represents the object to add. This stream /// will be copied to the cache. /// + /// The object type of the object to add to the cache. /// /// A which represents the cached entry. /// - public abstract Stream Add(long offset, Stream stream); + public abstract Stream Add(long offset, Stream stream, string objectType); /// public void Dispose() diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs b/src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs index c7f8c6eb8..8043d87e1 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitPackMemoryCache.cs @@ -21,33 +21,33 @@ namespace Nerdbank.GitVersioning.ManagedGit; /// twice, it is read from the , rather than the underlying . /// /// -/// and return +/// and return /// objects which may operate on the same underlying , but independently maintain /// their state. /// /// public class GitPackMemoryCache : GitPackCache { - private readonly Dictionary cache = new Dictionary(); + private readonly Dictionary cache = new(); /// - public override Stream Add(long offset, Stream stream) + public override Stream Add(long offset, Stream stream, string objectType) { var cacheStream = new GitPackMemoryCacheStream(stream); - this.cache.Add(offset, cacheStream); + this.cache.Add(offset, (cacheStream, objectType)); return new GitPackMemoryCacheViewStream(cacheStream); } /// - public override bool TryOpen(long offset, [NotNullWhen(true)] out Stream? stream) + public override bool TryOpen(long offset, [NotNullWhen(true)] out (Stream ContentStream, string ObjectType)? hit) { - if (this.cache.TryGetValue(offset, out GitPackMemoryCacheStream? cacheStream)) + if (this.cache.TryGetValue(offset, out (GitPackMemoryCacheStream Stream, string ObjectType) tuple)) { - stream = new GitPackMemoryCacheViewStream(cacheStream!); + hit = (new GitPackMemoryCacheViewStream(tuple.Stream), tuple.ObjectType); return true; } - stream = null; + hit = null; return false; } @@ -64,8 +64,8 @@ protected override void Dispose(bool disposing) { while (this.cache.Count > 0) { - long key = this.cache.Keys.First(); - GitPackMemoryCacheStream? stream = this.cache[key]; + var key = this.cache.Keys.First(); + (GitPackMemoryCacheStream? stream, _) = this.cache[key]; stream.Dispose(); this.cache.Remove(key); } diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitPackNullCache.cs b/src/NerdBank.GitVersioning/ManagedGit/GitPackNullCache.cs index f96e8ba94..67ffdc14e 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitPackNullCache.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitPackNullCache.cs @@ -19,15 +19,15 @@ public class GitPackNullCache : GitPackCache public static GitPackNullCache Instance { get; } = new GitPackNullCache(); /// - public override Stream Add(long offset, Stream stream) + public override Stream Add(long offset, Stream stream, string objectType) { return stream; } /// - public override bool TryOpen(long offset, [NotNullWhen(true)] out Stream? stream) + public override bool TryOpen(long offset, [NotNullWhen(true)] out (Stream ContentStream, string ObjectType)? hit) { - stream = null; + hit = null; return false; } diff --git a/test/Nerdbank.GitVersioning.Tests/ManagedGit/GitPackMemoryCacheTests.cs b/test/Nerdbank.GitVersioning.Tests/ManagedGit/GitPackMemoryCacheTests.cs index c03ae8582..32aaa85b6 100644 --- a/test/Nerdbank.GitVersioning.Tests/ManagedGit/GitPackMemoryCacheTests.cs +++ b/test/Nerdbank.GitVersioning.Tests/ManagedGit/GitPackMemoryCacheTests.cs @@ -20,11 +20,13 @@ public void StreamsAreIndependent() { var cache = new GitPackMemoryCache(); - Stream stream1 = cache.Add(0, stream); - Assert.True(cache.TryOpen(0, out Stream stream2)); + Stream stream1 = cache.Add(0, stream, "anObjectType"); + Assert.True(cache.TryOpen(0, out (Stream ContentStream, string ObjectType)? hit)); + Assert.True(hit.HasValue); + Assert.Equal("anObjectType", hit.Value.ObjectType); using (stream1) - using (stream2) + using (Stream stream2 = hit.Value.ContentStream) { stream1.Seek(5, SeekOrigin.Begin); Assert.Equal(5, stream1.Position);