forked from neo-project/neo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use HashsetCache instead of FIFOSet for KnownHashes and SentHashes (n…
…eo-project#1389) * update * change fifoset to hashsetcache for knownhashes and senthashes * format * optimise HashSetCache * remove FIFOSet * remove FIFOSet and update ut * change List to LinkedList * remove bucket count upper limit * update exception message * Adding some comments * dotnet format * rename maxBucketCount * format * Cache count * Vitor suggestions * Update HashSetCache.cs * format * Fix * fix counting count * optimise * optimse * update List Co-authored-by: Shargon <[email protected]> Co-authored-by: Vitor Nazário Coelho <[email protected]>
- Loading branch information
Showing
6 changed files
with
148 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace Neo.IO.Caching | ||
{ | ||
public class HashSetCache<T> : IReadOnlyCollection<T> where T : IEquatable<T> | ||
{ | ||
/// <summary> | ||
/// Sets where the Hashes are stored | ||
/// </summary> | ||
private readonly LinkedList<HashSet<T>> sets = new LinkedList<HashSet<T>>(); | ||
|
||
/// <summary> | ||
/// Maximum capacity of each bucket inside each HashSet of <see cref="sets"/>. | ||
/// </summary> | ||
private readonly int bucketCapacity; | ||
|
||
/// <summary> | ||
/// Maximum number of buckets for the LinkedList, meaning its maximum cardinality. | ||
/// </summary> | ||
private readonly int maxBucketCount; | ||
|
||
/// <summary> | ||
/// Entry count | ||
/// </summary> | ||
public int Count { get; private set; } | ||
|
||
public HashSetCache(int bucketCapacity, int maxBucketCount = 10) | ||
{ | ||
if (bucketCapacity <= 0) throw new ArgumentOutOfRangeException($"{nameof(bucketCapacity)} should be greater than 0"); | ||
if (maxBucketCount <= 0) throw new ArgumentOutOfRangeException($"{nameof(maxBucketCount)} should be greater than 0"); | ||
|
||
this.Count = 0; | ||
this.bucketCapacity = bucketCapacity; | ||
this.maxBucketCount = maxBucketCount; | ||
sets.AddFirst(new HashSet<T>()); | ||
} | ||
|
||
public bool Add(T item) | ||
{ | ||
if (Contains(item)) return false; | ||
Count++; | ||
if (sets.First.Value.Count < bucketCapacity) return sets.First.Value.Add(item); | ||
var newSet = new HashSet<T> | ||
{ | ||
item | ||
}; | ||
sets.AddFirst(newSet); | ||
if (sets.Count > maxBucketCount) | ||
{ | ||
Count -= sets.Last.Value.Count; | ||
sets.RemoveLast(); | ||
} | ||
return true; | ||
} | ||
|
||
public bool Contains(T item) | ||
{ | ||
foreach (var set in sets) | ||
{ | ||
if (set.Contains(item)) return true; | ||
} | ||
return false; | ||
} | ||
|
||
public void ExceptWith(IEnumerable<T> items) | ||
{ | ||
List<HashSet<T>> removeList = null; | ||
foreach (var item in items) | ||
{ | ||
foreach (var set in sets) | ||
{ | ||
if (set.Remove(item)) | ||
{ | ||
Count--; | ||
if (set.Count == 0) | ||
{ | ||
removeList ??= new List<HashSet<T>>(); | ||
removeList.Add(set); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
if (removeList == null) return; | ||
foreach (var set in removeList) | ||
{ | ||
sets.Remove(set); | ||
} | ||
} | ||
|
||
public IEnumerator<T> GetEnumerator() | ||
{ | ||
foreach (var set in sets) | ||
{ | ||
foreach (var item in set) | ||
{ | ||
yield return item; | ||
} | ||
} | ||
} | ||
|
||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters