From fe35e60649a0a1a6eedc3b683fbc6e7f34e3f9e0 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 21 Feb 2026 08:54:50 +0100 Subject: [PATCH] Enable AcBinary serialization for all test models - Set `[AcBinarySerializable(true)]` on all SharedTestModels types - Default `UseMetadata` to true for property hash footer - Reset slotted ID maps and cache indices in serializer context - Reduce test iterations for DEBUG builds to speed up runs - Add debug comments in context `Clear()` method --- AyCode.Core.Serializers.Console/Program.cs | 4 +- .../TestModels/SharedTestModels.cs | 44 +++++++++---------- .../Serializers/AcSerializerContextBase.cs | 3 ++ ...rySerializer.BinarySerializationContext.cs | 2 + .../Binaries/AcBinarySerializerOptions.cs | 2 +- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/AyCode.Core.Serializers.Console/Program.cs b/AyCode.Core.Serializers.Console/Program.cs index f313729..a645910 100644 --- a/AyCode.Core.Serializers.Console/Program.cs +++ b/AyCode.Core.Serializers.Console/Program.cs @@ -46,8 +46,8 @@ public static class Program private static readonly UTF8Encoding Utf8NoBom = new(encoderShouldEmitUTF8Identifier: false); #if DEBUG - private static int WarmupIterations = 5; - private static int TestIterations = 10; + private static int WarmupIterations = 0; + private static int TestIterations = 1; #else private static int WarmupIterations = 5000; private static int TestIterations = 1000; diff --git a/AyCode.Core.Tests/TestModels/SharedTestModels.cs b/AyCode.Core.Tests/TestModels/SharedTestModels.cs index 0d4f97e..11129a1 100644 --- a/AyCode.Core.Tests/TestModels/SharedTestModels.cs +++ b/AyCode.Core.Tests/TestModels/SharedTestModels.cs @@ -55,7 +55,7 @@ public enum TestUserRole /// Implements IId<int> for semantic $id/$ref serialization. /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class SharedTag : IId { @@ -80,7 +80,7 @@ public partial class SharedTag : IId /// Shared category - for hierarchical cross-reference testing. /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class SharedCategory : IId { @@ -106,7 +106,7 @@ public partial class SharedCategory : IId /// Shared user reference - appears in many places to test $ref deduplication. /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class SharedUser : IId { @@ -136,7 +136,7 @@ public partial class SharedUser : IId /// User preferences - non-IId nested object /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class UserPreferences { @@ -162,7 +162,7 @@ public partial class UserPreferences /// Does NOT implement IId, so uses standard Newtonsoft reference tracking. /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class MetadataInfo { @@ -190,7 +190,7 @@ public partial class MetadataInfo /// Level 1: Main order - root of the hierarchy /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class TestOrder : IId { @@ -250,7 +250,7 @@ public partial class TestOrder : IId /// Level 2: Order item with pallets /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class TestOrderItem : IId { @@ -290,7 +290,7 @@ public partial class TestOrderItem : IId /// Level 3: Pallet containing measurements /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class TestPallet : IId { @@ -333,7 +333,7 @@ public partial class TestPallet : IId /// Level 4: Measurement with multiple points /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class TestMeasurement : IId { @@ -368,7 +368,7 @@ public partial class TestMeasurement : IId /// Level 5: Deepest level - measurement point /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] [MessagePackObject] public partial class TestMeasurementPoint : IId { @@ -402,7 +402,7 @@ public partial class TestMeasurementPoint : IId /// /// Order with Guid Id - for testing Guid-based IId /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class TestGuidOrder : IId { public Guid Id { get; set; } @@ -414,7 +414,7 @@ public class TestGuidOrder : IId /// /// Item with Guid Id /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class TestGuidItem : IId { public Guid Id { get; set; } @@ -430,7 +430,7 @@ public class TestGuidItem : IId /// Simulates NopCommerce GenericAttribute - stores key-value pairs where DateTime values /// are stored as strings in the database. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class TestGenericAttribute { public int Id { get; set; } @@ -442,7 +442,7 @@ public class TestGenericAttribute /// DTO with GenericAttributes collection - simulates OrderDto with string-stored DateTime values. /// This reproduces the production bug where Binary serialization was thought to corrupt DateTime strings. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class TestDtoWithGenericAttributes : IId { public int Id { get; set; } @@ -453,7 +453,7 @@ public class TestDtoWithGenericAttributes : IId /// /// Order with nullable collections for null vs empty testing /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class TestOrderWithNullableCollections { public int Id { get; set; } @@ -466,7 +466,7 @@ public class TestOrderWithNullableCollections /// Class with all primitive types for WASM/serialization testing /// [MemoryPackable] -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public partial class PrimitiveTestClass { public int IntValue { get; set; } @@ -489,7 +489,7 @@ public partial class PrimitiveTestClass /// Class with extended primitive types for full serializer coverage. /// Includes DateTimeOffset, TimeSpan, Dictionary, null properties. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ExtendedPrimitiveTestClass { public int Id { get; set; } @@ -519,7 +519,7 @@ public class ExtendedPrimitiveTestClass /// /// Class with array of objects containing null items for WriteNull coverage /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ObjectWithNullItems { public int Id { get; set; } @@ -534,7 +534,7 @@ public class ObjectWithNullItems /// "Server-side" DTO with extra properties that the "client" doesn't know about. /// Used to test SkipValue functionality when deserializing unknown properties. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ServerCustomerDto : IId { public int Id { get; set; } @@ -567,7 +567,7 @@ public class ServerCustomerDto : IId /// the deserializer must skip unknown properties correctly /// while still maintaining string intern table consistency. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ClientCustomerDto : IId { public int Id { get; set; } @@ -581,7 +581,7 @@ public class ClientCustomerDto : IId /// Server DTO with nested objects that client doesn't know about. /// Tests skipping complex nested structures. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ServerOrderWithExtras : IId { public int Id { get; set; } @@ -602,7 +602,7 @@ public class ServerOrderWithExtras : IId /// /// Client version of the order - doesn't have Customer/RelatedCustomers properties. /// -[AcBinarySerializable(false)] +[AcBinarySerializable(true)] public class ClientOrderSimple : IId { public int Id { get; set; } diff --git a/AyCode.Core/Serializers/AcSerializerContextBase.cs b/AyCode.Core/Serializers/AcSerializerContextBase.cs index 548d850..ac16d16 100644 --- a/AyCode.Core/Serializers/AcSerializerContextBase.cs +++ b/AyCode.Core/Serializers/AcSerializerContextBase.cs @@ -115,6 +115,9 @@ public abstract class AcSerializerContextBase /// public virtual void Clear() { + //System.Diagnostics.Debug.WriteLine($"Wrappers count: {_wrappers.Count}"); + //Console.WriteLine($"Wrappers count: {_wrappers.Count}"); + foreach (var wrapper in _wrappers.Values) { wrapper.ResetTracking(Options.UseAsync); diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs index 13b312e..cacd312 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializer.BinarySerializationContext.cs @@ -289,9 +289,11 @@ public static partial class AcBinarySerializer _stringInternMap?.Reset(); _metadataSeenBits.AsSpan().Clear(); _metadataSeenOverflow?.Clear(); + ResetSlottedMaps(_slottedIdMapsInt32); ResetSlottedMaps(_slottedIdMapsInt64); ResetSlottedMaps(_slottedIdMapsGuid); + _nextCacheIndex = 0; NextFirstIndex = 0; ScanVisitIndex = 0; diff --git a/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs b/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs index 6b01f75..e0fff73 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinarySerializerOptions.cs @@ -82,7 +82,7 @@ public sealed class AcBinarySerializerOptions : AcSerializerOptions /// allowing the deserializer to match properties by name between different types. /// Default: false (no overhead) /// - public bool UseMetadata { get; set; } = false; + public bool UseMetadata { get; set; } = true; public bool UseGeneratedCode { get; set; } = true;