LaquaiLib.Collections.HashList
1.0.0
See the version list below for details.
dotnet add package LaquaiLib.Collections.HashList --version 1.0.0
NuGet\Install-Package LaquaiLib.Collections.HashList -Version 1.0.0
<PackageReference Include="LaquaiLib.Collections.HashList" Version="1.0.0" />
<PackageVersion Include="LaquaiLib.Collections.HashList" Version="1.0.0" />
<PackageReference Include="LaquaiLib.Collections.HashList" />
paket add LaquaiLib.Collections.HashList --version 1.0.0
#r "nuget: LaquaiLib.Collections.HashList, 1.0.0"
#:package LaquaiLib.Collections.HashList@1.0.0
#addin nuget:?package=LaquaiLib.Collections.HashList&version=1.0.0
#tool nuget:?package=LaquaiLib.Collections.HashList&version=1.0.0
LaquaiLib.HashList
Implements a simple hash list, effectively a cross between some set data structure (to guarantee uniqueness of elements) and a list (to keep track of insertion order).
Right now, there's two strategies for the non-concurrent version which are not directly surfaced. Access them through the HashList static type which create instances of those strategies. They differ in which operation is more optimized: either indexing and enumeration or deletion. Insertion and Contains checks always offer set-like performance, but a choice must be made for Remove, IndexOf etc.
- Specifying
bool optimizeForRemove: truereturns an impl optimized forO(1)removals, but withO(N / 2)indexing and enumeration. - Specifying
bool optimizeForRemove: false(the default when using an overload of the factory method that doesn't have the parameter) returns an impl optimized forO(1)indexing and enumeration, but withO(N)removals.
Note that direct enumeration via foreach isn't affected as badly, merely differing by a few additional indirections through internal structures.
The concurrent variant is merely a wrapper for any of the above strategies since concurrency is orthogonal to the choice of optimization strategy. Reads never collide and are allowed concurrently.
- Snapshot enumeration: prevents holding the lock during iteration (which would cause deadlocks on any write attempts mid-enumeration), at the cost of an allocation per enumeration.
Mutate(Action<HashList<T>>): executes the passed delegate under a write lock, allowing compound operations that require atomicity.
You should, however, think really well of why you're reaching for the concurrent variant. Concurrent writes make keeping track of insertion order meaningless since the order in which writers acquire the internal lock is non-deterministic. If writes are sufficiently rare, you might be better off with the non-concurrent variant, locking around writes yourself and avoiding all locking overhead on read paths. Even better, if you're building once and then never modifying again, choose the non-concurrent variant, then copy and store that (perhaps using a ReadOnlyCollection<> over that copy if you're sharing to unknown consumers).
Contact me on Discord @ eyeoftheenemy or open an issue here if you have any questions, suggestions or want to contribute!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.