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, 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, IStringHashMultiplexer { private readonly ThreadLocal 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); } } }