Skip to content

Commit

Permalink
Optimize Sarc.Write
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchLeaders committed Mar 15, 2024
1 parent 67eee8c commit af313cf
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 19 deletions.
32 changes: 17 additions & 15 deletions src/SarcLibrary/Sarc.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
global using SarcNodeData = (string Name, (uint FileNameHash, System.ArraySegment<byte> Data, int Alignment) Value);

using CommunityToolkit.HighPerformance.Buffers;
using Revrs;
using SarcLibrary.Structures;
using SarcLibrary.Writers;
Expand Down Expand Up @@ -69,29 +69,31 @@ public unsafe void Write(Stream stream, Endianness? endianness = null, bool lega

writer.Move(sizeof(SarcHeader));

SarcNodeData[] sorted = this
.Select(x => (x.Key, Value: (
Hash: SfatWriter.GetFileNameHash(x.Key), x.Value,
Alignment: SarcAlignment.Estimate(x, endianness.Value, legacy)
)))
.OrderBy(x => x.Value.Hash)
.ToArray();
int sarcAlignment = 1;
using SpanOwner<SarcNodeData> sorted = SpanOwner<SarcNodeData>.Allocate(Count);

int i = -1;
foreach (KeyValuePair<string, ArraySegment<byte>> entry in this) {
uint hash = SfatWriter.GetFileNameHash(entry.Key);

SfatWriter.Write(writer, sorted, IsHashOnly);
int alignment = SarcAlignment.Estimate(entry, endianness.Value, legacy);
sarcAlignment = SarcAlignment.LCM(sarcAlignment, alignment);

if (!IsHashOnly) {
SfntWriter.Write(writer, sorted);
sorted.Span[++i] = (entry.Key, Value: (hash, entry.Value, alignment));
}

int sarcAlignment = 1;
foreach ((var _, var value) in sorted) {
sarcAlignment = SarcAlignment.LCM(sarcAlignment, value.Alignment);
sorted.Span.Sort((SarcNodeData x, SarcNodeData y) => x.Value.FileNameHash.CompareTo(y.Value.FileNameHash));

SfatWriter.Write(ref writer, sorted.Span, IsHashOnly);

if (!IsHashOnly) {
SfntWriter.Write(ref writer, sorted.Span);
}

writer.Align(sarcAlignment);

int dataOffset = (int)writer.Position;
foreach ((var _, var value) in sorted) {
foreach ((var _, var value) in sorted.Span) {
writer.Align(value.Alignment);
writer.Write(value.Data);
}
Expand Down
3 changes: 2 additions & 1 deletion src/SarcLibrary/SarcLibrary.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Revrs" Version="1.0.3" />
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.2.2" />
<PackageReference Include="Revrs" Version="1.0.4" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/SarcLibrary/Writers/SfatWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ internal class SfatWriter
private const uint HASH_KEY = 0x65;
private const ushort HEADER_SIZE = 0xC;

public static void Write(RevrsWriter writer, SarcNodeData[] entries, bool isHashOnly)
public static void Write(ref RevrsWriter writer, Span<SarcNodeData> entries, bool isHashOnly)
{
SfatHeader header = new() {
Magic = Sarc.SFAT_MAGIC,
Expand All @@ -29,7 +29,7 @@ public static void Write(RevrsWriter writer, SarcNodeData[] entries, bool isHash
FileNameHash = entry.Value.FileNameHash,
FileAttributes = isHashOnly ? 0x0 : 0x01000000 | (nameOffset / 4),
DataStartOffset = dataOffset += dataOffset.AlignUp(entry.Value.Alignment),
DataEndOffset = dataOffset += entry.Value.Data.Length
DataEndOffset = dataOffset += entry.Value.Data.Count
};

nameOffset += entry.Name.Length + 1;
Expand Down
2 changes: 1 addition & 1 deletion src/SarcLibrary/Writers/SfntWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace SarcLibrary.Writers;

public class SfntWriter
{
public unsafe static void Write(RevrsWriter writer, SarcNodeData[] entries)
public unsafe static void Write(ref RevrsWriter writer, Span<SarcNodeData> entries)
{
SfntHeader header = new() {
Magic = Sarc.SFNT_MAGIC,
Expand Down

0 comments on commit af313cf

Please sign in to comment.