wasSharp – Diff between revs 31 and 40
?pathlinks?
Rev 31 | Rev 40 | |||
---|---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////// |
1 | /////////////////////////////////////////////////////////////////////////// |
|
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
|
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
|
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
|
5 | /////////////////////////////////////////////////////////////////////////// |
5 | /////////////////////////////////////////////////////////////////////////// |
|
6 | // Based on work by Ben Mosher |
6 | // Based on work by Ben Mosher |
|
7 | |
7 | |
|
8 | using System; |
8 | using System; |
|
9 | using System.Collections; |
9 | using System.Collections; |
|
10 | using System.Collections.Generic; |
10 | using System.Collections.Generic; |
|
11 | using System.Threading; |
11 | using System.Threading; |
|
- | 12 | using System.Linq; |
||
12 | |
13 | |
|
13 | namespace wasSharp.Collections.Specialized |
14 | namespace wasSharp.Collections.Specialized |
|
14 | { |
15 | { |
|
- | 16 | public static class ConcurrentHashSetExtensions |
||
- | 17 | { |
||
- | 18 | public static ConcurrentHashSet<T> ToConcurrentHashSet<T>(this IEnumerable<T> enumerable) |
||
- | 19 | { |
||
- | 20 | return new ConcurrentHashSet<T>(enumerable); |
||
- | 21 | } |
||
- | 22 | } |
||
- | 23 | |
||
15 | public class ConcurrentHashSet<T> : IDisposable, ICollection<T>, IEnumerable<T>, ISet<T> |
24 | public class ConcurrentHashSet<T> : IDisposable, ICollection<T>, IEnumerable<T>, ISet<T> |
|
16 | { |
25 | { |
|
17 | private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); |
26 | private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); |
|
18 | private readonly HashSet<T> _hashSet = new HashSet<T>(); |
27 | private readonly HashSet<T> _hashSet = null; |
|
- | 28 | private IEnumerable<string> enumerable; |
||
- | 29 | |
||
- | 30 | public ConcurrentHashSet() |
||
- | 31 | { |
||
- | 32 | _lock.EnterWriteLock(); |
||
- | 33 | try |
||
- | 34 | { |
||
- | 35 | _hashSet = new HashSet<T>(); |
||
- | 36 | } |
||
- | 37 | finally |
||
- | 38 | { |
||
- | 39 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
||
- | 40 | } |
||
- | 41 | } |
||
- | 42 | |
||
- | 43 | public ConcurrentHashSet(IEqualityComparer<T> stringComparer) |
||
- | 44 | { |
||
- | 45 | _lock.EnterWriteLock(); |
||
- | 46 | try |
||
- | 47 | { |
||
- | 48 | _hashSet = new HashSet<T>(stringComparer); |
||
- | 49 | } |
||
- | 50 | finally |
||
- | 51 | { |
||
- | 52 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
||
- | 53 | } |
||
- | 54 | } |
||
- | 55 | |
||
- | 56 | public ConcurrentHashSet(IEnumerable<T> enumerable) |
||
- | 57 | { |
||
- | 58 | _lock.EnterWriteLock(); |
||
- | 59 | try |
||
- | 60 | { |
||
- | 61 | _hashSet = new HashSet<T>(); |
||
- | 62 | foreach (var i in enumerable) |
||
- | 63 | { |
||
- | 64 | _hashSet.Add(i); |
||
- | 65 | } |
||
- | 66 | } |
||
- | 67 | finally |
||
- | 68 | { |
||
- | 69 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
||
- | 70 | } |
||
- | 71 | } |
||
19 | |
72 | |
|
20 | #region Implementation of ICollection<T> |
73 | #region Implementation of ICollection<T> |
|
21 | |
74 | |
|
22 | public bool Add(T item) |
75 | public bool Add(T item) |
|
23 | { |
76 | { |
|
24 | _lock.EnterWriteLock(); |
77 | _lock.EnterWriteLock(); |
|
25 | try |
78 | try |
|
26 | { |
79 | { |
|
27 | return _hashSet.Add(item); |
80 | return _hashSet.Add(item); |
|
28 | } |
81 | } |
|
29 | finally |
82 | finally |
|
30 | { |
83 | { |
|
31 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
84 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
32 | } |
85 | } |
|
33 | } |
86 | } |
|
34 | |
87 | |
|
35 | public void Clear() |
88 | public void Clear() |
|
36 | { |
89 | { |
|
37 | _lock.EnterWriteLock(); |
90 | _lock.EnterWriteLock(); |
|
38 | try |
91 | try |
|
39 | { |
92 | { |
|
40 | _hashSet.Clear(); |
93 | _hashSet.Clear(); |
|
41 | } |
94 | } |
|
42 | finally |
95 | finally |
|
43 | { |
96 | { |
|
44 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
97 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
45 | } |
98 | } |
|
46 | } |
99 | } |
|
47 | |
100 | |
|
48 | public bool Contains(T item) |
101 | public bool Contains(T item) |
|
49 | { |
102 | { |
|
50 | _lock.EnterReadLock(); |
103 | _lock.EnterReadLock(); |
|
51 | try |
104 | try |
|
52 | { |
105 | { |
|
53 | return _hashSet.Contains(item); |
106 | return _hashSet.Contains(item); |
|
54 | } |
107 | } |
|
55 | finally |
108 | finally |
|
56 | { |
109 | { |
|
57 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
110 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
58 | } |
111 | } |
|
59 | } |
112 | } |
|
60 | |
113 | |
|
61 | public bool Remove(T item) |
114 | public bool Remove(T item) |
|
62 | { |
115 | { |
|
63 | _lock.EnterWriteLock(); |
116 | _lock.EnterWriteLock(); |
|
64 | try |
117 | try |
|
65 | { |
118 | { |
|
66 | return _hashSet.Remove(item); |
119 | return _hashSet.Remove(item); |
|
67 | } |
120 | } |
|
- | 121 | finally |
||
- | 122 | { |
||
- | 123 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
||
- | 124 | } |
||
- | 125 | } |
||
- | 126 | |
||
- | 127 | public int RemoveWhere(Predicate<T> match) |
||
- | 128 | { |
||
- | 129 | _lock.EnterWriteLock(); |
||
- | 130 | try |
||
- | 131 | { |
||
- | 132 | return _hashSet.RemoveWhere(match); |
||
- | 133 | } |
||
68 | finally |
134 | finally |
|
69 | { |
135 | { |
|
70 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
136 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
71 | } |
137 | } |
|
72 | } |
138 | } |
|
73 | |
139 | |
|
74 | public int Count |
140 | public int Count |
|
75 | { |
141 | { |
|
76 | get |
142 | get |
|
77 | { |
143 | { |
|
78 | _lock.EnterReadLock(); |
144 | _lock.EnterReadLock(); |
|
79 | try |
145 | try |
|
80 | { |
146 | { |
|
81 | return _hashSet.Count; |
147 | return _hashSet.Count; |
|
82 | } |
148 | } |
|
83 | finally |
149 | finally |
|
84 | { |
150 | { |
|
85 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
151 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
86 | } |
152 | } |
|
87 | } |
153 | } |
|
88 | } |
154 | } |
|
89 | |
155 | |
|
90 | void ICollection<T>.Add(T item) |
156 | void ICollection<T>.Add(T item) |
|
91 | { |
157 | { |
|
92 | _lock.EnterWriteLock(); |
158 | _lock.EnterWriteLock(); |
|
93 | try |
159 | try |
|
94 | { |
160 | { |
|
95 | _hashSet.Add(item); |
161 | _hashSet.Add(item); |
|
96 | } |
162 | } |
|
97 | finally |
163 | finally |
|
98 | { |
164 | { |
|
99 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
165 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
100 | } |
166 | } |
|
101 | } |
167 | } |
|
102 | |
168 | |
|
103 | public void CopyTo(T[] array, int arrayIndex) |
169 | public void CopyTo(T[] array, int arrayIndex) |
|
104 | { |
170 | { |
|
105 | _lock.EnterReadLock(); |
171 | _lock.EnterReadLock(); |
|
106 | try |
172 | try |
|
107 | { |
173 | { |
|
108 | _hashSet.CopyTo(array, arrayIndex); |
174 | _hashSet.CopyTo(array, arrayIndex); |
|
109 | } |
175 | } |
|
110 | finally |
176 | finally |
|
111 | { |
177 | { |
|
112 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
178 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
113 | } |
179 | } |
|
114 | } |
180 | } |
|
115 | |
181 | |
|
116 | public IEnumerator<T> GetEnumerator() |
182 | public IEnumerator<T> GetEnumerator() |
|
117 | { |
183 | { |
|
118 | _lock.EnterReadLock(); |
184 | _lock.EnterReadLock(); |
|
119 | try |
185 | try |
|
120 | { |
186 | { |
|
121 | return _hashSet.GetEnumerator(); |
187 | return _hashSet.GetEnumerator(); |
|
122 | } |
188 | } |
|
123 | finally |
189 | finally |
|
124 | { |
190 | { |
|
125 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
191 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
126 | } |
192 | } |
|
127 | } |
193 | } |
|
128 | |
194 | |
|
129 | IEnumerator IEnumerable.GetEnumerator() |
195 | IEnumerator IEnumerable.GetEnumerator() |
|
130 | { |
196 | { |
|
131 | _lock.EnterReadLock(); |
197 | _lock.EnterReadLock(); |
|
132 | try |
198 | try |
|
133 | { |
199 | { |
|
134 | return _hashSet.GetEnumerator(); |
200 | return _hashSet.GetEnumerator(); |
|
135 | } |
201 | } |
|
136 | finally |
202 | finally |
|
137 | { |
203 | { |
|
138 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
204 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
139 | } |
205 | } |
|
140 | } |
206 | } |
|
141 | |
207 | |
|
142 | public bool IsReadOnly |
208 | public bool IsReadOnly |
|
143 | { |
209 | { |
|
144 | get |
210 | get |
|
145 | { |
211 | { |
|
146 | return ((ICollection<T>)_hashSet).IsReadOnly; |
212 | return ((ICollection<T>)_hashSet).IsReadOnly; |
|
147 | } |
213 | } |
|
148 | } |
214 | } |
|
149 | |
215 | |
|
150 | #endregion Implementation of ICollection<T> |
216 | #endregion Implementation of ICollection<T> |
|
151 | |
217 | |
|
152 | #region Dispose |
218 | #region Dispose |
|
153 | |
219 | |
|
154 | public void Dispose() |
220 | public void Dispose() |
|
155 | { |
221 | { |
|
156 | Dispose(true); |
222 | Dispose(true); |
|
157 | GC.SuppressFinalize(this); |
223 | GC.SuppressFinalize(this); |
|
158 | } |
224 | } |
|
159 | |
225 | |
|
160 | protected virtual void Dispose(bool disposing) |
226 | protected virtual void Dispose(bool disposing) |
|
161 | { |
227 | { |
|
162 | if (disposing) |
228 | if (disposing) |
|
163 | { |
229 | { |
|
164 | if (_lock != null) |
230 | if (_lock != null) |
|
165 | _lock.Dispose(); |
231 | _lock.Dispose(); |
|
166 | _hashSet.Clear(); |
232 | _hashSet.Clear(); |
|
167 | } |
233 | } |
|
168 | } |
234 | } |
|
169 | |
235 | |
|
170 | ~ConcurrentHashSet() |
236 | ~ConcurrentHashSet() |
|
171 | { |
237 | { |
|
172 | Dispose(false); |
238 | Dispose(false); |
|
173 | } |
239 | } |
|
174 | |
240 | |
|
175 | #endregion Dispose |
241 | #endregion Dispose |
|
176 | |
242 | |
|
177 | #region Implementation of ISet<T> |
243 | #region Implementation of ISet<T> |
|
178 | |
244 | |
|
179 | public void ExceptWith(IEnumerable<T> other) |
245 | public void ExceptWith(IEnumerable<T> other) |
|
180 | { |
246 | { |
|
181 | _lock.EnterWriteLock(); |
247 | _lock.EnterWriteLock(); |
|
182 | try |
248 | try |
|
183 | { |
249 | { |
|
184 | _hashSet.ExceptWith(other); |
250 | _hashSet.ExceptWith(other); |
|
185 | } |
251 | } |
|
186 | finally |
252 | finally |
|
187 | { |
253 | { |
|
188 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
254 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
189 | } |
255 | } |
|
190 | } |
256 | } |
|
191 | |
257 | |
|
192 | public void IntersectWith(IEnumerable<T> other) |
258 | public void IntersectWith(IEnumerable<T> other) |
|
193 | { |
259 | { |
|
194 | _lock.EnterWriteLock(); |
260 | _lock.EnterWriteLock(); |
|
195 | try |
261 | try |
|
196 | { |
262 | { |
|
197 | _hashSet.IntersectWith(other); |
263 | _hashSet.IntersectWith(other); |
|
198 | } |
264 | } |
|
199 | finally |
265 | finally |
|
200 | { |
266 | { |
|
201 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
267 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
202 | } |
268 | } |
|
203 | } |
269 | } |
|
204 | |
270 | |
|
205 | public bool IsProperSubsetOf(IEnumerable<T> other) |
271 | public bool IsProperSubsetOf(IEnumerable<T> other) |
|
206 | { |
272 | { |
|
207 | _lock.EnterReadLock(); |
273 | _lock.EnterReadLock(); |
|
208 | try |
274 | try |
|
209 | { |
275 | { |
|
210 | return _hashSet.IsProperSubsetOf(other); |
276 | return _hashSet.IsProperSubsetOf(other); |
|
211 | } |
277 | } |
|
212 | finally |
278 | finally |
|
213 | { |
279 | { |
|
214 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
280 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
215 | } |
281 | } |
|
216 | } |
282 | } |
|
217 | |
283 | |
|
218 | public bool IsProperSupersetOf(IEnumerable<T> other) |
284 | public bool IsProperSupersetOf(IEnumerable<T> other) |
|
219 | { |
285 | { |
|
220 | _lock.EnterReadLock(); |
286 | _lock.EnterReadLock(); |
|
221 | try |
287 | try |
|
222 | { |
288 | { |
|
223 | return _hashSet.IsProperSupersetOf(other); |
289 | return _hashSet.IsProperSupersetOf(other); |
|
224 | } |
290 | } |
|
225 | finally |
291 | finally |
|
226 | { |
292 | { |
|
227 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
293 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
228 | } |
294 | } |
|
229 | } |
295 | } |
|
230 | |
296 | |
|
231 | public bool IsSubsetOf(IEnumerable<T> other) |
297 | public bool IsSubsetOf(IEnumerable<T> other) |
|
232 | { |
298 | { |
|
233 | _lock.EnterReadLock(); |
299 | _lock.EnterReadLock(); |
|
234 | try |
300 | try |
|
235 | { |
301 | { |
|
236 | return _hashSet.IsSubsetOf(other); |
302 | return _hashSet.IsSubsetOf(other); |
|
237 | } |
303 | } |
|
238 | finally |
304 | finally |
|
239 | { |
305 | { |
|
240 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
306 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
241 | } |
307 | } |
|
242 | } |
308 | } |
|
243 | |
309 | |
|
244 | public bool IsSupersetOf(IEnumerable<T> other) |
310 | public bool IsSupersetOf(IEnumerable<T> other) |
|
245 | { |
311 | { |
|
246 | _lock.EnterReadLock(); |
312 | _lock.EnterReadLock(); |
|
247 | try |
313 | try |
|
248 | { |
314 | { |
|
249 | return _hashSet.IsSupersetOf(other); |
315 | return _hashSet.IsSupersetOf(other); |
|
250 | } |
316 | } |
|
251 | finally |
317 | finally |
|
252 | { |
318 | { |
|
253 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
319 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
254 | } |
320 | } |
|
255 | } |
321 | } |
|
256 | |
322 | |
|
257 | public bool Overlaps(IEnumerable<T> other) |
323 | public bool Overlaps(IEnumerable<T> other) |
|
258 | { |
324 | { |
|
259 | _lock.EnterReadLock(); |
325 | _lock.EnterReadLock(); |
|
260 | try |
326 | try |
|
261 | { |
327 | { |
|
262 | return _hashSet.Overlaps(other); |
328 | return _hashSet.Overlaps(other); |
|
263 | } |
329 | } |
|
264 | finally |
330 | finally |
|
265 | { |
331 | { |
|
266 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
332 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
267 | } |
333 | } |
|
268 | } |
334 | } |
|
269 | |
335 | |
|
270 | public bool SetEquals(IEnumerable<T> other) |
336 | public bool SetEquals(IEnumerable<T> other) |
|
271 | { |
337 | { |
|
272 | _lock.EnterReadLock(); |
338 | _lock.EnterReadLock(); |
|
273 | try |
339 | try |
|
274 | { |
340 | { |
|
275 | return _hashSet.SetEquals(other); |
341 | return _hashSet.SetEquals(other); |
|
276 | } |
342 | } |
|
277 | finally |
343 | finally |
|
278 | { |
344 | { |
|
279 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
345 | if (_lock.IsReadLockHeld) _lock.ExitReadLock(); |
|
280 | } |
346 | } |
|
281 | } |
347 | } |
|
282 | |
348 | |
|
283 | public void SymmetricExceptWith(IEnumerable<T> other) |
349 | public void SymmetricExceptWith(IEnumerable<T> other) |
|
284 | { |
350 | { |
|
285 | _lock.EnterWriteLock(); |
351 | _lock.EnterWriteLock(); |
|
286 | try |
352 | try |
|
287 | { |
353 | { |
|
288 | _hashSet.SymmetricExceptWith(other); |
354 | _hashSet.SymmetricExceptWith(other); |
|
289 | } |
355 | } |
|
290 | finally |
356 | finally |
|
291 | { |
357 | { |
|
292 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
358 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
293 | } |
359 | } |
|
294 | } |
360 | } |
|
295 | |
361 | |
|
296 | public void UnionWith(IEnumerable<T> other) |
362 | public void UnionWith(IEnumerable<T> other) |
|
297 | { |
363 | { |
|
298 | _lock.EnterWriteLock(); |
364 | _lock.EnterWriteLock(); |
|
299 | try |
365 | try |
|
300 | { |
366 | { |
|
301 | _hashSet.UnionWith(other); |
367 | _hashSet.UnionWith(other); |
|
302 | } |
368 | } |
|
303 | finally |
369 | finally |
|
304 | { |
370 | { |
|
305 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
371 | if (_lock.IsWriteLockHeld) _lock.ExitWriteLock(); |
|
306 | } |
372 | } |
|
307 | } |
373 | } |
|
308 | |
374 | |
|
309 | #endregion Implementation of ISet<T> |
375 | #endregion Implementation of ISet<T> |
|
310 | } |
376 | } |
|
311 | } |
377 | } |
|
312 | |
378 | |