diff --git a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs index 7a3ce9593f4..732aaad4db0 100644 --- a/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs +++ b/src/Nethermind/Nethermind.Blockchain/Receipts/PersistentReceiptStorage.cs @@ -321,7 +321,7 @@ public long MigratedBlockNumber set { _migratedBlockNumber = value; - _defaultColumn.Set(MigrationBlockNumberKey, MigratedBlockNumber.ToBigEndianByteArrayWithoutLeadingZeros()); + _defaultColumn.PutSpan(MigrationBlockNumberKey.Bytes, value.ToBigEndianSpanWithoutLeadingZeros(out _)); } } diff --git a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs index d269c4f2825..00a6a23f1c0 100644 --- a/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs +++ b/src/Nethermind/Nethermind.Consensus.AuRa/Validators/ValidatorStore.cs @@ -36,7 +36,7 @@ public void SetValidators(long finalizingBlockNumber, Address[] validators) var validatorInfo = new ValidatorInfo(finalizingBlockNumber, _latestFinalizedValidatorsBlockNumber, validators); var rlp = Rlp.Encode(validatorInfo); _db.Set(GetKey(finalizingBlockNumber), rlp.Bytes); - _db.Set(LatestFinalizedValidatorsBlockNumberKey, finalizingBlockNumber.ToBigEndianByteArrayWithoutLeadingZeros()); + _db.PutSpan(LatestFinalizedValidatorsBlockNumberKey.Bytes, finalizingBlockNumber.ToBigEndianSpanWithoutLeadingZeros(out _)); _latestFinalizedValidatorsBlockNumber = finalizingBlockNumber; _latestValidatorInfo = validatorInfo; Metrics.ValidatorsCount = validators.Length; diff --git a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs index 1306742283c..7417a66bfb7 100644 --- a/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs +++ b/src/Nethermind/Nethermind.Core/Extensions/Int64Extensions.cs @@ -3,7 +3,9 @@ using System; using System.Buffers.Binary; +using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Nethermind.Int256; @@ -11,112 +13,19 @@ namespace Nethermind.Core.Extensions; public static class Int64Extensions { - public static byte[] ToBigEndianByteArrayWithoutLeadingZeros(this long value) + public static ReadOnlySpan ToBigEndianSpanWithoutLeadingZeros(this long value, out long buffer) { - byte byte6 = (byte)(value >> 8); - byte byte5 = (byte)(value >> 16); - byte byte4 = (byte)(value >> 24); - byte byte3 = (byte)(value >> 32); - byte byte2 = (byte)(value >> 40); - byte byte1 = (byte)(value >> 48); - byte byte0 = (byte)(value >> 56); - - if (byte0 == 0) - { - if (byte1 == 0) - { - if (byte2 == 0) - { - if (byte3 == 0) - { - if (byte4 == 0) - { - if (byte5 == 0) - { - if (byte6 == 0) - { - byte[] bytes = new byte[1]; - bytes[0] = (byte)value; - return bytes; - } - else - { - byte[] bytes = new byte[2]; - bytes[1] = (byte)value; - bytes[0] = byte6; - return bytes; - } - } - else - { - byte[] bytes = new byte[3]; - bytes[2] = (byte)value; - bytes[1] = byte6; - bytes[0] = byte5; - return bytes; - } - } - else - { - byte[] bytes = new byte[4]; - bytes[3] = (byte)value; - bytes[2] = byte6; - bytes[1] = byte5; - bytes[0] = byte4; - return bytes; - } - } - else - { - byte[] bytes = new byte[5]; - bytes[4] = (byte)value; - bytes[3] = byte6; - bytes[2] = byte5; - bytes[1] = byte4; - bytes[0] = byte3; - return bytes; - } - } - else - { - byte[] bytes = new byte[6]; - bytes[5] = (byte)value; - bytes[4] = byte6; - bytes[3] = byte5; - bytes[2] = byte4; - bytes[1] = byte3; - bytes[0] = byte2; - return bytes; - } - } - else - { - byte[] bytes = new byte[7]; - bytes[6] = (byte)value; - bytes[5] = byte6; - bytes[4] = byte5; - bytes[3] = byte4; - bytes[2] = byte3; - bytes[1] = byte2; - bytes[0] = byte1; - return bytes; - } - } - else - { - byte[] bytes = new byte[8]; - bytes[7] = (byte)value; - bytes[6] = byte6; - bytes[5] = byte5; - bytes[4] = byte4; - bytes[3] = byte3; - bytes[2] = byte2; - bytes[1] = byte1; - bytes[0] = byte0; - return bytes; - } + // Min 7 bytes as we still want a byte if the value is 0. + var start = Math.Min(BitOperations.LeadingZeroCount((ulong)value) / sizeof(long), sizeof(long) - 1); + // We create the span over the out value to ensure the span stack space remains valid. + buffer = BitConverter.IsLittleEndian ? BinaryPrimitives.ReverseEndianness(value) : value; + ReadOnlySpan span = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref buffer, 1)); + return span[start..]; } + public static byte[] ToBigEndianByteArrayWithoutLeadingZeros(this long value) + => value.ToBigEndianSpanWithoutLeadingZeros(out _).ToArray(); + public static byte[] ToBigEndianByteArray(this long value) { byte[] bytes = BitConverter.GetBytes(value); diff --git a/src/Nethermind/Nethermind.Core/IKeyValueStore.cs b/src/Nethermind/Nethermind.Core/IKeyValueStore.cs index 717ae542c71..0c09710b712 100644 --- a/src/Nethermind/Nethermind.Core/IKeyValueStore.cs +++ b/src/Nethermind/Nethermind.Core/IKeyValueStore.cs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: LGPL-3.0-only using System; -using System.Buffers; -using Nethermind.Core.Buffers; using Nethermind.Core.Extensions; namespace Nethermind.Core diff --git a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs index d4f6e4a46cc..906b39acf45 100644 --- a/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs +++ b/src/Nethermind/Nethermind.Core/KeyValueStoreExtensions.cs @@ -69,10 +69,10 @@ public static bool KeyExists(this IReadOnlyKeyValueStore db, Hash256 key) public static bool KeyExists(this IReadOnlyKeyValueStore db, long key) { - return db.KeyExists(key.ToBigEndianByteArrayWithoutLeadingZeros()); + return db.KeyExists(key.ToBigEndianSpanWithoutLeadingZeros(out _)); } - public static byte[]? Get(this IReadOnlyKeyValueStore db, long key) => db[key.ToBigEndianByteArrayWithoutLeadingZeros()]; + public static byte[]? Get(this IReadOnlyKeyValueStore db, long key) => db[key.ToBigEndianSpanWithoutLeadingZeros(out _)]; /// /// @@ -80,7 +80,7 @@ public static bool KeyExists(this IReadOnlyKeyValueStore db, long key) /// /// /// Can return null or empty Span on missing key - public static Span GetSpan(this IReadOnlyKeyValueStore db, long key) => db.GetSpan(key.ToBigEndianByteArrayWithoutLeadingZeros()); + public static Span GetSpan(this IReadOnlyKeyValueStore db, long key) => db.GetSpan(key.ToBigEndianSpanWithoutLeadingZeros(out _)); public static MemoryManager? GetOwnedMemory(this IReadOnlyKeyValueStore db, ReadOnlySpan key) { @@ -140,7 +140,7 @@ public static void Delete(this IWriteOnlyKeyValueStore db, Hash256 key) public static void Delete(this IWriteOnlyKeyValueStore db, long key) { - db.Remove(key.ToBigEndianByteArrayWithoutLeadingZeros()); + db.Remove(key.ToBigEndianSpanWithoutLeadingZeros(out _)); } [SkipLocalsInit] @@ -153,7 +153,7 @@ public static void Delete(this IWriteOnlyKeyValueStore db, long blockNumber, Has public static void Set(this IWriteOnlyKeyValueStore db, long key, byte[] value) { - db[key.ToBigEndianByteArrayWithoutLeadingZeros()] = value; + db[key.ToBigEndianSpanWithoutLeadingZeros(out _)] = value; } #endregion diff --git a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs index 8b5ac589718..8427e7f2d98 100644 --- a/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs +++ b/src/Nethermind/Nethermind.Db.Rocks/DbOnTheRocks.cs @@ -11,7 +11,6 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Channels; using System.Threading.Tasks; using ConcurrentCollections; using Nethermind.Config; diff --git a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs index d801f521148..ba068b85dfb 100644 --- a/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs +++ b/src/Nethermind/Nethermind.Db/Blooms/BloomStorage.cs @@ -213,7 +213,7 @@ public void Migrate(IEnumerable headers) private void Set(Hash256 key, long value) { - _bloomInfoDb.Set(key, value.ToBigEndianByteArrayWithoutLeadingZeros()); + _bloomInfoDb.PutSpan(key.Bytes, value.ToBigEndianSpanWithoutLeadingZeros(out _)); } public void Dispose() diff --git a/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs b/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs index 88694f12b15..1042f94031a 100644 --- a/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs +++ b/src/Nethermind/Nethermind.Serialization.Rlp/KeyValueStoreRlpExtensions.cs @@ -29,7 +29,7 @@ public static class KeyValueStoreRlpExtensions public static TItem? Get(this IReadOnlyKeyValueStore db, long key, IRlpStreamDecoder? decoder, LruCache? cache = null, RlpBehaviors rlpBehaviors = RlpBehaviors.None, bool shouldCache = true) where TItem : class { - byte[] keyDb = key.ToBigEndianByteArrayWithoutLeadingZeros(); + ReadOnlySpan keyDb = key.ToBigEndianSpanWithoutLeadingZeros(out _); return Get(db, key, keyDb, decoder, cache, rlpBehaviors, shouldCache); }