Comment out IdentityMap<TId> implementation
The entire IdentityMap<TId> class and related types have been commented out, leaving the code inactive but preserved for reference. No functional code remains in the file; all logic is now present only as comments.
This commit is contained in:
parent
94dfa1b5f5
commit
c766a83178
|
|
@ -0,0 +1,406 @@
|
||||||
|
//using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
//namespace AyCode.Core.Serializers;
|
||||||
|
|
||||||
|
//#region IId Reference Tracking
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// Specifies the accessor type for IId.Id property to enable typed getter dispatch without boxing.
|
||||||
|
///// </summary>
|
||||||
|
//public enum IdAccessorType : byte
|
||||||
|
//{
|
||||||
|
// None = 0,
|
||||||
|
// /// <summary>Id is int (most common).</summary>
|
||||||
|
// Int32 = 1,
|
||||||
|
// /// <summary>Id is long.</summary>
|
||||||
|
// Int64 = 2,
|
||||||
|
// /// <summary>Id is Guid.</summary>
|
||||||
|
// Guid = 3,
|
||||||
|
//}
|
||||||
|
///// <summary>
|
||||||
|
///// Interface for identity maps used in serialization tracking.
|
||||||
|
///// Enables type-safe Reset() without knowing the generic type parameter.
|
||||||
|
///// </summary>
|
||||||
|
//public interface IIdentityMap
|
||||||
|
//{
|
||||||
|
// /// <summary>
|
||||||
|
// /// Resets the identity map for reuse between serializations.
|
||||||
|
// /// </summary>
|
||||||
|
// void Reset();
|
||||||
|
//}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// High-performance identity map for tracking IId values during serialization/deserialization.
|
||||||
|
///// Uses custom hash table optimized for our use case:
|
||||||
|
///// - Small int keys (0-4095): direct array access with bitmap
|
||||||
|
///// - Large keys: custom hash table with chaining
|
||||||
|
///// No Dictionary overhead, no per-entry allocation.
|
||||||
|
///// </summary>
|
||||||
|
///// <typeparam name="TId">The ID type (int, long, Guid, string)</typeparam>
|
||||||
|
//public sealed class IdentityMap<TId> : IIdentityMap where TId : notnull
|
||||||
|
//{
|
||||||
|
// // Small int optimization (TId = int only, 0-4095)
|
||||||
|
// private const int SmallSize = 4096;
|
||||||
|
// private const int SmallBitmapSize = SmallSize / 64; // 64 ulongs
|
||||||
|
|
||||||
|
// // Slot for storing tracked values
|
||||||
|
// private struct Slot
|
||||||
|
// {
|
||||||
|
// public object? Value; // stored object for deserialization
|
||||||
|
// public int Next; // next slot index in chain (-1 = end)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Small int storage (only used when TId is int)
|
||||||
|
// private ulong[]? _smallBitmap; // quick "seen?" check
|
||||||
|
// private Slot[]? _smallSlots; // direct indexed storage
|
||||||
|
|
||||||
|
// // Hash table storage (for large ints and other types)
|
||||||
|
// private int[]? _buckets; // bucket index → first entry index
|
||||||
|
// private Slot[]? _entries; // hash table entries
|
||||||
|
// private TId[]? _keys; // keys for equality check
|
||||||
|
// private int _count; // number of entries in hash table
|
||||||
|
|
||||||
|
// private const int InitialHashCapacity = 16;
|
||||||
|
|
||||||
|
// // Type checks (JIT eliminates these at compile time)
|
||||||
|
// private static readonly bool IsInt32 = typeof(TId) == typeof(int);
|
||||||
|
// private static readonly bool IsInt64 = typeof(TId) == typeof(long);
|
||||||
|
// private static readonly bool IsGuid = typeof(TId) == typeof(Guid);
|
||||||
|
// private static readonly bool IsString = typeof(TId) == typeof(string);
|
||||||
|
|
||||||
|
// public IdentityMap()
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Tries to add a key to tracking (serialization).
|
||||||
|
// /// Returns true if first occurrence (key was added).
|
||||||
|
// /// Returns false if already seen.
|
||||||
|
// /// </summary>
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// public bool TryAddKey(TId key)
|
||||||
|
// {
|
||||||
|
// // Small int fast path
|
||||||
|
// if (IsInt32)
|
||||||
|
// {
|
||||||
|
// var intKey = Unsafe.As<TId, int>(ref key);
|
||||||
|
// if ((uint)intKey < SmallSize)
|
||||||
|
// {
|
||||||
|
// return TryAddSmallInt(intKey);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Hash table path
|
||||||
|
// return TryAddHash(key, out _);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// private bool TryAddSmallInt(int key)
|
||||||
|
// {
|
||||||
|
// // Lazy init
|
||||||
|
// if (_smallBitmap == null)
|
||||||
|
// {
|
||||||
|
// _smallBitmap = new ulong[SmallBitmapSize];
|
||||||
|
// _smallSlots = new Slot[SmallSize];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var wordIdx = key >> 6;
|
||||||
|
// var bit = 1UL << (key & 63);
|
||||||
|
|
||||||
|
// ref var word = ref _smallBitmap[wordIdx];
|
||||||
|
// if ((word & bit) != 0)
|
||||||
|
// return false; // already seen
|
||||||
|
|
||||||
|
// word |= bit;
|
||||||
|
// _smallSlots![key] = default; // init slot
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// private bool TryAddHash(TId key, out int slotIndex)
|
||||||
|
// {
|
||||||
|
// var hash = GetHashCode(key);
|
||||||
|
|
||||||
|
// // Lazy init
|
||||||
|
// if (_buckets == null)
|
||||||
|
// {
|
||||||
|
// InitHashTable(InitialHashCapacity);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var bucketIdx = (hash & 0x7FFFFFFF) % _buckets!.Length;
|
||||||
|
|
||||||
|
// // Search chain
|
||||||
|
// for (var i = _buckets[bucketIdx]; i >= 0; i = _entries![i].Next)
|
||||||
|
// {
|
||||||
|
// if (EqualityComparer<TId>.Default.Equals(_keys![i], key))
|
||||||
|
// {
|
||||||
|
// slotIndex = i;
|
||||||
|
// return false; // already seen
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Resize if needed
|
||||||
|
// if (_count >= _entries!.Length)
|
||||||
|
// {
|
||||||
|
// Resize();
|
||||||
|
// bucketIdx = (hash & 0x7FFFFFFF) % _buckets.Length;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Add new entry
|
||||||
|
// slotIndex = _count++;
|
||||||
|
// _keys![slotIndex] = key;
|
||||||
|
// _entries[slotIndex] = new Slot { Next = _buckets[bucketIdx] };
|
||||||
|
// _buckets[bucketIdx] = slotIndex;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// private static int GetHashCode(TId key)
|
||||||
|
// {
|
||||||
|
// // Specialized hash for known types
|
||||||
|
// if (IsInt32) return Unsafe.As<TId, int>(ref key);
|
||||||
|
// if (IsInt64) return Unsafe.As<TId, long>(ref key).GetHashCode();
|
||||||
|
// if (IsGuid) return Unsafe.As<TId, Guid>(ref key).GetHashCode();
|
||||||
|
// return key.GetHashCode();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void InitHashTable(int capacity)
|
||||||
|
// {
|
||||||
|
// _buckets = new int[capacity];
|
||||||
|
// Array.Fill(_buckets, -1);
|
||||||
|
// _entries = new Slot[capacity];
|
||||||
|
// _keys = new TId[capacity];
|
||||||
|
// _count = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void Resize()
|
||||||
|
// {
|
||||||
|
// var newCapacity = _buckets!.Length * 2;
|
||||||
|
// var newBuckets = new int[newCapacity];
|
||||||
|
// Array.Fill(newBuckets, -1);
|
||||||
|
// var newEntries = new Slot[newCapacity];
|
||||||
|
// var newKeys = new TId[newCapacity];
|
||||||
|
|
||||||
|
// // Copy entries
|
||||||
|
// Array.Copy(_entries!, newEntries, _count);
|
||||||
|
// Array.Copy(_keys!, newKeys, _count);
|
||||||
|
|
||||||
|
// // Rebuild bucket chains
|
||||||
|
// for (var i = 0; i < _count; i++)
|
||||||
|
// {
|
||||||
|
// var bucketIdx = (GetHashCode(newKeys[i]) & 0x7FFFFFFF) % newCapacity;
|
||||||
|
// newEntries[i].Next = newBuckets[bucketIdx];
|
||||||
|
// newBuckets[bucketIdx] = i;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// _buckets = newBuckets;
|
||||||
|
// _entries = newEntries;
|
||||||
|
// _keys = newKeys;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// public bool HasKey(TId key)
|
||||||
|
// {
|
||||||
|
// // Small int fast path
|
||||||
|
// if (IsInt32)
|
||||||
|
// {
|
||||||
|
// var intKey = Unsafe.As<TId, int>(ref key);
|
||||||
|
// if ((uint)intKey < SmallSize && _smallBitmap != null)
|
||||||
|
// {
|
||||||
|
// var wordIdx = intKey >> 6;
|
||||||
|
// var bit = 1UL << (intKey & 63);
|
||||||
|
// return (_smallBitmap[wordIdx] & bit) != 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Hash table path
|
||||||
|
// if (_buckets == null) return false;
|
||||||
|
|
||||||
|
// var hash = GetHashCode(key);
|
||||||
|
// var bucketIdx = (hash & 0x7FFFFFFF) % _buckets.Length;
|
||||||
|
|
||||||
|
// for (var i = _buckets[bucketIdx]; i >= 0; i = _entries![i].Next)
|
||||||
|
// {
|
||||||
|
// if (EqualityComparer<TId>.Default.Equals(_keys![i], key))
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Checks if key exists and returns existing value, or adds new key (deserialization).
|
||||||
|
// /// Returns true if first occurrence (key was added, out = null).
|
||||||
|
// /// Returns false if already seen (out = existing value).
|
||||||
|
// /// </summary>
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// public bool TryGetOrAddKey(TId key, out object? existing)
|
||||||
|
// {
|
||||||
|
// // Small int fast path
|
||||||
|
// if (IsInt32)
|
||||||
|
// {
|
||||||
|
// var intKey = Unsafe.As<TId, int>(ref key);
|
||||||
|
// if ((uint)intKey < SmallSize)
|
||||||
|
// {
|
||||||
|
// return TryGetOrAddSmallInt(intKey, out existing);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Hash table path
|
||||||
|
// if (!TryAddHash(key, out var slotIndex))
|
||||||
|
// {
|
||||||
|
// existing = _entries![slotIndex].Value;
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// existing = null;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// private bool TryGetOrAddSmallInt(int key, out object? existing)
|
||||||
|
// {
|
||||||
|
// // Lazy init
|
||||||
|
// if (_smallBitmap == null)
|
||||||
|
// {
|
||||||
|
// _smallBitmap = new ulong[SmallBitmapSize];
|
||||||
|
// _smallSlots = new Slot[SmallSize];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var wordIdx = key >> 6;
|
||||||
|
// var bit = 1UL << (key & 63);
|
||||||
|
|
||||||
|
// ref var word = ref _smallBitmap[wordIdx];
|
||||||
|
// if ((word & bit) != 0)
|
||||||
|
// {
|
||||||
|
// existing = _smallSlots![key].Value;
|
||||||
|
// return false; // already seen
|
||||||
|
// }
|
||||||
|
|
||||||
|
// word |= bit;
|
||||||
|
// _smallSlots![key] = default;
|
||||||
|
// existing = null;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Gets existing value or adds new value for key (deserialization with object storage).
|
||||||
|
// /// Returns the existing value if key was seen before, or stores and returns newValue.
|
||||||
|
// /// </summary>
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// public object TryGetOrAddValue(TId key, object newValue)
|
||||||
|
// {
|
||||||
|
// // Small int fast path
|
||||||
|
// if (IsInt32)
|
||||||
|
// {
|
||||||
|
// var intKey = Unsafe.As<TId, int>(ref key);
|
||||||
|
// if ((uint)intKey < SmallSize)
|
||||||
|
// {
|
||||||
|
// return TryGetOrAddSmallIntValue(intKey, newValue);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Hash table path
|
||||||
|
// if (!TryAddHash(key, out var slotIndex))
|
||||||
|
// {
|
||||||
|
// var existing = _entries![slotIndex].Value;
|
||||||
|
// if (existing != null) return existing;
|
||||||
|
// }
|
||||||
|
// _entries![slotIndex].Value = newValue;
|
||||||
|
// return newValue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// private object TryGetOrAddSmallIntValue(int key, object newValue)
|
||||||
|
// {
|
||||||
|
// // Lazy init
|
||||||
|
// if (_smallBitmap == null)
|
||||||
|
// {
|
||||||
|
// _smallBitmap = new ulong[SmallBitmapSize];
|
||||||
|
// _smallSlots = new Slot[SmallSize];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var wordIdx = key >> 6;
|
||||||
|
// var bit = 1UL << (key & 63);
|
||||||
|
|
||||||
|
// ref var word = ref _smallBitmap[wordIdx];
|
||||||
|
// if ((word & bit) != 0)
|
||||||
|
// {
|
||||||
|
// var existing = _smallSlots![key].Value;
|
||||||
|
// if (existing != null) return existing;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// word |= bit;
|
||||||
|
// _smallSlots![key].Value = newValue;
|
||||||
|
// return newValue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Tries to get the value for a key (ObjectRef lookup).
|
||||||
|
// /// Returns true if found, false if not.
|
||||||
|
// /// </summary>
|
||||||
|
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
// public bool TryGetValue(TId key, out object? value)
|
||||||
|
// {
|
||||||
|
// // Small int fast path
|
||||||
|
// if (IsInt32)
|
||||||
|
// {
|
||||||
|
// var intKey = Unsafe.As<TId, int>(ref key);
|
||||||
|
// if ((uint)intKey < SmallSize && _smallBitmap != null)
|
||||||
|
// {
|
||||||
|
// var wordIdx = intKey >> 6;
|
||||||
|
// var bit = 1UL << (intKey & 63);
|
||||||
|
// if ((_smallBitmap[wordIdx] & bit) != 0)
|
||||||
|
// {
|
||||||
|
// value = _smallSlots![intKey].Value;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// value = null;
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Hash table path
|
||||||
|
// if (_buckets == null)
|
||||||
|
// {
|
||||||
|
// value = null;
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var hash = GetHashCode(key);
|
||||||
|
// var bucketIdx = (hash & 0x7FFFFFFF) % _buckets.Length;
|
||||||
|
|
||||||
|
// for (var i = _buckets[bucketIdx]; i >= 0; i = _entries![i].Next)
|
||||||
|
// {
|
||||||
|
// if (EqualityComparer<TId>.Default.Equals(_keys![i], key))
|
||||||
|
// {
|
||||||
|
// value = _entries[i].Value;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// value = null;
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// <summary>
|
||||||
|
// /// Resets the identity map for reuse.
|
||||||
|
// /// </summary>
|
||||||
|
// public void Reset()
|
||||||
|
// {
|
||||||
|
// // Clear small int storage
|
||||||
|
// if (_smallBitmap != null)
|
||||||
|
// {
|
||||||
|
// Array.Clear(_smallBitmap);
|
||||||
|
// Array.Clear(_smallSlots!);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Clear hash table
|
||||||
|
// if (_buckets != null)
|
||||||
|
// {
|
||||||
|
// Array.Fill(_buckets, -1);
|
||||||
|
// Array.Clear(_entries!);
|
||||||
|
// Array.Clear(_keys!);
|
||||||
|
// _count = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
Loading…
Reference in New Issue