33namespace Internal.Utilities.Collections
44
55open System.Collections .Generic
6+ open System.Collections .Concurrent
67
78// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
89// one entry. So use two hash tables: one for the main entries and one for the overflow.
@@ -11,40 +12,51 @@ type internal HashMultiMap<'Key, 'Value
1112#if ! NO_CHECKNULLS
1213 when 'Key:not null
1314#endif
14- >( size : int , comparer : IEqualityComparer < 'Key >) =
15+ >( size : int , comparer : IEqualityComparer < 'Key >, ? useConcurrentDictionary : bool ) =
1516
16- let firstEntries = Dictionary <_, _>( size , comparer)
17+ let comparer = comparer
1718
18- let rest = Dictionary<_, _>( 3 , comparer)
19+ let firstEntries : IDictionary < _ , _ > =
20+ if defaultArg useConcurrentDictionary false then
21+ ConcurrentDictionary<_, _>( comparer)
22+ else
23+ Dictionary<_, _>( size, comparer)
1924
20- new ( comparer: IEqualityComparer< 'Key>) = HashMultiMap< 'Key, 'Value>( 11 , comparer)
25+ let rest : IDictionary < _ , _ > =
26+ if defaultArg useConcurrentDictionary false then
27+ ConcurrentDictionary<_, _>( comparer)
28+ else
29+ Dictionary<_, _>( 3 , comparer)
2130
22- new ( entries: seq< 'Key * 'Value>, comparer: IEqualityComparer< 'Key>) as x =
23- new HashMultiMap< 'Key, 'Value>( 11 , comparer)
24- then entries |> Seq.iter ( fun ( k , v ) -> x.Add( k, v))
31+ new ( comparer: IEqualityComparer< 'Key>, ?useConcurrentDictionary: bool) =
32+ HashMultiMap< 'Key, 'Value>( 11 , comparer, defaultArg useConcurrentDictionary false )
2533
26- member x.GetRest ( k ) =
34+ new ( entries: seq< 'Key * 'Value>, comparer: IEqualityComparer< 'Key>, ?useConcurrentDictionary: bool) as this =
35+ HashMultiMap< 'Key, 'Value>( 11 , comparer, defaultArg useConcurrentDictionary false )
36+ then entries |> Seq.iter ( fun ( k , v ) -> this.Add( k, v))
37+
38+ member _.GetRest ( k ) =
2739 match rest.TryGetValue k with
2840 | true , res -> res
2941 | _ -> []
3042
31- member x .Add( y , z ) =
43+ member this .Add( y , z ) =
3244 match firstEntries.TryGetValue y with
33- | true , res -> rest[ y] <- res :: x .GetRest( y)
45+ | true , res -> rest[ y] <- res :: this .GetRest( y)
3446 | _ -> ()
3547
3648 firstEntries[ y] <- z
3749
38- member x .Clear() =
50+ member _ .Clear() =
3951 firstEntries.Clear()
4052 rest.Clear()
4153
42- member x .FirstEntries = firstEntries
54+ member _ .FirstEntries = firstEntries
4355
44- member x .Rest = rest
56+ member _ .Rest = rest
4557
46- member x .Copy() =
47- let res = HashMultiMap< 'Key, 'Value>( firstEntries.Count, firstEntries.Comparer )
58+ member _ .Copy() =
59+ let res = HashMultiMap< 'Key, 'Value>( firstEntries.Count, comparer )
4860
4961 for kvp in firstEntries do
5062 res.FirstEntries.Add( kvp.Key, kvp.Value)
@@ -90,11 +102,11 @@ type internal HashMultiMap<'Key, 'Value
90102 for z in rest do
91103 f kvp.Key z
92104
93- member x .Contains( y ) = firstEntries.ContainsKey( y)
105+ member _ .Contains( y ) = firstEntries.ContainsKey( y)
94106
95- member x .ContainsKey( y ) = firstEntries.ContainsKey( y)
107+ member _ .ContainsKey( y ) = firstEntries.ContainsKey( y)
96108
97- member x .Remove( y ) =
109+ member _ .Remove( y ) =
98110 match firstEntries.TryGetValue y with
99111 // NOTE: If not ok then nothing to remove - nop
100112 | true , _ res ->
@@ -112,14 +124,14 @@ type internal HashMultiMap<'Key, 'Value
112124 | _ -> firstEntries.Remove( y) |> ignore
113125 | _ -> ()
114126
115- member x .Replace( y , z ) = firstEntries[ y] <- z
127+ member _ .Replace( y , z ) = firstEntries[ y] <- z
116128
117- member x .TryFind( y ) =
129+ member _ .TryFind( y ) =
118130 match firstEntries.TryGetValue y with
119131 | true , res -> Some res
120132 | _ -> None
121133
122- member x .Count = firstEntries.Count
134+ member _ .Count = firstEntries.Count
123135
124136 interface IEnumerable< KeyValuePair< 'Key, 'Value>> with
125137
@@ -188,6 +200,6 @@ type internal HashMultiMap<'Key, 'Value
188200 member s.CopyTo ( arr , arrIndex ) =
189201 s |> Seq.iteri ( fun j x -> arr[ arrIndex + j] <- x)
190202
191- member s .IsReadOnly = false
203+ member _ .IsReadOnly = false
192204
193205 member s.Count = s.Count
0 commit comments