Skip to content

Commit

Permalink
Compute map UIDs without copying all data to a MemoryStream.
Browse files Browse the repository at this point in the history
We can use MergedStream to create a single combined stream with all the input and pass this to the hash function. This saves copying all the data into a MemoryStream to achieve the same goal, which requires more memory and allocations.
  • Loading branch information
RoosterDragon committed Dec 16, 2017
1 parent 502c3e2 commit 50dde32
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions OpenRA.Game/Map/Map.cs
Expand Up @@ -19,6 +19,7 @@
using System.Text;
using OpenRA.FileSystem;
using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Traits;

Expand Down Expand Up @@ -253,16 +254,27 @@ public static string ComputeUID(IReadOnlyPackage package)
if (!contents.Contains(required))
throw new FileNotFoundException("Required file {0} not present in this map".F(required));

using (var ms = new MemoryStream())
var streams = new List<Stream>();
try
{
foreach (var filename in contents)
if (filename.EndsWith(".yaml") || filename.EndsWith(".bin") || filename.EndsWith(".lua"))
using (var s = package.GetStream(filename))
s.CopyTo(ms);
streams.Add(package.GetStream(filename));

// Take the SHA1
ms.Seek(0, SeekOrigin.Begin);
return CryptoUtil.SHA1Hash(ms);
if (streams.Count == 0)
return CryptoUtil.SHA1Hash(new byte[0]);

var merged = streams[0];
for (var i = 1; i < streams.Count; i++)
merged = new MergedStream(merged, streams[i]);

return CryptoUtil.SHA1Hash(merged);
}
finally
{
foreach (var stream in streams)
stream.Dispose();
}
}

Expand Down

0 comments on commit 50dde32

Please sign in to comment.