Skip to content

Commit

Permalink
GitPack: Don't use MemoryMappedFiles in 32-bit processes
Browse files Browse the repository at this point in the history
  • Loading branch information
qmfrederik committed Jul 27, 2021
1 parent 41696ba commit edc1621
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
20 changes: 18 additions & 2 deletions src/NerdBank.GitVersioning.Tests/ManagedGit/GitPackTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ZLibStream>(commitStream);
var deflateStream = Assert.IsType<DeflateStream>(zlibStream.BaseStream);
var pooledStream = Assert.IsType<MemoryMappedStream>(deflateStream.BaseStream);

if (IntPtr.Size > 4)
{
var pooledStream = Assert.IsType<MemoryMappedStream>(deflateStream.BaseStream);
}
else
{
var pooledStream = Assert.IsType<FileStream>(deflateStream.BaseStream);
}

Assert.Equal(222, commitStream.Length);
Assert.Equal("/zgldANj+jvgOwlecnOKylZDVQg=", Convert.ToBase64String(sha.ComputeHash(commitStream)));
Expand All @@ -85,7 +93,15 @@ public void GetDeltafiedObject()
var deltaStream = Assert.IsType<GitPackDeltafiedStream>(commitStream);
var zlibStream = Assert.IsType<ZLibStream>(deltaStream.BaseStream);
var deflateStream = Assert.IsType<DeflateStream>(zlibStream.BaseStream);
var pooledStream = Assert.IsType<MemoryMappedStream>(deflateStream.BaseStream);

if (IntPtr.Size > 4)
{
var pooledStream = Assert.IsType<MemoryMappedStream>(deflateStream.BaseStream);
}
else
{
var directAccessStream = Assert.IsType<FileStream>(deflateStream.BaseStream);
}

Assert.Equal(137, commitStream.Length);
Assert.Equal("lZu/7nGb0n1UuO9SlPluFnSvj4o=", Convert.ToBase64String(sha.ComputeHash(commitStream)));
Expand Down
27 changes: 20 additions & 7 deletions src/NerdBank.GitVersioning/ManagedGit/GitPack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class GitPack : IDisposable
private readonly Func<FileStream> packStream;
private readonly Lazy<FileStream> 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<GitObjectId, long> offsets = new Dictionary<GitObjectId, long>();
Expand Down Expand Up @@ -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);
}
}

/// <summary>
Expand Down Expand Up @@ -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();
}

Expand All @@ -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()
Expand Down

0 comments on commit edc1621

Please sign in to comment.