Skip to content

Commit

Permalink
Reduce branches in HexPrefix.FromBytes (#7596)
Browse files Browse the repository at this point in the history
  • Loading branch information
benaadams authored Oct 13, 2024
1 parent 4bba613 commit 837065c
Showing 1 changed file with 35 additions and 10 deletions.
45 changes: 35 additions & 10 deletions src/Nethermind/Nethermind.Trie/HexPrefix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Nethermind.Trie
{
Expand Down Expand Up @@ -39,23 +42,45 @@ public static byte[] ToBytes(byte[] path, bool isLeaf)

public static (byte[] key, bool isLeaf) FromBytes(ReadOnlySpan<byte> bytes)
{
bool isLeaf = bytes[0] >= 32;
bool isEven = (bytes[0] & 16) == 0;
int nibblesCount = bytes.Length * 2 - (isEven ? 2 : 1);
byte[] path = new byte[nibblesCount];
for (int i = 0; i < nibblesCount; i++)
Span<byte> span = new(path);
if (!isEven)
{
span[0] = (byte)(bytes[0] & 0xF);
span = span.Slice(1);
}
bool isLeaf = bytes[0] >= 32;
bytes = bytes.Slice(1);

Span<ushort> nibbles = MemoryMarshal.CreateSpan(
ref Unsafe.As<byte, ushort>(ref MemoryMarshal.GetReference(span)),
span.Length / 2);

Debug.Assert(nibbles.Length == bytes.Length);

ref byte byteRef = ref MemoryMarshal.GetReference(bytes);
ref ushort lookup16 = ref MemoryMarshal.GetArrayDataReference(Lookup16);
for (int i = 0; i < nibbles.Length; i++)
{
path[i] =
isEven
? i % 2 == 0
? (byte)((bytes[1 + i / 2] & 240) / 16)
: (byte)(bytes[1 + i / 2] & 15)
: i % 2 == 0
? (byte)(bytes[i / 2] & 15)
: (byte)((bytes[1 + i / 2] & 240) / 16);
nibbles[i] = Unsafe.Add(ref lookup16, Unsafe.Add(ref byteRef, i));
}

return (path, isLeaf);
}

private static readonly ushort[] Lookup16 = CreateLookup16("x2");

private static ushort[] CreateLookup16(string format)
{
ushort[] result = new ushort[256];
for (int i = 0; i < 256; i++)
{
result[i] = (ushort)(((i & 0xF) << 8) | ((i & 240) >> 4));
}

return result;
}
}
}

0 comments on commit 837065c

Please sign in to comment.