wasSharp – Blame information for rev 44

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