From edc162175a43ce985c769f942ac063ea26a271ef Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Fri, 23 Jul 2021 16:37:10 +0200 Subject: [PATCH] GitPack: Don't use MemoryMappedFiles in 32-bit processes --- .../ManagedGit/GitPackTests.cs | 20 ++++++++++++-- .../ManagedGit/GitPack.cs | 27 ++++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/NerdBank.GitVersioning.Tests/ManagedGit/GitPackTests.cs b/src/NerdBank.GitVersioning.Tests/ManagedGit/GitPackTests.cs index 94905c70..6a55fe77 100644 --- a/src/NerdBank.GitVersioning.Tests/ManagedGit/GitPackTests.cs +++ b/src/NerdBank.GitVersioning.Tests/ManagedGit/GitPackTests.cs @@ -63,7 +63,15 @@ public void GetPackedObject() // This commit is not deltafied. It is stored as a .gz-compressed stream in the pack file. var zlibStream = Assert.IsType(commitStream); var deflateStream = Assert.IsType(zlibStream.BaseStream); - var pooledStream = Assert.IsType(deflateStream.BaseStream); + + if (IntPtr.Size > 4) + { + var pooledStream = Assert.IsType(deflateStream.BaseStream); + } + else + { + var pooledStream = Assert.IsType(deflateStream.BaseStream); + } Assert.Equal(222, commitStream.Length); Assert.Equal("/zgldANj+jvgOwlecnOKylZDVQg=", Convert.ToBase64String(sha.ComputeHash(commitStream))); @@ -85,7 +93,15 @@ public void GetDeltafiedObject() var deltaStream = Assert.IsType(commitStream); var zlibStream = Assert.IsType(deltaStream.BaseStream); var deflateStream = Assert.IsType(zlibStream.BaseStream); - var pooledStream = Assert.IsType(deflateStream.BaseStream); + + if (IntPtr.Size > 4) + { + var pooledStream = Assert.IsType(deflateStream.BaseStream); + } + else + { + var directAccessStream = Assert.IsType(deflateStream.BaseStream); + } Assert.Equal(137, commitStream.Length); Assert.Equal("lZu/7nGb0n1UuO9SlPluFnSvj4o=", Convert.ToBase64String(sha.ComputeHash(commitStream))); diff --git a/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs b/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs index 27c45c69..eff2eaf8 100644 --- a/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs +++ b/src/NerdBank.GitVersioning/ManagedGit/GitPack.cs @@ -31,8 +31,8 @@ public class GitPack : IDisposable private readonly Func packStream; private readonly Lazy indexStream; private readonly GitPackCache cache; - private MemoryMappedFile packFile; - private MemoryMappedViewAccessor accessor; + private MemoryMappedFile? packFile = null; + private MemoryMappedViewAccessor? accessor = null; // Maps GitObjectIds to offets in the git pack. private readonly Dictionary offsets = new Dictionary(); @@ -98,8 +98,11 @@ public GitPack(GetObjectFromRepositoryDelegate getObjectFromRepositoryDelegate, this.indexStream = indexStream ?? throw new ArgumentNullException(nameof(indexStream)); this.cache = cache ?? new GitPackMemoryCache(); - this.packFile = MemoryMappedFile.CreateFromFile(this.packStream(), mapName: null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, leaveOpen: false); - this.accessor = this.packFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read); + if (IntPtr.Size > 4) + { + this.packFile = MemoryMappedFile.CreateFromFile(this.packStream(), mapName: null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, leaveOpen: false); + this.accessor = this.packFile.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read); + } } /// @@ -240,8 +243,8 @@ public void Dispose() this.indexReader.Value.Dispose(); } - this.accessor.Dispose(); - this.packFile.Dispose(); + this.accessor?.Dispose(); + this.packFile?.Dispose(); this.cache.Dispose(); } @@ -265,7 +268,17 @@ public void Dispose() private Stream GetPackStream() { - return new MemoryMappedStream(this.accessor); + // On 64-bit processes, we can use Memory Mapped Streams (the address space + // will be large enough to map the entire packfile). On 32-bit processes, + // we directly access the underlying stream. + if (IntPtr.Size > 4) + { + return new MemoryMappedStream(this.accessor); + } + else + { + return this.packStream(); + } } private GitPackIndexReader OpenIndex()