3
3
namespace Internal.Utilities.Collections
4
4
5
5
open System.Collections .Generic
6
+ open System.Collections .Concurrent
6
7
7
8
// Each entry in the HashMultiMap dictionary has at least one entry. Under normal usage each entry has _only_
8
9
// 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
11
12
#if ! NO_CHECKNULLS
12
13
when 'Key:not null
13
14
#endif
14
- >( size : int , comparer : IEqualityComparer < 'Key >) =
15
+ >( size : int , comparer : IEqualityComparer < 'Key >, ? useConcurrentDictionary : bool ) =
15
16
16
- let firstEntries = Dictionary <_, _>( size , comparer)
17
+ let comparer = comparer
17
18
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)
19
24
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)
21
30
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 )
25
33
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 ) =
27
39
match rest.TryGetValue k with
28
40
| true , res -> res
29
41
| _ -> []
30
42
31
- member x .Add( y , z ) =
43
+ member this .Add( y , z ) =
32
44
match firstEntries.TryGetValue y with
33
- | true , res -> rest[ y] <- res :: x .GetRest( y)
45
+ | true , res -> rest[ y] <- res :: this .GetRest( y)
34
46
| _ -> ()
35
47
36
48
firstEntries[ y] <- z
37
49
38
- member x .Clear() =
50
+ member _ .Clear() =
39
51
firstEntries.Clear()
40
52
rest.Clear()
41
53
42
- member x .FirstEntries = firstEntries
54
+ member _ .FirstEntries = firstEntries
43
55
44
- member x .Rest = rest
56
+ member _ .Rest = rest
45
57
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 )
48
60
49
61
for kvp in firstEntries do
50
62
res.FirstEntries.Add( kvp.Key, kvp.Value)
@@ -90,11 +102,11 @@ type internal HashMultiMap<'Key, 'Value
90
102
for z in rest do
91
103
f kvp.Key z
92
104
93
- member x .Contains( y ) = firstEntries.ContainsKey( y)
105
+ member _ .Contains( y ) = firstEntries.ContainsKey( y)
94
106
95
- member x .ContainsKey( y ) = firstEntries.ContainsKey( y)
107
+ member _ .ContainsKey( y ) = firstEntries.ContainsKey( y)
96
108
97
- member x .Remove( y ) =
109
+ member _ .Remove( y ) =
98
110
match firstEntries.TryGetValue y with
99
111
// NOTE: If not ok then nothing to remove - nop
100
112
| true , _ res ->
@@ -112,14 +124,14 @@ type internal HashMultiMap<'Key, 'Value
112
124
| _ -> firstEntries.Remove( y) |> ignore
113
125
| _ -> ()
114
126
115
- member x .Replace( y , z ) = firstEntries[ y] <- z
127
+ member _ .Replace( y , z ) = firstEntries[ y] <- z
116
128
117
- member x .TryFind( y ) =
129
+ member _ .TryFind( y ) =
118
130
match firstEntries.TryGetValue y with
119
131
| true , res -> Some res
120
132
| _ -> None
121
133
122
- member x .Count = firstEntries.Count
134
+ member _ .Count = firstEntries.Count
123
135
124
136
interface IEnumerable< KeyValuePair< 'Key, 'Value>> with
125
137
@@ -188,6 +200,6 @@ type internal HashMultiMap<'Key, 'Value
188
200
member s.CopyTo ( arr , arrIndex ) =
189
201
s |> Seq.iteri ( fun j x -> arr[ arrIndex + j] <- x)
190
202
191
- member s .IsReadOnly = false
203
+ member _ .IsReadOnly = false
192
204
193
205
member s.Count = s.Count
0 commit comments