-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Add CollectionsMarshal support for the HashSet<T>
collection
#82840
Comments
Tagging subscribers to this area: @dotnet/area-system-collections Issue DetailsBackground and motivationThe API Proposalnamespace System.Runtime.InteropServices
{
public static class CollectionsMarshal
{
public static ref T? GetValueRefOrAddDefault<T> (HashSet<T> hashSet, T item, out bool exists);
public static ref T GetValueRefOrNullRef<T> (HashSet<T> hashSet, T item);
}
} API UsageBelow is a partial implementation of a concurrent public partial class ConcurrentBoundedHashSet<T>
{
private readonly HashSet<T> _set = new();
private readonly int _boundedCapacity;
/// <summary>
/// Searches the set for a given value and returns the equal value it finds,
/// otherwise adds the given value to the set if space is available,
/// otherwise returns false.
/// </summary>
public bool TryGetOrAdd(T equalValue, out T? actualValue)
{
lock (_set)
{
if (_set.Count < _boundedCapacity)
{
ref T? valueRef = ref CollectionsMarshal.GetValueRefOrAddDefault(_set, equalValue,
out bool exists);
if (!exists) valueRef = equalValue;
actualValue = valueRef; return true;
}
else
{
ref T valueRef = ref CollectionsMarshal.GetValueRefOrNullRef(_set, equalValue);
if (!Unsafe.IsNullRef(ref valueRef))
{
actualValue = valueRef; return true;
}
else
{
actualValue = default; return false;
}
}
}
}
} Alternative DesignsNo response RisksNone that I can think of. Labels: area-System.Collections / api-suggestion.
|
The CollectionMarshal methods for Dictionary provide
|
I agree with @eiriktsarpalis; the proposed |
@eiriktsarpalis, @stephentoub you are both right. This was a poorly thought proposal. On top of the above, in the "API Usage" example the I am closing this one. |
Background and motivation
The
Dictionary<TKey,TValue>
collection was improved in .NET 6, by introducing directref
access to its values. This improvement made the collection more suitable for performance-critical applications, by reducing the number of times a key has to be hashed when adding/modifying values in the collection. For example theGetOrAdd
extension method can be implemented efficiently with a single hashing of the key. The same improvement could be made to theHashSet<T>
collection as well. AGetOrAdd
API has also been proposed for theHashSet<T>
, but that proposal was closed with a mention about addingCollectionsMarshal
support in the future. This proposal here is exactly about adding this support.API Proposal
API Usage
Below is a partial implementation of a concurrent
HashSet<T>
with bounded capacity. The proposed APIGetValueRefOrAddDefault
is used when space is available in the collection, and the proposed APIGetValueRefOrNullRef
is used when the collection is full:Alternative Designs
No response
Risks
None that I can think of.
Labels: area-System.Collections / api-suggestion.
The text was updated successfully, but these errors were encountered: