Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CarDecoder.DecodeCar(byte[]) performance #157

Merged
merged 2 commits into from
Jan 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions src/FishyFlip/Tools/CarDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright (c) Drastic Actions. All rights reserved.
// </copyright>

using System.Runtime.InteropServices;

namespace FishyFlip.Tools;

/// <summary>
Expand All @@ -24,6 +26,16 @@ public static class CarDecoder
/// <param name="bytes">Byte Array.</param>
/// <param name="progress">Fires when a car file is decoded.</param>
public static void DecodeCar(byte[] bytes, OnCarDecoded? progress = null)
{
DecodeCar(bytes.AsSpan(), progress);
}

/// <summary>
/// Decodes CAR ReadOnlySpan.
/// </summary>
/// <param name="bytes">Bytes to decode.</param>
/// <param name="progress">Fires when a car file is decoded.</param>
public static void DecodeCar(ReadOnlySpan<byte> bytes, OnCarDecoded? progress = null)
{
int bytesLength = bytes.Length;
var header = DecodeReader(bytes);
Expand All @@ -41,12 +53,12 @@ public static void DecodeCar(byte[] bytes, OnCarDecoded? progress = null)
start += body.Length;

var cidBytes = bytes[start..(start + ATCidV1BytesLength)];
var cid = Cid.Read(cidBytes);
var cid = Cid.Read(cidBytes.ToArray());

start += ATCidV1BytesLength;
var bs = bytes[start..(start + body.Value - ATCidV1BytesLength)];
start += body.Value - ATCidV1BytesLength;
progress?.Invoke(new CarProgressStatusEvent(cid, bs));
progress?.Invoke(new CarProgressStatusEvent(cid, bs.ToArray()));
}
}

Expand Down Expand Up @@ -121,33 +133,32 @@ private static DecodedBlock DecodeReader(Stream stream)
}
}

return new DecodedBlock(Decode(a), a.Count);
#if NET5_OR_GREATER
return new DecodedBlock(Decode(CollectionsMarshal.AsSpan(a)), a.Count);
#else
return new DecodedBlock(Decode(a.ToArray()), a.Count);
#endif
}

private static DecodedBlock DecodeReader(byte[] bytes)
private static DecodedBlock DecodeReader(ReadOnlySpan<byte> bytes)
{
var a = new List<byte>();

int i = 0;
while (true)
for (int i = 0; i < bytes.Length; i++)
{
byte b = bytes[i];

i++;
a.Add(b);
if ((b & 0x80) == 0)
{
break;
var a = bytes.Slice(0, i + 1);
return new DecodedBlock(Decode(a), a.Length);
}
}

return new DecodedBlock(Decode(a), a.Count);
throw new InvalidDataException("Incomplete block.");
}

private static int Decode(List<byte> b)
private static int Decode(ReadOnlySpan<byte> b)
{
int r = 0;
for (int i = 0; i < b.Count; i++)
for (int i = 0; i < b.Length; i++)
{
int e = b[i];
r = r + ((e & 0x7F) << (i * 7));
Expand Down
Loading