Skip to content
This repository was archived by the owner on May 27, 2026. It is now read-only.

Commit 50027ed

Browse files
committed
[Core] Refactored ZCompression to optimize GC
1 parent 0930ded commit 50027ed

2 files changed

Lines changed: 51 additions & 28 deletions

File tree

Lagrange.Core/Utility/Compression/Common.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Lagrange.Core.Utility.Compression;
66

7-
internal static class Common
7+
public static class Common
88
{
99
public static byte[] Deflate(byte[] data)
1010
{
@@ -14,21 +14,26 @@ public static byte[] Deflate(byte[] data)
1414
deflateStream.Close();
1515
return memoryStream.ToArray();
1616
}
17-
18-
public static byte[] Inflate(ReadOnlySpan<byte> data)
17+
18+
public static byte[] Deflate(ReadOnlySpan<byte> data)
1919
{
20-
using var ms = new MemoryStream();
21-
using var ds = new DeflateStream(ms, CompressionMode.Decompress, true);
22-
using var os = new MemoryStream();
20+
using var memoryStream = new MemoryStream();
21+
using var deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress);
22+
deflateStream.Write(data);
23+
deflateStream.Close();
24+
return memoryStream.ToArray();
25+
}
2326

24-
ms.Write(data);
25-
ms.Position = 0;
27+
public static byte[] Inflate(ReadOnlySpan<byte> data)
28+
{
29+
using var input = new MemoryStream(data.Length);
30+
input.Write(data);
31+
input.Position = 0;
2632

27-
ds.CopyTo(os);
28-
var deflate = new byte[os.Length];
29-
os.Position = 0;
30-
os.Read(deflate, 0, deflate.Length);
33+
using var deflate = new DeflateStream(input, CompressionMode.Decompress);
34+
using var output = new MemoryStream();
35+
deflate.CopyTo(output);
3136

32-
return deflate;
37+
return output.ToArray();
3338
}
3439
}

Lagrange.Core/Utility/Compression/ZCompression.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Lagrange.Core.Utility.Compression;
55

6-
internal static class ZCompression
6+
public static class ZCompression
77
{
88
public static byte[] ZCompress(byte[] data, byte[]? header = null)
99
{
@@ -15,34 +15,52 @@ public static byte[] ZCompress(byte[] data, byte[]? header = null)
1515
stream.WriteByte(0xDA); // Zlib header
1616

1717
stream.Write(deflate.AsSpan());
18-
19-
var checksum = Adler32(data);
20-
stream.Write(checksum.AsSpan());
21-
18+
19+
Span<byte> checksum = stackalloc byte[4];
20+
BinaryPrimitives.WriteUInt32BigEndian(checksum, Adler32(data));
21+
stream.Write(checksum);
22+
2223
return stream.ToArray();
2324
}
24-
25+
2526
public static byte[] ZCompress(string data, byte[]? header = null) => ZCompress(Encoding.UTF8.GetBytes(data), header);
2627

28+
public static byte[] ZCompress(ReadOnlySpan<byte> data, ReadOnlySpan<byte> header = default)
29+
{
30+
using var stream = new MemoryStream();
31+
var deflate = Common.Deflate(data);
32+
33+
stream.Write(header);
34+
stream.WriteByte(0x78); // Zlib header
35+
stream.WriteByte(0xDA); // Zlib header
36+
37+
stream.Write(deflate.AsSpan());
38+
39+
Span<byte> checksum = stackalloc byte[4];
40+
BinaryPrimitives.WriteUInt32BigEndian(checksum, Adler32(data));
41+
stream.Write(checksum);
42+
43+
return stream.ToArray();
44+
}
45+
2746
public static byte[] ZDecompress(ReadOnlySpan<byte> data, bool validate = true)
2847
{
29-
var checksum = data[^4..];
30-
48+
uint expectedChecksum = BinaryPrimitives.ReadUInt32BigEndian(data[^4..]);
49+
3150
var inflate = Common.Inflate(data[2..^4]);
32-
if (validate) return checksum.SequenceEqual(Adler32(inflate)) ? inflate : throw new Exception("Checksum mismatch");
51+
if (validate && Adler32(inflate) != expectedChecksum) throw new Exception("Checksum mismatch");
52+
3353
return inflate;
3454
}
35-
36-
private static byte[] Adler32(byte[] data)
55+
56+
private static uint Adler32(ReadOnlySpan<byte> data)
3757
{
3858
uint a = 1, b = 0;
3959
foreach (byte t in data)
4060
{
4161
a = (a + t) % 65521;
4262
b = (b + a) % 65521;
4363
}
44-
var result = new byte[4];
45-
BinaryPrimitives.WriteUInt32BigEndian(result, (b << 16) | a);
46-
return result;
64+
return (b << 16) | a;
4765
}
48-
}
66+
}

0 commit comments

Comments
 (0)