Skip to content

Commit 5095912

Browse files
committed
Improve caching mechanisms
1 parent 4e500cb commit 5095912

File tree

1 file changed

+68
-27
lines changed

1 file changed

+68
-27
lines changed

src/EasySign/Bundle.cs

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class Bundle
2929
private byte[] _rawZipContents = [];
3030

3131
private readonly ConcurrentDictionary<string, byte[]> _cache = new();
32+
private byte[] _zipCache = [];
3233
private readonly int _maxCacheSize;
3334
private int _currentCacheSize;
3435

@@ -242,8 +243,32 @@ public ZipArchive OpenZipArchive(ZipArchiveMode mode = ZipArchiveMode.Read)
242243
}
243244
else
244245
{
245-
Logger.LogDebug("Loading bundle from file: {file}", BundlePath);
246+
if (mode == ZipArchiveMode.Read)
247+
{
248+
Stream stream;
249+
if (_zipCache.Length == 0)
250+
{
251+
Logger.LogDebug("Loading bundle from file: {file}", BundlePath);
252+
stream = File.OpenRead(BundlePath);
253+
254+
if (ReadOnly && stream.Length < _maxCacheSize)
255+
{
256+
Logger.LogDebug("Caching bundle with {Size} bytes", stream.Length);
257+
_zipCache = ReadStream(stream);
258+
}
259+
}
260+
else
261+
{
262+
Logger.LogDebug("Loading bundle from cache with {Size} bytes", _zipCache.Length);
263+
stream = new MemoryStream(_zipCache, writable: false);
264+
}
265+
266+
return new ZipArchive(stream, ZipArchiveMode.Read);
267+
}
246268

269+
_zipCache = Array.Empty<byte>();
270+
271+
Logger.LogDebug("Loading bundle from file: {file}", BundlePath);
247272
return ZipFile.Open(BundlePath, mode);
248273
}
249274
}
@@ -568,9 +593,37 @@ public X509Certificate2 GetCertificate(string certificateHash)
568593
return certificate;
569594
}
570595

596+
/// <summary>
597+
/// Gets the data of an entry in the bundle as bytes array and caches the entry data if the bundle is Read-only.
598+
/// </summary>
599+
/// <remarks>
600+
/// Protected entries are only resolved with <see cref="ReadSource.Bundle"/>.
601+
/// </remarks>
602+
/// <param name="entryName">The name of the entry to get the bytes for.</param>
603+
/// <param name="readSource">The source from which to read the data.</param>
604+
/// <returns>The entry data as bytes array.</returns>
605+
public byte[] GetBytes(string entryName, ReadSource readSource)
606+
{
607+
Ensure.String.IsNotNullOrEmpty(entryName.Trim(), nameof(entryName));
608+
609+
Logger.LogInformation("Getting file data for entry: {name}", entryName);
610+
611+
if (!_cache.TryGetValue(entryName, out var data))
612+
{
613+
data = ReadStream(GetStream(entryName, readSource));
614+
615+
_ = CacheEntry(entryName, data);
616+
}
617+
618+
return data;
619+
}
620+
571621
/// <summary>
572622
/// Gets a stream for an entry in the bundle and caches the entry data if the bundle is Read-only.
573623
/// </summary>
624+
/// <remarks>
625+
/// Protected entries are only resolved with <see cref="ReadSource.Bundle"/>.
626+
/// </remarks>
574627
/// <param name="entryName">The name of the entry to get the stream for.</param>
575628
/// <param name="readSource">The source from which to read the data.</param>
576629
/// <returns>A stream for the entry.</returns>
@@ -583,7 +636,7 @@ public Stream GetStream(string entryName, ReadSource readSource = ReadSource.Bot
583636
if (_cache.TryGetValue(entryName, out var data))
584637
{
585638
Logger.LogDebug("Reading entry {name} from cache", entryName);
586-
return new MemoryStream(data);
639+
return new MemoryStream(data, writable: false);
587640
}
588641
else
589642
{
@@ -621,28 +674,6 @@ public Stream GetStream(string entryName, ReadSource readSource = ReadSource.Bot
621674

622675
return stream;
623676
}
624-
625-
/// <summary>
626-
/// Gets the data of an entry in the bundle as bytes array and caches the entry data if the bundle is Read-only.
627-
/// </summary>
628-
/// <param name="entryName">The name of the entry to get the bytes for.</param>
629-
/// <param name="readSource">The source from which to read the data.</param>
630-
/// <returns>The entry data as bytes array.</returns>
631-
public byte[] GetBytes(string entryName, ReadSource readSource)
632-
{
633-
Ensure.String.IsNotNullOrEmpty(entryName.Trim(), nameof(entryName));
634-
635-
Logger.LogInformation("Getting file data for entry: {name}", entryName);
636-
637-
if (!_cache.TryGetValue(entryName, out var data))
638-
{
639-
data = ReadStream(GetStream(entryName, readSource));
640-
641-
_ = CacheEntry(entryName, data);
642-
}
643-
644-
return data;
645-
}
646677

647678
/// <summary>
648679
/// Writes changes to the bundle file.
@@ -780,9 +811,19 @@ private static byte[] ReadStream(Stream stream)
780811
throw new OverflowException("Stream length is too big for buffering");
781812
}
782813

783-
MemoryStream ms = new();
784-
stream.CopyTo(ms);
785-
return ms.ToArray();
814+
byte[] result;
815+
if (stream is MemoryStream memoryStream)
816+
{
817+
result = memoryStream.ToArray();
818+
}
819+
else
820+
{
821+
MemoryStream ms = new();
822+
stream.CopyTo(ms);
823+
result = ms.ToArray();
824+
}
825+
826+
return result;
786827
}
787828

788829
/// <summary>

0 commit comments

Comments
 (0)