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.
910[<Sealed>]
10- type internal HashMultiMap < 'Key , 'Value >( size : int , comparer : IEqualityComparer < 'Key >) =
11+ type internal HashMultiMap < 'Key , 'Value >( size : int , comparer : IEqualityComparer < 'Key >, ? useConcurrentDictionary : bool ) =
1112
12- let firstEntries = Dictionary <_, _>( size , comparer)
13+ let comparer = comparer
1314
14- let rest = Dictionary<_, _>( 3 , comparer)
15+ let firstEntries : IDictionary < _ , _ > =
16+ if defaultArg useConcurrentDictionary false then
17+ ConcurrentDictionary<_, _>( comparer)
18+ else
19+ Dictionary<_, _>( size, comparer)
1520
16- new ( comparer: IEqualityComparer< 'Key>) = HashMultiMap< 'Key, 'Value>( 11 , comparer)
21+ let rest : IDictionary < _ , _ > =
22+ if defaultArg useConcurrentDictionary false then
23+ ConcurrentDictionary<_, _>( comparer)
24+ else
25+ Dictionary<_, _>( 3 , comparer)
1726
18- new ( entries: seq< 'Key * 'Value>, comparer: IEqualityComparer< 'Key>) as x =
19- new HashMultiMap< 'Key, 'Value>( 11 , comparer)
20- then entries |> Seq.iter ( fun ( k , v ) -> x.Add( k, v))
27+ new ( comparer: IEqualityComparer< 'Key>, ?useConcurrentDictionary: bool) =
28+ HashMultiMap< 'Key, 'Value>( 11 , comparer, defaultArg useConcurrentDictionary false )
2129
22- member x.GetRest ( k ) =
30+ new ( entries: seq< 'Key * 'Value>, comparer: IEqualityComparer< 'Key>, ?useConcurrentDictionary: bool) as this =
31+ HashMultiMap< 'Key, 'Value>( 11 , comparer, defaultArg useConcurrentDictionary false )
32+ then entries |> Seq.iter ( fun ( k , v ) -> this.Add( k, v))
33+
34+ member _.GetRest ( k ) =
2335 match rest.TryGetValue k with
2436 | true , res -> res
2537 | _ -> []
2638
27- member x .Add( y , z ) =
39+ member this .Add( y , z ) =
2840 match firstEntries.TryGetValue y with
29- | true , res -> rest[ y] <- res :: x .GetRest( y)
41+ | true , res -> rest[ y] <- res :: this .GetRest( y)
3042 | _ -> ()
3143
3244 firstEntries[ y] <- z
3345
34- member x .Clear() =
46+ member _ .Clear() =
3547 firstEntries.Clear()
3648 rest.Clear()
3749
38- member x .FirstEntries = firstEntries
50+ member _ .FirstEntries = firstEntries
3951
40- member x .Rest = rest
52+ member _ .Rest = rest
4153
42- member x .Copy() =
43- let res = HashMultiMap< 'Key, 'Value>( firstEntries.Count, firstEntries.Comparer )
54+ member _ .Copy() =
55+ let res = HashMultiMap< 'Key, 'Value>( firstEntries.Count, comparer )
4456
4557 for kvp in firstEntries do
4658 res.FirstEntries.Add( kvp.Key, kvp.Value)
@@ -86,11 +98,11 @@ type internal HashMultiMap<'Key, 'Value>(size: int, comparer: IEqualityComparer<
8698 for z in rest do
8799 f kvp.Key z
88100
89- member x .Contains( y ) = firstEntries.ContainsKey( y)
101+ member _ .Contains( y ) = firstEntries.ContainsKey( y)
90102
91- member x .ContainsKey( y ) = firstEntries.ContainsKey( y)
103+ member _ .ContainsKey( y ) = firstEntries.ContainsKey( y)
92104
93- member x .Remove( y ) =
105+ member _ .Remove( y ) =
94106 match firstEntries.TryGetValue y with
95107 // NOTE: If not ok then nothing to remove - nop
96108 | true , _ res ->
@@ -108,14 +120,14 @@ type internal HashMultiMap<'Key, 'Value>(size: int, comparer: IEqualityComparer<
108120 | _ -> firstEntries.Remove( y) |> ignore
109121 | _ -> ()
110122
111- member x .Replace( y , z ) = firstEntries[ y] <- z
123+ member _ .Replace( y , z ) = firstEntries[ y] <- z
112124
113- member x .TryFind( y ) =
125+ member _ .TryFind( y ) =
114126 match firstEntries.TryGetValue y with
115127 | true , res -> Some res
116128 | _ -> None
117129
118- member x .Count = firstEntries.Count
130+ member _ .Count = firstEntries.Count
119131
120132 interface IEnumerable< KeyValuePair< 'Key, 'Value>> with
121133
@@ -184,6 +196,6 @@ type internal HashMultiMap<'Key, 'Value>(size: int, comparer: IEqualityComparer<
184196 member s.CopyTo ( arr , arrIndex ) =
185197 s |> Seq.iteri ( fun j x -> arr[ arrIndex + j] <- x)
186198
187- member s .IsReadOnly = false
199+ member _ .IsReadOnly = false
188200
189201 member s.Count = s.Count
0 commit comments