Files
stgsharp/内核源代码/StgSharp.Common/Collections/KeyMultiplexer.cs
T

111 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
namespace StgSharp.Collections
{
public class StringHashMultiplexer : IEqualityComparer<string>, IStringHashMultiplexer
{
private string _source, _sourceLast;
private int _initCount, _remainedCount, _hashCache, _hashLast;
public int RemainedMultiplexCount
{
get => _remainedCount;
set => _initCount = value;
}
public bool Equals(string x, string y)
{
return x == y;
}
public int GetHashCode(string obj)
{
if (_remainedCount > 0 && ReferenceEquals(_source, obj))
{
_remainedCount--;
return _hashCache;
}
if (ReferenceEquals(_sourceLast, obj))
{
return _hashLast;
}
_sourceLast = obj;
_hashLast = ForceComputeHash(obj);
return _hashLast;
}
public void CacheHash(string obj, int count)
{
_hashCache = ForceComputeHash(obj);
_initCount = count;
_remainedCount = _initCount;
_source = obj;
}
public void ExtendCache(int count)
{
_initCount += count;
_remainedCount += count;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe int ForceComputeHash([NotNull] string obj)
{
int hash;
fixed (char* cPtr = obj.AsSpan())
{
hash = InternalIO.Intrinsic.cityhash_simplify(cPtr, obj.Length);
}
return hash;
}
}
public class ConcurrentStringHashMultiplexer : IEqualityComparer<string>, IStringHashMultiplexer
{
private readonly ThreadLocal<StringHashMultiplexer> multiplexers =
new (()=>new StringHashMultiplexer());
public int RemainedMultiplexCount
{
get => multiplexers.Value.RemainedMultiplexCount;
set => multiplexers.Value.RemainedMultiplexCount = value;
}
public void CacheHash(string obj, int count)
{
throw new NotImplementedException();
}
public bool Equals(string x, string y)
{
return x == y;
}
public void ExtendCache(int count)
{
multiplexers.Value.ExtendCache(count);
}
public unsafe int ForceComputeHash([NotNull] string obj)
{
int hash;
fixed (char* cPtr = obj.AsSpan())
{
hash = InternalIO.Intrinsic.cityhash_simplify(cPtr, obj.Length);
}
return hash;
}
public int GetHashCode(string obj)
{
return multiplexers.Value.GetHashCode(obj);
}
}
}