Skip to content

Commit

Permalink
增加ConcurrentHashSet
Browse files Browse the repository at this point in the history
  • Loading branch information
ldqk committed Jan 12, 2022
1 parent d5e7d66 commit e465e3d
Show file tree
Hide file tree
Showing 9 changed files with 429 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet />
<Version>2.4.6.5</Version>
<Version>2.4.7</Version>
<Authors>懒得勤快</Authors>
<Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
<Copyright>懒得勤快,长空X</Copyright>
Expand Down Expand Up @@ -42,7 +42,7 @@

<ItemGroup>
<PackageReference Include="DnsClient" Version="1.5.0" />
<PackageReference Include="HtmlSanitizer" Version="6.0.441" />
<PackageReference Include="HtmlSanitizer" Version="7.0.473" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
Expand Down
378 changes: 378 additions & 0 deletions Masuit.Tools.Abstractions/Systems/ConcurrentHashSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,378 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Threading;

namespace Masuit.Tools.Systems;

/// <summary>
/// 并发HashSet
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class ConcurrentHashSet<T> : ISet<T>, IDisposable
{
private readonly ReaderWriterLockSlim _lock = new(LockRecursionPolicy.SupportsRecursion);

private readonly HashSet<T> _hashSet = new();

public int Count
{
get
{
_lock.EnterWriteLock();
try
{
return _hashSet.Count;
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}
}

public bool IsReadOnly => false;

public ConcurrentHashSet()
{
}

public ConcurrentHashSet(IEqualityComparer<T> comparer)
{
_hashSet = new HashSet<T>(comparer);
}

public ConcurrentHashSet(IEnumerable<T> collection)
{
_hashSet = new HashSet<T>(collection);
}

public ConcurrentHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
{
_hashSet = new HashSet<T>(collection, comparer);
}

public ConcurrentHashSet(SerializationInfo info, StreamingContext context)
{
_hashSet = new HashSet<T>();
var iSerializable = (ISerializable)_hashSet;
iSerializable.GetObjectData(info, context);
}

public void OnDeserialization(object sender)
{
_hashSet.OnDeserialization(sender);
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
_hashSet.GetObjectData(info, context);
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public IEnumerator<T> GetEnumerator()
{
return _hashSet.GetEnumerator();
}

public void Add(T item)
{
_lock.EnterWriteLock();
try
{
_hashSet.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public void UnionWith(IEnumerable<T> other)
{
_lock.EnterWriteLock();
_lock.EnterReadLock();
try
{
_hashSet.UnionWith(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}

if (_lock.IsReadLockHeld)
{
_lock.ExitReadLock();
}
}
}

public void IntersectWith(IEnumerable<T> other)
{
_lock.EnterWriteLock();
_lock.EnterReadLock();
try
{
_hashSet.IntersectWith(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}

if (_lock.IsReadLockHeld)
{
_lock.ExitReadLock();
}
}
}

public void ExceptWith(IEnumerable<T> other)
{
_lock.EnterWriteLock();
_lock.EnterReadLock();
try
{
_hashSet.ExceptWith(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}

if (_lock.IsReadLockHeld)
{
_lock.ExitReadLock();
}
}
}

public void SymmetricExceptWith(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
_hashSet.SymmetricExceptWith(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool IsSubsetOf(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.IsSubsetOf(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool IsSupersetOf(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.IsSupersetOf(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool IsProperSupersetOf(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.IsProperSupersetOf(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool IsProperSubsetOf(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.IsProperSubsetOf(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool Overlaps(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Overlaps(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool SetEquals(IEnumerable<T> other)
{
_lock.EnterWriteLock();
try
{
return _hashSet.SetEquals(other);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

bool ISet<T>.Add(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Add(item);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public void Clear()
{
_lock.EnterWriteLock();
try
{
_hashSet.Clear();
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool Contains(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Contains(item);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public void CopyTo(T[] array, int arrayIndex)
{
_lock.EnterWriteLock();
try
{
_hashSet.CopyTo(array, arrayIndex);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public bool Remove(T item)
{
_lock.EnterWriteLock();
try
{
return _hashSet.Remove(item);
}
finally
{
if (_lock.IsWriteLockHeld)
{
_lock.ExitWriteLock();
}
}
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if (disposing && _lock != null)
{
_lock.Dispose();
}
}

~ConcurrentHashSet()
{
Dispose(false);
}
}
Loading

0 comments on commit e465e3d

Please sign in to comment.