diff --git a/AyCode.Core/Serializers/AcSerializerCommon.cs b/AyCode.Core/Serializers/AcSerializerCommon.cs
index 2351b6a..2f1dd75 100644
--- a/AyCode.Core/Serializers/AcSerializerCommon.cs
+++ b/AyCode.Core/Serializers/AcSerializerCommon.cs
@@ -1,10 +1,8 @@
-using System.Collections;
-using System.Collections.Concurrent;
+using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using AyCode.Core.Helpers;
using AyCode.Core.Serializers.Expressions;
using AyCode.Core.Serializers.Jsons;
using LExpression = System.Linq.Expressions.Expression;
@@ -60,19 +58,14 @@ public static class AcSerializerCommon
///
/// Cache key type (usually Type)
/// Cached value type
- public sealed class ThreadLocalCache where TKey : notnull
+ public sealed class ThreadLocalCache(Func factory)
+ where TKey : notnull
{
private readonly ConcurrentDictionary _globalCache = new();
- private readonly Func _factory;
-
+
[ThreadStatic]
private static Dictionary? t_localCache;
- public ThreadLocalCache(Func factory)
- {
- _factory = factory;
- }
-
///
/// Gets a value from cache, creating it if necessary.
/// Uses ThreadLocal cache for hot path, falls back to ConcurrentDictionary.
@@ -94,7 +87,7 @@ public static class AcSerializerCommon
[MethodImpl(MethodImplOptions.NoInlining)]
private TValue GetSlow(TKey key)
{
- var value = _globalCache.GetOrAdd(key, _factory);
+ var value = _globalCache.GetOrAdd(key, factory);
// Populate ThreadLocal cache
var localCache = t_localCache ??= new Dictionary();
@@ -1033,109 +1026,104 @@ public static class AcSerializerCommon
/// Used by cross-type deserialization (Deserialize<TSource, TDest>).
/// Thread-safe and cached for performance.
///
- public sealed class PropertyMappingCache
- {
- private readonly ConcurrentDictionary<(Type Source, Type Dest), PropertyMappingInfo> _cache = new();
+ //public sealed class PropertyMappingCache
+ //{
+ // private readonly ConcurrentDictionary<(Type Source, Type Dest), PropertyMappingInfo> _cache = new();
- ///
- /// Gets or builds property mapping between two types.
- /// Result is cached for subsequent calls.
- ///
- public PropertyMappingInfo GetOrBuild(Type sourceType, Type destType, PropertyMapperDelegate? customMapper, Func getMetadata)
- {
- var key = (sourceType, destType);
- return _cache.GetOrAdd(key, _ => BuildMapping(sourceType, destType, customMapper, getMetadata));
- }
+ // ///
+ // /// Gets or builds property mapping between two types.
+ // /// Result is cached for subsequent calls.
+ // ///
+ // public PropertyMappingInfo GetOrBuild(Type sourceType, Type destType, PropertyMapperDelegate? customMapper, Func getMetadata)
+ // {
+ // var key = (sourceType, destType);
+ // return _cache.GetOrAdd(key, _ => BuildMapping(sourceType, destType, customMapper, getMetadata));
+ // }
- private static PropertyMappingInfo BuildMapping(Type sourceType, Type destType, PropertyMapperDelegate? customMapper, Func getMetadata)
- {
- var sourceProps = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
- .Where(p => p.CanRead)
- .ToArray();
+ // private static PropertyMappingInfo BuildMapping(Type sourceType, Type destType, PropertyMapperDelegate? customMapper, Func getMetadata)
+ // {
+ // var sourceProps = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
+ // .Where(p => p.CanRead)
+ // .ToArray();
- var destProps = destType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
- .Where(p => p.CanWrite)
- .ToDictionary(p => p.Name, StringComparer.Ordinal);
+ // var destProps = destType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
+ // .Where(p => p.CanWrite)
+ // .ToDictionary(p => p.Name, StringComparer.Ordinal);
- var mappings = new List<(PropertyInfo Source, PropertyInfo Dest)>();
+ // var mappings = new List<(PropertyInfo Source, PropertyInfo Dest)>();
- foreach (var sourceProp in sourceProps)
- {
- PropertyInfo? destProp = null;
+ // foreach (var sourceProp in sourceProps)
+ // {
+ // PropertyInfo? destProp = null;
- // Use custom mapper if provided
- if (customMapper != null)
- {
- destProp = customMapper(sourceProp, destType);
- }
- else
- {
- // Default: match by name
- destProps.TryGetValue(sourceProp.Name, out destProp);
- }
+ // // Use custom mapper if provided
+ // if (customMapper != null)
+ // {
+ // destProp = customMapper(sourceProp, destType);
+ // }
+ // else
+ // {
+ // // Default: match by name
+ // destProps.TryGetValue(sourceProp.Name, out destProp);
+ // }
- if (destProp != null && AreTypesCompatible(sourceProp.PropertyType, destProp.PropertyType))
- {
- mappings.Add((sourceProp, destProp));
- }
- }
+ // if (destProp != null && AreTypesCompatible(sourceProp.PropertyType, destProp.PropertyType))
+ // {
+ // mappings.Add((sourceProp, destProp));
+ // }
+ // }
- return new PropertyMappingInfo(mappings.ToArray());
- }
+ // return new PropertyMappingInfo(mappings.ToArray());
+ // }
- ///
- /// Checks if two property types are compatible for mapping.
- /// Handles exact match, inheritance, nullable unwrapping, and numeric conversions.
- ///
- private static bool AreTypesCompatible(Type sourceType, Type destType)
- {
- // Exact match
- if (sourceType == destType) return true;
+ // ///
+ // /// Checks if two property types are compatible for mapping.
+ // /// Handles exact match, inheritance, nullable unwrapping, and numeric conversions.
+ // ///
+ // private static bool AreTypesCompatible(Type sourceType, Type destType)
+ // {
+ // // Exact match
+ // if (sourceType == destType) return true;
- // Assignable (inheritance, interfaces)
- if (destType.IsAssignableFrom(sourceType)) return true;
+ // // Assignable (inheritance, interfaces)
+ // if (destType.IsAssignableFrom(sourceType)) return true;
- // Unwrap nullable types
- var sourceUnderlying = Nullable.GetUnderlyingType(sourceType) ?? sourceType;
- var destUnderlying = Nullable.GetUnderlyingType(destType) ?? destType;
+ // // Unwrap nullable types
+ // var sourceUnderlying = Nullable.GetUnderlyingType(sourceType) ?? sourceType;
+ // var destUnderlying = Nullable.GetUnderlyingType(destType) ?? destType;
- if (sourceUnderlying == destUnderlying) return true;
+ // if (sourceUnderlying == destUnderlying) return true;
- // Numeric conversions (int -> long, float -> double, etc.)
- if (IsNumericType(sourceUnderlying) && IsNumericType(destUnderlying))
- return true;
+ // // Numeric conversions (int -> long, float -> double, etc.)
+ // if (IsNumericType(sourceUnderlying) && IsNumericType(destUnderlying))
+ // return true;
- return false;
- }
+ // return false;
+ // }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static bool IsNumericType(Type type)
- {
- return type == typeof(byte) || type == typeof(sbyte) ||
- type == typeof(short) || type == typeof(ushort) ||
- type == typeof(int) || type == typeof(uint) ||
- type == typeof(long) || type == typeof(ulong) ||
- type == typeof(float) || type == typeof(double) ||
- type == typeof(decimal);
- }
- }
+ // [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ // private static bool IsNumericType(Type type)
+ // {
+ // return type == typeof(byte) || type == typeof(sbyte) ||
+ // type == typeof(short) || type == typeof(ushort) ||
+ // type == typeof(int) || type == typeof(uint) ||
+ // type == typeof(long) || type == typeof(ulong) ||
+ // type == typeof(float) || type == typeof(double) ||
+ // type == typeof(decimal);
+ // }
+ //}
///
/// Contains property mapping information for a source->destination type pair.
/// Immutable and thread-safe.
///
- public sealed class PropertyMappingInfo
- {
- public PropertyMappingInfo(IReadOnlyList<(PropertyInfo Source, PropertyInfo Dest)> mappings)
- {
- Mappings = mappings;
- }
-
- ///
- /// List of source->destination property pairs.
- ///
- public IReadOnlyList<(PropertyInfo Source, PropertyInfo Dest)> Mappings { get; }
- }
+ //public sealed record PropertyMappingInfo(IReadOnlyList<(PropertyInfo Source, PropertyInfo Dest)> Mappings)
+ //{
+ // ///
+ // /// List of source->destination property pairs.
+ // ///
+ // public IReadOnlyList<(PropertyInfo Source, PropertyInfo Dest)> Mappings { get; } = Mappings;
+ //}
///
/// Binary-specific index-to-index mapping for cross-type deserialization.
diff --git a/AyCode.Core/Serializers/AcSerializerContextBase.cs b/AyCode.Core/Serializers/AcSerializerContextBase.cs
index b464d9f..a3d4994 100644
--- a/AyCode.Core/Serializers/AcSerializerContextBase.cs
+++ b/AyCode.Core/Serializers/AcSerializerContextBase.cs
@@ -30,9 +30,6 @@ public abstract class AcSerializerContextBase where TMetadata : TypeM
///
protected abstract Func MetadataFactory { get; }
- private const int BitArraySize = 1024;
- private const int MaxSmallId = BitArraySize * 64;
-
#region Wrapper Access
///
@@ -67,149 +64,21 @@ public abstract class AcSerializerContextBase where TMetadata : TypeM
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetValue(TypeMetadataWrapper wrapper, int refId, out object? instance)
{
- var map = wrapper.IdentityMap as AcSerializerCommon.IdentityMap;
- if (map == null)
- {
- map = new AcSerializerCommon.IdentityMap();
- wrapper.IdentityMap = map;
- }
-
- return map.TryGetValue(refId, out instance);
+ return wrapper.TryGetValue(refId, out instance);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetValue(TypeMetadataWrapper wrapper, long refId, out object? instance)
{
- var map = wrapper.IdentityMap as AcSerializerCommon.IdentityMap;
- if (map == null)
- {
- map = new AcSerializerCommon.IdentityMap();
- wrapper.IdentityMap = map;
- }
-
- return map.TryGetValue(refId, out instance);
+ return wrapper.TryGetValue(refId, out instance);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetValue(TypeMetadataWrapper wrapper, Guid refId, out object? instance)
{
- var map = wrapper.IdentityMap as AcSerializerCommon.IdentityMap;
- if (map == null)
- {
- map = new AcSerializerCommon.IdentityMap();
- wrapper.IdentityMap = map;
- }
-
- return map.TryGetValue(refId, out instance);
+ return wrapper.TryGetValue(refId, out instance);
}
- ///
- /// Tries to track an object with int RefId.
- /// Use when wrapper.Metadata.IdAccessorType == Int32.
- /// Returns true if first occurrence.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool TryTrack(TypeMetadataWrapper wrapper, object obj, out int refId)
- {
- Debug.Assert(wrapper.Metadata.IdAccessorType == AcSerializerCommon.IdAccessorType.Int32);
-
- var getter = (Func