From be761de768496c107ea0b17dc707cc65b696a352 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Thu, 7 Dec 2017 21:30:51 +0000 Subject: [PATCH] Compute map UIDs without copying all data to a MemoryStream. 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. --- OpenRA.Game/Map/Map.cs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index e9bd0fc47a..ae5fe20e1f 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -19,6 +19,7 @@ using System.Reflection; using System.Text; using OpenRA.FileSystem; using OpenRA.Graphics; +using OpenRA.Primitives; using OpenRA.Support; using OpenRA.Traits; @@ -253,16 +254,27 @@ namespace OpenRA 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(); + 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(); } }