Skip to content

Commit

Permalink
Reduce heap allocation in CpkArchive IO ops
Browse files Browse the repository at this point in the history
  • Loading branch information
0x7c13 committed Oct 15, 2023
1 parent 01913ed commit 3751ea1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 26 deletions.
43 changes: 18 additions & 25 deletions Assets/Scripts/Pal3.Core/DataReader/Cpk/CpkArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,12 @@ private byte[] ReadAllBytesUsingInMemoryCache(string fileVirtualPath)
{
CpkTableEntity entity = ValidateAndGetTableEntity(fileVirtualPath);

byte[] data;
ReadOnlySpan<byte> dataInArchive = new ReadOnlySpan<byte>(_archiveData)
.Slice((int)entity.StartPos, (int)entity.PackedSize);

var start = (int) entity.StartPos;
var end = (int) (entity.StartPos + entity.PackedSize);

if (entity.IsCompressed())
{
data = new byte[entity.OriginSize];
MiniLzo.Decompress(_archiveData[start..end], data);
}
else
{
data = _archiveData[start..end];
}

return data;
return entity.IsCompressed() ?
DecompressDataInArchive(dataInArchive, entity.OriginSize) :
dataInArchive.ToArray();
}

private byte[] GetFileContent(string fileVirtualPath)
Expand All @@ -169,27 +159,30 @@ private byte[] GetFileContent(string fileVirtualPath)

private byte[] GetFileContentInternal(CpkTableEntity entity)
{
byte[] rawData;

if (_archiveInMemory)
{
var start = (int) entity.StartPos;
var end = (int) (entity.StartPos + entity.PackedSize);
rawData = _archiveData[start..end];
ReadOnlySpan<byte> rawData = new ReadOnlySpan<byte>(_archiveData)
.Slice((int)entity.StartPos, (int)entity.PackedSize);
return entity.IsCompressed() ?
DecompressDataInArchive(rawData, entity.OriginSize) :
rawData.ToArray();
}
else
{
using var stream = new FileStream(_filePath, FileMode.Open, FileAccess.Read);
stream.Seek(entity.StartPos, SeekOrigin.Begin);
var buffer = new byte[entity.PackedSize];
_ = stream.Read(buffer, 0, (int)entity.PackedSize);
rawData = buffer;
return entity.IsCompressed() ?
DecompressDataInArchive(buffer, entity.OriginSize) :
buffer;
}
}

if (!entity.IsCompressed()) return rawData;

var decompressedData = new byte[entity.OriginSize];
MiniLzo.Decompress(rawData, decompressedData);
private byte[] DecompressDataInArchive(ReadOnlySpan<byte> compressedData, uint originSize)
{
var decompressedData = new byte[originSize];
MiniLzo.Decompress(compressedData, decompressedData);
return decompressedData;
}

Expand Down
2 changes: 1 addition & 1 deletion Assets/Scripts/Pal3.Core/DataReader/Cpk/Lzo/MiniLzo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static class MiniLzo
{
private const uint M2_MAX_OFFSET = 0x0800;

public static unsafe void Decompress(byte[] src, byte[] dst)
public static unsafe void Decompress(ReadOnlySpan<byte> src, byte[] dst)
{
uint t = 0;
fixed (byte* input = src, output = dst)
Expand Down

0 comments on commit 3751ea1

Please sign in to comment.