@@ -47,35 +47,35 @@ public final class CacheContainer: Sendable {
47
47
}
48
48
}
49
49
50
- final class ThreadSafeDictionary < V : Hashable & Sendable , T : Sendable > : Collection , @unchecked Sendable {
51
- private var dictionary : [ V : T ]
50
+ final class ThreadSafeDictionary < Key : Hashable & Sendable , Value : Sendable > : Collection , @unchecked Sendable {
51
+ private var dictionary : [ Key : Value ]
52
52
private let concurrentQueue = DispatchQueue ( label: " Dictionary Barrier Queue " , attributes: . concurrent)
53
53
54
- var keys : Dictionary < V , T > . Keys {
54
+ var keys : Dictionary < Key , Value > . Keys {
55
55
concurrentQueue. sync { dictionary. keys }
56
56
}
57
57
58
- var values : Dictionary < V , T > . Values {
58
+ var values : Dictionary < Key , Value > . Values {
59
59
concurrentQueue. sync { dictionary. values }
60
60
}
61
61
62
- var startIndex : Dictionary < V , T > . Index {
62
+ var startIndex : Dictionary < Key , Value > . Index {
63
63
concurrentQueue. sync { dictionary. startIndex }
64
64
}
65
65
66
- var endIndex : Dictionary < V , T > . Index {
66
+ var endIndex : Dictionary < Key , Value > . Index {
67
67
concurrentQueue. sync { dictionary. endIndex }
68
68
}
69
69
70
- init ( dictionary: [ V : T ] = [ : ] ) {
70
+ init ( dictionary: [ Key : Value ] = [ : ] ) {
71
71
self . dictionary = dictionary
72
72
}
73
73
74
- func index( after i: Dictionary < V , T > . Index ) -> Dictionary < V , T > . Index {
74
+ func index( after i: Dictionary < Key , Value > . Index ) -> Dictionary < Key , Value > . Index {
75
75
concurrentQueue. sync { dictionary. index ( after: i) }
76
76
}
77
77
78
- subscript( key: V ) -> T ? {
78
+ subscript( key: Key ) -> Value ? {
79
79
set ( newValue) {
80
80
concurrentQueue. async ( flags: . barrier) { [ weak self] in
81
81
self ? . dictionary [ key] = newValue
@@ -86,13 +86,74 @@ final class ThreadSafeDictionary<V: Hashable & Sendable, T: Sendable>: Collectio
86
86
}
87
87
}
88
88
89
- subscript( index: Dictionary < V , T > . Index ) -> Dictionary < V , T > . Element {
89
+ subscript( index: Dictionary < Key , Value > . Index ) -> Dictionary < Key , Value > . Element {
90
90
concurrentQueue. sync { dictionary [ index] }
91
91
}
92
92
93
- func removeValue( forKey key: V ) {
93
+ func removeValue( forKey key: Key ) {
94
94
concurrentQueue. async ( flags: . barrier) { [ weak self] in
95
95
self ? . dictionary. removeValue ( forKey: key)
96
96
}
97
97
}
98
98
}
99
+
100
+
101
+
102
+ struct ThreadSafeDictionary2 < Key: Hashable & Sendable , Value: Sendable > {
103
+ private let dictionary : Mutex < [ Key : Value ] >
104
+
105
+ init ( dictionary: [ Key : Value ] = [ : ] ) {
106
+ self . dictionary = Mutex ( dictionary)
107
+ }
108
+
109
+ var keys : Dictionary < Key , Value > . Keys {
110
+ dictionary. withLock ( \. keys)
111
+ }
112
+
113
+ var values : Dictionary < Key , Value > . Values {
114
+ dictionary. withLock ( \. values)
115
+ }
116
+
117
+ subscript( key: Key ) -> Value ? {
118
+ get { dictionary. withLock ( \. [ key] ) }
119
+ set { dictionary. withLock { $0 [ key] = newValue } }
120
+ }
121
+
122
+ @discardableResult
123
+ func removeValue( forKey key: Key ) -> Value ? {
124
+ dictionary. withLock { $0. removeValue ( forKey: key) }
125
+ }
126
+ }
127
+
128
+ extension ThreadSafeDictionary2 : Collection {
129
+ var startIndex : Dictionary < Key , Value > . Index {
130
+ dictionary. withLock ( \. startIndex)
131
+ }
132
+
133
+ var endIndex : Dictionary < Key , Value > . Index {
134
+ dictionary. withLock ( \. endIndex)
135
+ }
136
+
137
+ subscript( index: Dictionary < Key , Value > . Index ) -> Dictionary < Key , Value > . Element {
138
+ dictionary. withLock ( \. [ index] )
139
+ }
140
+
141
+ func index( after i: Dictionary < Key , Value > . Index ) -> Dictionary < Key , Value > . Index {
142
+ dictionary. withLock { $0. index ( after: i) }
143
+ }
144
+ }
145
+
146
+ final class Mutex < Value: ~ Copyable> : @unchecked Sendable {
147
+ private let lock = NSLock ( )
148
+ private var value : Value
149
+
150
+ init ( _ initialValue: consuming Value ) {
151
+ self . value = initialValue
152
+ }
153
+
154
+ func withLock< Result: ~ Copyable, E: Error > ( _ body: ( inout Value ) throws ( E ) -> Result ) throws ( E) -> Result {
155
+ lock. lock ( )
156
+ defer { lock. unlock ( ) }
157
+ return try body ( & value)
158
+ }
159
+ }
0 commit comments