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

[Move] Part-2 Classes into Different Library - Neo.IO #3388

Merged
merged 12 commits into from
Jul 16, 2024
91 changes: 91 additions & 0 deletions src/Neo.Extensions/BigIntegerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// BigIntegerExtensions.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace Neo.Extensions
{
public static class BigIntegerExtensions
{
internal static int GetLowestSetBit(this BigInteger i)
{
if (i.Sign == 0)
return -1;
var b = i.ToByteArray();
var w = 0;
while (b[w] == 0)
w++;
for (var x = 0; x < 8; x++)
if ((b[w] & 1 << x) > 0)
return x + w * 8;
throw new Exception();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static BigInteger Mod(this BigInteger x, BigInteger y)
{
x %= y;
if (x.Sign < 0)
x += y;
return x;
}

internal static BigInteger ModInverse(this BigInteger a, BigInteger n)
{
BigInteger i = n, v = 0, d = 1;
while (a > 0)
{
BigInteger t = i / a, x = a;
a = i % x;
i = x;
x = d;
d = v - t * x;
v = x;
}
v %= n;
if (v < 0) v = (v + n) % n;
return v;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TestBit(this BigInteger i, int index)
{
return (i & (BigInteger.One << index)) > BigInteger.Zero;
}

/// <summary>
/// Finds the sum of the specified integers.
/// </summary>
/// <param name="source">The specified integers.</param>
/// <returns>The sum of the integers.</returns>
public static BigInteger Sum(this IEnumerable<BigInteger> source)
{
var sum = BigInteger.Zero;
foreach (var bi in source) sum += bi;
return sum;
}

/// <summary>
/// Converts a <see cref="BigInteger"/> to byte array and eliminates all the leading zeros.
/// </summary>
/// <param name="i">The <see cref="BigInteger"/> to convert.</param>
/// <returns>The converted byte array.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte[] ToByteArrayStandard(this BigInteger i)
{
if (i.IsZero) return Array.Empty<byte>();
return i.ToByteArray();
}
}
}
2 changes: 1 addition & 1 deletion src/Neo.Extensions/Neo.Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ItemGroup>
<InternalsVisibleTo Include="Neo" />
<InternalsVisibleTo Include="Neo.IO" />
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
<InternalsVisibleTo Include="Neo.UnitTests" />
cschuchardt88 marked this conversation as resolved.
Show resolved Hide resolved
shargon marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/Neo.GUI/GUI/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// modifications are permitted.

using Akka.Actor;
using Neo.Extensions;
using Neo.IO.Actors;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/IO/Actors/Idle.cs → src/Neo.IO/Actors/Idle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ namespace Neo.IO.Actors
{
internal sealed class Idle
{
public static Idle Instance { get; } = new Idle();
public static Idle Instance { get; } = new();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,17 @@

namespace Neo.IO.Caching
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Type</param>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
internal class ReflectionCacheAttribute : Attribute
internal class ReflectionCacheAttribute
(Type type) : Attribute
{
/// <summary>
/// Type
/// </summary>
public Type Type { get; }

/// <summary>
/// Constructor
/// </summary>
/// <param name="type">Type</param>
public ReflectionCacheAttribute(Type type)
{
Type = type;
}
public Type Type { get; } = type;
}
}
1 change: 1 addition & 0 deletions src/Neo/Cryptography/ECC/ECFieldElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Extensions;
using System;
using System.Numerics;

Expand Down
1 change: 1 addition & 0 deletions src/Neo/Cryptography/ECC/ECPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Extensions;
using Neo.IO;
using Neo.IO.Caching;
using System;
Expand Down
70 changes: 0 additions & 70 deletions src/Neo/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,6 @@ public static byte[] Concat(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b)
return buffer;
}

internal static int GetLowestSetBit(this BigInteger i)
{
if (i.Sign == 0)
return -1;
byte[] b = i.ToByteArray();
int w = 0;
while (b[w] == 0)
w++;
for (int x = 0; x < 8; x++)
if ((b[w] & 1 << x) > 0)
return x + w * 8;
throw new Exception();
}

internal static void Remove<T>(this HashSet<T> set, ISet<T> other)
{
if (set.Count > other.Count)
Expand Down Expand Up @@ -157,32 +143,6 @@ public static byte[] HexToBytes(this string value)
return result;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static BigInteger Mod(this BigInteger x, BigInteger y)
{
x %= y;
if (x.Sign < 0)
x += y;
return x;
}

internal static BigInteger ModInverse(this BigInteger a, BigInteger n)
{
BigInteger i = n, v = 0, d = 1;
while (a > 0)
{
BigInteger t = i / a, x = a;
a = i % x;
i = x;
x = d;
d = v - t * x;
v = x;
}
v %= n;
if (v < 0) v = (v + n) % n;
return v;
}

internal static BigInteger NextBigInteger(this Random rand, int sizeInBits)
{
if (sizeInBits < 0)
Expand All @@ -198,36 +158,6 @@ internal static BigInteger NextBigInteger(this Random rand, int sizeInBits)
return new BigInteger(b);
}

/// <summary>
/// Finds the sum of the specified integers.
/// </summary>
/// <param name="source">The specified integers.</param>
/// <returns>The sum of the integers.</returns>
public static BigInteger Sum(this IEnumerable<BigInteger> source)
{
var sum = BigInteger.Zero;
foreach (var bi in source) sum += bi;
return sum;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool TestBit(this BigInteger i, int index)
{
return (i & (BigInteger.One << index)) > BigInteger.Zero;
}

/// <summary>
/// Converts a <see cref="BigInteger"/> to byte array and eliminates all the leading zeros.
/// </summary>
/// <param name="i">The <see cref="BigInteger"/> to convert.</param>
/// <returns>The converted byte array.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte[] ToByteArrayStandard(this BigInteger i)
{
if (i.IsZero) return Array.Empty<byte>();
return i.ToByteArray();
}

/// <summary>
/// Converts a byte array to hex <see cref="string"/>.
/// </summary>
Expand Down
14 changes: 4 additions & 10 deletions src/Neo/IO/Actors/PriorityMailbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,11 @@

namespace Neo.IO.Actors
{
internal abstract class PriorityMailbox : MailboxType, IProducesMessageQueue<PriorityMessageQueue>
internal abstract class PriorityMailbox
(Settings settings, Config config) : MailboxType(settings, config), IProducesMessageQueue<PriorityMessageQueue>
{
public PriorityMailbox(Akka.Actor.Settings settings, Config config)
: base(settings, config)
{
}

public override IMessageQueue Create(IActorRef owner, ActorSystem system)
{
return new PriorityMessageQueue(ShallDrop, IsHighPriority);
}
public override IMessageQueue Create(IActorRef owner, ActorSystem system) =>
new PriorityMessageQueue(ShallDrop, IsHighPriority);

internal protected virtual bool IsHighPriority(object message) => false;
internal protected virtual bool ShallDrop(object message, IEnumerable queue) => false;
Expand Down
35 changes: 15 additions & 20 deletions src/Neo/IO/Actors/PriorityMessageQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,37 @@

namespace Neo.IO.Actors
{
internal class PriorityMessageQueue : IMessageQueue, IUnboundedMessageQueueSemantics
internal class PriorityMessageQueue
(Func<object, IEnumerable, bool> dropper, Func<object, bool> priority_generator) : IMessageQueue, IUnboundedMessageQueueSemantics
{
private readonly ConcurrentQueue<Envelope> high = new();
private readonly ConcurrentQueue<Envelope> low = new();
private readonly Func<object, IEnumerable, bool> dropper;
private readonly Func<object, bool> priority_generator;
private int idle = 1;
private readonly ConcurrentQueue<Envelope> _high = new();
private readonly ConcurrentQueue<Envelope> _low = new();
private readonly Func<object, IEnumerable, bool> _dropper = dropper;
private readonly Func<object, bool> _priority_generator = priority_generator;
private int _idle = 1;

public bool HasMessages => !high.IsEmpty || !low.IsEmpty;
public int Count => high.Count + low.Count;

public PriorityMessageQueue(Func<object, IEnumerable, bool> dropper, Func<object, bool> priority_generator)
{
this.dropper = dropper;
this.priority_generator = priority_generator;
}
public bool HasMessages => !_high.IsEmpty || !_low.IsEmpty;
public int Count => _high.Count + _low.Count;

public void CleanUp(IActorRef owner, IMessageQueue deadletters)
{
}

public void Enqueue(IActorRef receiver, Envelope envelope)
{
Interlocked.Increment(ref idle);
Interlocked.Increment(ref _idle);
if (envelope.Message is Idle) return;
if (dropper(envelope.Message, high.Concat(low).Select(p => p.Message)))
if (_dropper(envelope.Message, _high.Concat(_low).Select(p => p.Message)))
return;
ConcurrentQueue<Envelope> queue = priority_generator(envelope.Message) ? high : low;
var queue = _priority_generator(envelope.Message) ? _high : _low;
queue.Enqueue(envelope);
}

public bool TryDequeue(out Envelope envelope)
{
if (high.TryDequeue(out envelope)) return true;
if (low.TryDequeue(out envelope)) return true;
if (Interlocked.Exchange(ref idle, 0) > 0)
if (_high.TryDequeue(out envelope)) return true;
if (_low.TryDequeue(out envelope)) return true;
if (Interlocked.Exchange(ref _idle, 0) > 0)
{
envelope = new Envelope(Idle.Instance, ActorRefs.NoSender);
return true;
Expand Down
17 changes: 9 additions & 8 deletions src/Neo/IO/Caching/ReflectionCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,30 @@

namespace Neo.IO.Caching
{
internal static class ReflectionCache<T> where T : Enum
internal static class ReflectionCache<T>
where T : Enum
{
private static readonly Dictionary<T, Type> dictionary = new();
private static readonly Dictionary<T, Type> s_dictionary = [];

public static int Count => dictionary.Count;
public static int Count => s_dictionary.Count;

static ReflectionCache()
{
foreach (FieldInfo field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static))
foreach (var field in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static))
{
// Get attribute
ReflectionCacheAttribute attribute = field.GetCustomAttribute<ReflectionCacheAttribute>();
var attribute = field.GetCustomAttribute<ReflectionCacheAttribute>();
if (attribute == null) continue;

// Append to cache
dictionary.Add((T)field.GetValue(null), attribute.Type);
s_dictionary.Add((T)field.GetValue(null), attribute.Type);
}
}

public static object CreateInstance(T key, object def = null)
{
// Get Type from cache
if (dictionary.TryGetValue(key, out Type t))
if (s_dictionary.TryGetValue(key, out var t))
return Activator.CreateInstance(t);

// return null
Expand All @@ -46,7 +47,7 @@ public static object CreateInstance(T key, object def = null)

public static ISerializable CreateSerializable(T key, ReadOnlyMemory<byte> data)
{
if (dictionary.TryGetValue(key, out Type t))
if (s_dictionary.TryGetValue(key, out var t))
return data.AsSerializable(t);
return null;
}
Expand Down
8 changes: 2 additions & 6 deletions src/Neo/IO/Caching/RelayCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@

namespace Neo.IO.Caching
{
internal class RelayCache : FIFOCache<UInt256, IInventory>
internal class RelayCache
(int max_capacity) : FIFOCache<UInt256, IInventory>(max_capacity)
{
public RelayCache(int max_capacity)
: base(max_capacity)
{
}

protected override UInt256 GetKeyForItem(IInventory item)
{
return item.Hash;
Expand Down
Loading
Loading