// MIT License - Copyright (c) 2023 wallstop
// Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE
namespace WallstopStudios.UnityHelpers.Core.DataStructure
{
using System;
#if !SINGLE_THREADED
using System.Collections.Concurrent;
#else
using WallstopStudios.UnityHelpers.Core.Extension;
using System.Collections.Generic;
#endif
///
/// Flyweight cache that interns frequently reused strings to reduce allocations and dictionary lookups.
/// Useful when you have a known set of keys and want reference equality semantics without hitting .
///
///
///
///
[Serializable]
public sealed class StringWrapper
: IEquatable,
IComparable,
IDisposable
{
#if SINGLE_THREADED
private static readonly Dictionary Cache = new();
#else
private static readonly ConcurrentDictionary Cache = new();
#endif
public readonly string value;
private readonly int _hashCode;
private StringWrapper(string value)
{
this.value = value;
_hashCode = value.GetHashCode();
}
public static StringWrapper Get(string value)
{
return Cache.GetOrAdd(value, key => new StringWrapper(key));
}
public static bool Remove(string value)
{
return Cache.TryRemove(value, out _);
}
public static int Clear()
{
int count = Cache.Count;
Cache.Clear();
return count;
}
public bool Equals(StringWrapper other)
{
if (ReferenceEquals(this, other))
{
return true;
}
if (ReferenceEquals(other, null))
{
return false;
}
if (_hashCode != other._hashCode)
{
return false;
}
return string.Equals(value, other.value, StringComparison.Ordinal);
}
public int CompareTo(StringWrapper other)
{
if (ReferenceEquals(this, other))
{
return 0;
}
if (ReferenceEquals(other, null))
{
return -1;
}
int comparison = _hashCode.CompareTo(other._hashCode);
if (comparison != 0)
{
return comparison;
}
return string.Compare(value, other.value, StringComparison.Ordinal);
}
public override int GetHashCode()
{
return _hashCode;
}
public override bool Equals(object other)
{
return Equals(other as StringWrapper);
}
public override string ToString()
{
return value;
}
public void Dispose()
{
Remove(value);
}
}
}