Skip to content

Commit

Permalink
Replace function exceptwith and unionwith with faster functions (#1204)
Browse files Browse the repository at this point in the history
  • Loading branch information
Qiao-Jin authored and shargon committed Nov 8, 2019
1 parent 940c829 commit af85f3c
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 9 deletions.
17 changes: 17 additions & 0 deletions neo.UnitTests/UT_FifoSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ public void FifoSetTest()
Assert.IsTrue(set.Add(c));

CollectionAssert.AreEqual(set.ToArray(), new UInt256[] { a, c });

set = new FIFOSet<UInt256>(10)
{
a,
c
};
var bb = set.ToArray();
set.ExceptWith(new UInt256[] { a });
CollectionAssert.AreEqual(set.ToArray(), new UInt256[] { c });

set = new FIFOSet<UInt256>(10)
{
a,
c
};
set.ExceptWith(new UInt256[] { c });
CollectionAssert.AreEqual(set.ToArray(), new UInt256[] { a });
}
}
}
40 changes: 39 additions & 1 deletion neo/Helper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Neo.IO.Caching;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
Expand Down Expand Up @@ -52,6 +53,43 @@ internal static int GetLowestSetBit(this BigInteger i)
throw new Exception();
}

internal static void Remove<T>(this HashSet<T> set, ISet<T> other)
{
if (set.Count > other.Count)
{
set.ExceptWith(other);
}
else
{
set.RemoveWhere(u => other.Contains(u));
}
}

internal static void Remove<T>(this HashSet<T> set, FIFOSet<T> other)
where T : IEquatable<T>
{
if (set.Count > other.Count)
{
set.ExceptWith(other);
}
else
{
set.RemoveWhere(u => other.Contains(u));
}
}

internal static void Remove<T, V>(this HashSet<T> set, IReadOnlyDictionary<T, V> other)
{
if (set.Count > other.Count)
{
set.ExceptWith(other.Keys);
}
else
{
set.RemoveWhere(u => other.ContainsKey(u));
}
}

internal static string GetVersion(this Assembly assembly)
{
CustomAttributeData attribute = assembly.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(AssemblyInformationalVersionAttribute));
Expand Down
10 changes: 6 additions & 4 deletions neo/IO/Caching/FIFOSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

namespace Neo.IO.Caching
{
internal class FIFOSet<T> : IEnumerable<T> where T : IEquatable<T>
internal class FIFOSet<T> : IReadOnlyCollection<T> where T : IEquatable<T>
{
private readonly int maxCapacity;
private readonly int removeCount;
private readonly OrderedDictionary dictionary;

public int Count => dictionary.Count;

public FIFOSet(int maxCapacity, decimal batchSize = 0.1m)
{
if (maxCapacity <= 0) throw new ArgumentOutOfRangeException(nameof(maxCapacity));
Expand Down Expand Up @@ -46,11 +48,11 @@ public bool Contains(T item)
return dictionary.Contains(item);
}

public void ExceptWith(IEnumerable<UInt256> hashes)
public void ExceptWith(IEnumerable<T> entries)
{
foreach (var hash in hashes)
foreach (var entry in entries)
{
dictionary.Remove(hash);
dictionary.Remove(entry);
}
}

Expand Down
8 changes: 4 additions & 4 deletions neo/Network/P2P/TaskManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ private void OnNewTasks(InvPayload payload)
return;
}
HashSet<UInt256> hashes = new HashSet<UInt256>(payload.Hashes);
hashes.ExceptWith(knownHashes);
hashes.Remove(knownHashes);
if (payload.Type == InventoryType.Block)
session.AvailableTasks.UnionWith(hashes.Where(p => globalTasks.ContainsKey(p)));

hashes.ExceptWith(globalTasks.Keys);
hashes.Remove(globalTasks);
if (hashes.Count == 0)
{
RequestTasks(session);
Expand Down Expand Up @@ -210,7 +210,7 @@ private void RequestTasks(TaskSession session)
if (session.HasTask) return;
if (session.AvailableTasks.Count > 0)
{
session.AvailableTasks.ExceptWith(knownHashes);
session.AvailableTasks.Remove(knownHashes);
session.AvailableTasks.RemoveWhere(p => Blockchain.Singleton.ContainsBlock(p));
HashSet<UInt256> hashes = new HashSet<UInt256>(session.AvailableTasks);
if (hashes.Count > 0)
Expand All @@ -220,7 +220,7 @@ private void RequestTasks(TaskSession session)
if (!IncrementGlobalTask(hash))
hashes.Remove(hash);
}
session.AvailableTasks.ExceptWith(hashes);
session.AvailableTasks.Remove(hashes);
foreach (UInt256 hash in hashes)
session.Tasks[hash] = DateTime.UtcNow;
foreach (InvPayload group in InvPayload.CreateGroup(InventoryType.Block, hashes.ToArray()))
Expand Down
2 changes: 2 additions & 0 deletions neo/UIntBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;

namespace Neo
{
Expand Down Expand Up @@ -110,6 +111,7 @@ void ISerializable.Serialize(BinaryWriter writer)
/// <summary>
/// Method ToArray() returns the byte array data_bytes, which stores the little-endian unsigned int
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public byte[] ToArray()
{
return data_bytes;
Expand Down

0 comments on commit af85f3c

Please sign in to comment.