111 lines
3.0 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|