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-1 Classes into Different Library - Neo.IO #3387

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 23 additions & 33 deletions src/Neo/IO/Caching/Cache.cs → src/Neo.IO/Caching/Cache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,21 @@

namespace Neo.IO.Caching
{
internal abstract class Cache<TKey, TValue> : ICollection<TValue>, IDisposable
internal abstract class Cache<TKey, TValue>
(int max_capacity, IEqualityComparer<TKey>? comparer = null) : ICollection<TValue>, IDisposable
where TKey : notnull
{
protected class CacheItem
(TKey key, TValue value)
{
public readonly TKey Key;
public readonly TValue Value;
public readonly DateTime Time;

public CacheItem(TKey key, TValue value)
{
Key = key;
Value = value;
Time = TimeProvider.Current.UtcNow;
}
public readonly TKey Key = key;
public readonly TValue Value = value;
public readonly DateTime Time = DateTime.UtcNow;
}

protected readonly ReaderWriterLockSlim RwSyncRootLock = new(LockRecursionPolicy.SupportsRecursion);
protected readonly Dictionary<TKey, CacheItem> InnerDictionary;
private readonly int max_capacity;
protected readonly Dictionary<TKey, CacheItem> InnerDictionary = new Dictionary<TKey, CacheItem>(comparer);
private readonly int _max_capacity = max_capacity;

public TValue this[TKey key]
{
Expand All @@ -44,7 +40,7 @@ public TValue this[TKey key]
RwSyncRootLock.EnterReadLock();
try
{
if (!InnerDictionary.TryGetValue(key, out CacheItem item)) throw new KeyNotFoundException();
if (!InnerDictionary.TryGetValue(key, out CacheItem? item)) throw new KeyNotFoundException();
OnAccess(item);
return item.Value;
}
Expand Down Expand Up @@ -73,15 +69,9 @@ public int Count

public bool IsReadOnly => false;

public Cache(int max_capacity, IEqualityComparer<TKey> comparer = null)
{
this.max_capacity = max_capacity;
InnerDictionary = new Dictionary<TKey, CacheItem>(comparer);
}

public void Add(TValue item)
{
TKey key = GetKeyForItem(item);
var key = GetKeyForItem(item);
RwSyncRootLock.EnterWriteLock();
try
{
Expand All @@ -95,16 +85,16 @@ public void Add(TValue item)

private void AddInternal(TKey key, TValue item)
{
if (InnerDictionary.TryGetValue(key, out CacheItem cacheItem))
if (InnerDictionary.TryGetValue(key, out CacheItem? cacheItem))
{
OnAccess(cacheItem);
}
else
{
if (InnerDictionary.Count >= max_capacity)
if (InnerDictionary.Count >= _max_capacity)
{
//TODO: Perform a performance test on the PLINQ query to determine which algorithm is better here (parallel or not)
foreach (CacheItem item_del in InnerDictionary.Values.AsParallel().OrderBy(p => p.Time).Take(InnerDictionary.Count - max_capacity + 1))
foreach (var item_del in InnerDictionary.Values.AsParallel().OrderBy(p => p.Time).Take(InnerDictionary.Count - _max_capacity + 1))
{
RemoveInternal(item_del);
}
Expand All @@ -118,9 +108,9 @@ public void AddRange(IEnumerable<TValue> items)
RwSyncRootLock.EnterWriteLock();
try
{
foreach (TValue item in items)
foreach (var item in items)
{
TKey key = GetKeyForItem(item);
var key = GetKeyForItem(item);
AddInternal(key, item);
}
}
Expand All @@ -135,7 +125,7 @@ public void Clear()
RwSyncRootLock.EnterWriteLock();
try
{
foreach (CacheItem item_del in InnerDictionary.Values.ToArray())
foreach (var item_del in InnerDictionary.Values.ToArray())
{
RemoveInternal(item_del);
}
Expand All @@ -151,7 +141,7 @@ public bool Contains(TKey key)
RwSyncRootLock.EnterReadLock();
try
{
if (!InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) return false;
if (!InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) return false;
OnAccess(cacheItem);
return true;
}
Expand All @@ -171,7 +161,7 @@ public void CopyTo(TValue[] array, int arrayIndex)
if (array == null) throw new ArgumentNullException();
if (arrayIndex < 0) throw new ArgumentOutOfRangeException();
if (arrayIndex + InnerDictionary.Count > array.Length) throw new ArgumentException();
foreach (TValue item in this)
foreach (var item in this)
{
array[arrayIndex++] = item;
}
Expand All @@ -188,7 +178,7 @@ public IEnumerator<TValue> GetEnumerator()
RwSyncRootLock.EnterReadLock();
try
{
foreach (TValue item in InnerDictionary.Values.Select(p => p.Value))
foreach (var item in InnerDictionary.Values.Select(p => p.Value))
{
yield return item;
}
Expand All @@ -211,7 +201,7 @@ public bool Remove(TKey key)
RwSyncRootLock.EnterWriteLock();
try
{
if (!InnerDictionary.TryGetValue(key, out CacheItem cacheItem)) return false;
if (!InnerDictionary.TryGetValue(key, out CacheItem? cacheItem)) return false;
RemoveInternal(cacheItem);
return true;
}
Expand Down Expand Up @@ -242,7 +232,7 @@ public bool TryGet(TKey key, out TValue item)
RwSyncRootLock.EnterReadLock();
try
{
if (InnerDictionary.TryGetValue(key, out CacheItem cacheItem))
if (InnerDictionary.TryGetValue(key, out CacheItem? cacheItem))
{
OnAccess(cacheItem);
item = cacheItem.Value;
Expand All @@ -253,7 +243,7 @@ public bool TryGet(TKey key, out TValue item)
{
RwSyncRootLock.ExitReadLock();
}
item = default;
item = default!;
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,10 @@

namespace Neo.IO.Caching
{
internal abstract class FIFOCache<TKey, TValue> : Cache<TKey, TValue>
internal abstract class FIFOCache<TKey, TValue>
(int max_capacity, IEqualityComparer<TKey>? comparer = null) : Cache<TKey, TValue>(max_capacity, comparer)
where TKey : notnull
{
public FIFOCache(int max_capacity, IEqualityComparer<TKey> comparer = null)
: base(max_capacity, comparer)
{
}

protected override void OnAccess(CacheItem item)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ class HashSetCache<T> : IReadOnlyCollection<T> where T : IEquatable<T>
/// <summary>
/// Sets where the Hashes are stored
/// </summary>
private readonly LinkedList<HashSet<T>> sets = new();
private readonly LinkedList<HashSet<T>> _sets = new();

/// <summary>
/// Maximum capacity of each bucket inside each HashSet of <see cref="sets"/>.
/// Maximum capacity of each bucket inside each HashSet of <see cref="_sets"/>.
/// </summary>
private readonly int bucketCapacity;
private readonly int _bucketCapacity;

/// <summary>
/// Maximum number of buckets for the LinkedList, meaning its maximum cardinality.
/// </summary>
private readonly int maxBucketCount;
private readonly int _maxBucketCount;

/// <summary>
/// Entry count
Expand All @@ -43,32 +43,32 @@ public HashSetCache(int bucketCapacity, int maxBucketCount = 10)
if (maxBucketCount <= 0) throw new ArgumentOutOfRangeException($"{nameof(maxBucketCount)} should be greater than 0");

Count = 0;
this.bucketCapacity = bucketCapacity;
this.maxBucketCount = maxBucketCount;
sets.AddFirst(new HashSet<T>());
_bucketCapacity = bucketCapacity;
_maxBucketCount = maxBucketCount;
_sets.AddFirst([]);
}

public bool Add(T item)
{
if (Contains(item)) return false;
Count++;
if (sets.First.Value.Count < bucketCapacity) return sets.First.Value.Add(item);
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)
_sets.AddFirst(newSet);
if (_sets.Count > _maxBucketCount)
{
Count -= sets.Last.Value.Count;
sets.RemoveLast();
Count -= _sets.Last?.Value.Count ?? 0;
_sets.RemoveLast();
}
return true;
}

public bool Contains(T item)
{
foreach (var set in sets)
foreach (var set in _sets)
{
if (set.Contains(item)) return true;
}
Expand All @@ -77,17 +77,17 @@ public bool Contains(T item)

public void ExceptWith(IEnumerable<T> items)
{
List<HashSet<T>> removeList = null;
List<HashSet<T>> removeList = default!;
foreach (var item in items)
{
foreach (var set in sets)
foreach (var set in _sets)
{
if (set.Remove(item))
{
Count--;
if (set.Count == 0)
{
removeList ??= new List<HashSet<T>>();
removeList ??= [];
removeList.Add(set);
}
break;
Expand All @@ -97,13 +97,13 @@ public void ExceptWith(IEnumerable<T> items)
if (removeList == null) return;
foreach (var set in removeList)
{
sets.Remove(set);
_sets.Remove(set);
}
}

public IEnumerator<T> GetEnumerator()
{
foreach (var set in sets)
foreach (var set in _sets)
{
foreach (var item in set)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ public void Enqueue(T item)
{
if (_array.Length == _count)
{
int newSize = _array.Length * GrowthFactor;
var newSize = _array.Length * GrowthFactor;
if (_head == 0)
{
Array.Resize(ref _array, newSize);
}
else
{
T[] buffer = new T[newSize];
var buffer = new T[newSize];
Array.Copy(_array, _head, buffer, 0, _array.Length - _head);
Array.Copy(_array, 0, buffer, _array.Length - _head, _head);
_array = buffer;
Expand Down Expand Up @@ -127,7 +127,7 @@ public bool TryPeek(out T item)
{
if (_count == 0)
{
item = default;
item = default!;
return false;
}
else
Expand All @@ -145,7 +145,7 @@ public T Dequeue()
{
if (_count == 0)
throw new InvalidOperationException("The queue is empty");
T result = _array[_head];
var result = _array[_head];
++_head;
_head %= _array.Length;
--_count;
Expand All @@ -161,7 +161,7 @@ public bool TryDequeue(out T item)
{
if (_count == 0)
{
item = default;
item = default!;
return false;
}
else
Expand Down Expand Up @@ -194,7 +194,7 @@ public void TrimExcess()
}
else if (_array.Length * TrimThreshold >= _count)
{
T[] arr = new T[_count];
var arr = new T[_count];
CopyTo(arr, 0);
_array = arr;
_head = 0;
Expand Down Expand Up @@ -228,14 +228,14 @@ public void CopyTo(T[] array, int arrayIndex)
/// <returns>An array containing the queue's items</returns>
public T[] ToArray()
{
T[] result = new T[_count];
var result = new T[_count];
CopyTo(result, 0);
return result;
}

public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < _count; i++)
for (var i = 0; i < _count; i++)
yield return _array[(_head + i) % _array.Length];
}

Expand Down
Loading
Loading