diff --git a/CHANGELOG.md b/CHANGELOG.md index 9505ca2..3647648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Singulink Collections Version History +## V3.0 +### Singulink.Collections +- Breaking change: Deprecated `Singulink.Collections.Abstractions` package. Types have been merged into the main `Singulink.Collections` package. +- Performance improvements to `ListDictionary<,>.ValueList` and `HashSetDictionary<,>.ValueSet`. +- Minor documentation fixes. + ## V2.0 ### All packages - Removed support for end-of-life .NET and .NET Framework runtimes with a build warning if used on an unsupported runtime diff --git a/README.md b/README.md index e7717a2..77e9f70 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The following collections are included in the package: - `Map`: Collection of two types of values that map between each other in a bidirectional one-to-one relationship. - `ReadOnlyHashSet`: Fast read-only wrapper around a HashSet (instead of going through `ISet<>`). - `ReadOnlyList`: Fast read-only wrapper around a List (instead of going through `IList<>`). -- A full set of interfaces for the new collections as well as an `IReadOnlySet<>` polyfill for .NET Standard. +- A full set of interfaces and read-only wrappers for the new collections as well as an `IReadOnlySet<>` polyfill for .NET Standard. **Singulink.Collections.Weak** provides a set of collection classes that store weak references to values so that the garbage collector is free to reclaim the memory they use when they aren't being referenced anymore. The values returned by the collections will never be `null` - if the value was garbage collected then the collection behaves as if the value was removed from the collection. diff --git a/Source/Singulink.Collections/HashSetDictionary.ReadOnlyValueSet.cs b/Source/Singulink.Collections/HashSetDictionary.ReadOnlyValueSet.cs index 40d58be..3b92a6d 100644 --- a/Source/Singulink.Collections/HashSetDictionary.ReadOnlyValueSet.cs +++ b/Source/Singulink.Collections/HashSetDictionary.ReadOnlyValueSet.cs @@ -10,7 +10,7 @@ namespace Singulink.Collections; public partial class HashSetDictionary { /// - /// Represents a synchronized read-only set of values associcated with a key in a . + /// Represents a synchronized read-only set of values associated with a key in a . /// public class ReadOnlyValueSet : ISet, IReadOnlySet, IEquatable { @@ -133,13 +133,8 @@ private protected HashSet GetSet() HashSet UpdateAndGetValues() { if (_dictionary.TryGetValues(_key, out var valueSet)) - { _lastSet = valueSet._lastSet; - if (_transientReadOnlySet != null) - _transientReadOnlySet.WrappedSet = _lastSet; - } - return _lastSet; } } diff --git a/Source/Singulink.Collections/HashSetDictionary.ValueSet.cs b/Source/Singulink.Collections/HashSetDictionary.ValueSet.cs index eddca51..558a84e 100644 --- a/Source/Singulink.Collections/HashSetDictionary.ValueSet.cs +++ b/Source/Singulink.Collections/HashSetDictionary.ValueSet.cs @@ -9,7 +9,7 @@ namespace Singulink.Collections; public partial class HashSetDictionary { /// - /// Represents a dictionary synchronized set of values associcated with a key in a . + /// Represents a dictionary synchronized set of values associated with a key in a . /// public sealed class ValueSet : ReadOnlyValueSet, ISet, IReadOnlyCollectionProvider { diff --git a/Source/Singulink.Collections/ListDictionary.ReadOnlyValueList.cs b/Source/Singulink.Collections/ListDictionary.ReadOnlyValueList.cs index ca9501c..1790265 100644 --- a/Source/Singulink.Collections/ListDictionary.ReadOnlyValueList.cs +++ b/Source/Singulink.Collections/ListDictionary.ReadOnlyValueList.cs @@ -10,7 +10,7 @@ namespace Singulink.Collections; public partial class ListDictionary { /// - /// Represents a synchronized read-only list of values associcated with a key in a . + /// Represents a synchronized read-only list of values associated with a key in a . /// public class ReadOnlyValueList : IList, IReadOnlyList, IEquatable { @@ -219,17 +219,11 @@ private protected List GetList() { return _lastList.Count > 0 ? _lastList : UpdateAndGetValues(); - [MethodImpl(MethodImplOptions.NoInlining)] List UpdateAndGetValues() { if (_dictionary.TryGetValues(_key, out var valueList)) - { _lastList = valueList._lastList; - if (_transientReadOnlyList != null) - _transientReadOnlyList.WrappedList = _lastList; - } - return _lastList; } } diff --git a/Source/Singulink.Collections/ListDictionary.ValueList.cs b/Source/Singulink.Collections/ListDictionary.ValueList.cs index 6d3ac81..bc3bc8e 100644 --- a/Source/Singulink.Collections/ListDictionary.ValueList.cs +++ b/Source/Singulink.Collections/ListDictionary.ValueList.cs @@ -10,13 +10,13 @@ namespace Singulink.Collections; public partial class ListDictionary { /// - /// Represents a dictionary synchronized list of values associcated with a key in a . + /// Represents a dictionary synchronized list of values associated with a key in a . /// public sealed class ValueList : ReadOnlyValueList, IList, IReadOnlyCollectionProvider { private ReadOnlyValueList? _readOnlyValueList; - internal ValueList(ListDictionary dictionary, TKey key) : base(dictionary, key, new()) { } + internal ValueList(ListDictionary dictionary, TKey key) : base(dictionary, key, []) { } /// /// Gets or sets the item at the specified index. diff --git a/Source/Singulink.Collections/ListDictionary.cs b/Source/Singulink.Collections/ListDictionary.cs index 39506e6..ad00adb 100644 --- a/Source/Singulink.Collections/ListDictionary.cs +++ b/Source/Singulink.Collections/ListDictionary.cs @@ -199,7 +199,7 @@ public int GetValueCount(TKey key) /// Ensures that the dictionary can hold up to a specified number of key/value list pairs without any further expansion of its backing storage. /// /// The number of key/value list pairs. - /// The currect capacity of the dictionary. + /// The current capacity of the dictionary. /// Capacity specified is less than 0. public int EnsureCapacity(int capacity) { @@ -299,7 +299,7 @@ private static void DebugValid(ValueList valueList) /// bool ICollection>>.Contains(KeyValuePair> item) { - return item.Value is ValueList valueList && TryGetValues(item.Key, out var exisingValueList) && valueList == exisingValueList; + return TryGetValues(item.Key, out var valueList) && valueList.Equals(item.Value); } /// diff --git a/Source/Singulink.Collections/ReadOnlyHashSet.cs b/Source/Singulink.Collections/ReadOnlyHashSet.cs index c98b01f..cc434e6 100644 --- a/Source/Singulink.Collections/ReadOnlyHashSet.cs +++ b/Source/Singulink.Collections/ReadOnlyHashSet.cs @@ -11,7 +11,7 @@ public class ReadOnlyHashSet : ISet, IReadOnlySet /// /// Gets an empty read-only hash set. /// - public static ReadOnlyHashSet Empty { get; } = new ReadOnlyHashSet(new HashSet()); + public static ReadOnlyHashSet Empty { get; } = new ReadOnlyHashSet([]); private HashSet _set; diff --git a/Source/Singulink.Collections/ReadOnlyList.cs b/Source/Singulink.Collections/ReadOnlyList.cs index a75c06e..e331393 100644 --- a/Source/Singulink.Collections/ReadOnlyList.cs +++ b/Source/Singulink.Collections/ReadOnlyList.cs @@ -10,7 +10,7 @@ public class ReadOnlyList : IList, IReadOnlyList /// /// Gets an empty read-only list. /// - public static ReadOnlyList Empty { get; } = new ReadOnlyList(new List()); + public static ReadOnlyList Empty { get; } = new ReadOnlyList([]); private List _list; diff --git a/Tests/Singulink.Collections.Weak.Tests/NoGCRegion.cs b/Tests/Singulink.Collections.Weak.Tests/NoGCRegion.cs index 5b92bd4..9368013 100644 --- a/Tests/Singulink.Collections.Weak.Tests/NoGCRegion.cs +++ b/Tests/Singulink.Collections.Weak.Tests/NoGCRegion.cs @@ -1,7 +1,5 @@ #pragma warning disable CA1815 // Override equals and operator equals on value types -using System.Security.Cryptography; - namespace Singulink.Collections.Weak.Tests; public struct NoGCRegion : IDisposable