From e6c1dcb6268fddd30d7e5b5348435c5d4f262a83 Mon Sep 17 00:00:00 2001 From: "Alexander.Shvedov" Date: Mon, 19 Feb 2024 14:20:18 +0100 Subject: [PATCH] UnsafeWriter: migrate whole RD to explicit type APIs --- .../Lifetimes/Serialization/UnsafeWriter.cs | 49 ++++++------ .../CollectionSerializers.cs | 71 ++++++++++------ .../ReflectionSerializers.cs | 2 +- .../ScalarSerializer.cs | 9 +-- rd-net/RdFramework/Base/RdExtBase.cs | 71 ++++++++-------- rd-net/RdFramework/IInternRoot.cs | 5 +- rd-net/RdFramework/IWire.cs | 2 +- rd-net/RdFramework/Impl/ExtCreatedUtils.cs | 17 ++-- .../Impl/HeavySingleContextHandler.cs | 21 ++--- .../Impl/LightSingleContextHandler.cs | 3 +- rd-net/RdFramework/Impl/ProtocolContexts.cs | 55 +++++++------ rd-net/RdFramework/Impl/RdList.cs | 68 ++++++++-------- rd-net/RdFramework/Impl/RdMap.cs | 41 +++++----- rd-net/RdFramework/Impl/RdProperty.cs | 45 +++++------ rd-net/RdFramework/Impl/RdSet.cs | 19 ++--- rd-net/RdFramework/Impl/Serializers.cs | 40 +++++----- rd-net/RdFramework/Impl/SerializersEx.cs | 18 ++--- rd-net/RdFramework/Impl/SocketWire.cs | 14 ++-- rd-net/RdFramework/RdId.cs | 3 +- rd-net/RdFramework/Tasks/RdFault.cs | 18 ++--- rd-net/RdFramework/Tasks/RdTaskResult.cs | 2 +- .../Text/Impl/Intrinsics/RdAssertion.cs | 19 ++--- .../Impl/Intrinsics/RdTextBufferChange.cs | 6 +- .../Text/Intrinsics/RdTextChangeSerializer.cs | 10 +-- .../Intrinsics/TextBufferVersionSerializer.cs | 4 +- .../Serialization/NativeMemoryPoolTests.cs | 8 +- .../Serialization/UnsafeMarshallersTest.cs | 80 +++++++++---------- .../Threading/ByteBufferAsyncProcessorTest.cs | 64 ++++++++------- .../Interning/InterningTestModel.cs | 8 +- .../GenericBuiltInSerializersTest.cs | 8 +- ...PolymorphicScalarBuiltInSerializersTest.cs | 4 +- .../ProxyGeneratorAsyncCallsTest.cs | 2 +- .../ScalarBuiltInSerializerTests.cs | 24 +++--- .../Reflection/data/Example/CustomReactive.cs | 4 +- .../Reflection/data/Generated/RefExt.cs | 18 ++--- rd-net/Test.RdFramework/SerializersTest.cs | 2 +- rd-net/Test.RdFramework/UnsafeWriterTest.cs | 10 ++- 37 files changed, 436 insertions(+), 408 deletions(-) diff --git a/rd-net/Lifetimes/Serialization/UnsafeWriter.cs b/rd-net/Lifetimes/Serialization/UnsafeWriter.cs index e9656d1d5..3c95a48e5 100644 --- a/rd-net/Lifetimes/Serialization/UnsafeWriter.cs +++ b/rd-net/Lifetimes/Serialization/UnsafeWriter.cs @@ -18,8 +18,6 @@ namespace JetBrains.Serialization /// It is so must be used only with (possibly nested) using in stack-like way. /// contains start position and length of currently serialized data (start + len = position), so when disposed it reverts writer /// position to the cookie's start position. - /// - /// /// /// [PublicAPI] @@ -116,7 +114,7 @@ public byte* Data /// /// Writes ` - sizeof(int)` into the pointer. - /// Cookie must be prepared by invoking `(0)` as first cookie call. + /// Cookie must be prepared by invoking `(0)` as first cookie call. /// public void WriteIntLength() { @@ -645,36 +643,38 @@ public void WriteDateTime(DateTime value) { if (Mode.IsAssertion) Assertion.Assert(value.Kind != DateTimeKind.Local, "Use UTC time"); - Write(value.Ticks); + WriteInt64(value.Ticks); } [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public void WriteTimeSpan(TimeSpan value) { - Write(value.Ticks); + WriteInt64(value.Ticks); } [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public void WriteUri(Uri value) { - Write(Uri.EscapeUriString(value.OriginalString)); + WriteString(Uri.EscapeUriString(value.OriginalString)); } [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public void WriteString(string? value) { - if (value == null) Write(-1); + if (value == null) + { + WriteInt32(-1); + } else { - Write(value.Length); + WriteInt32(value.Length); WriteStringContentInternal(this, value, 0, value.Length); } } /// - /// Doesn't write length prefix, only string contents. If value == null, does nothing. + /// Doesn't write length prefix, only string contents. If is value, does nothing. /// - /// [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public void WriteStringContent(string? value) { @@ -683,11 +683,8 @@ public void WriteStringContent(string? value) } /// - /// Doesn't write length prefix, only string contents. If value == null, does nothing. + /// Doesn't write length prefix, only string contents. If is value, does nothing. /// - /// - /// - /// [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public void WriteStringContent(string? value, int offset, int count) { @@ -792,11 +789,11 @@ public void WriteArray(int[]? value) { if (value == null) { - Write(-1); + WriteInt32(-1); } else { - Write(value.Length); + WriteInt32(value.Length); fixed (int* c = value) { Write((byte*)c, value.Length * sizeof(int)); @@ -808,12 +805,12 @@ public void WriteByteArray(byte[]? value) { if (value == null) { - Write(-1); + WriteInt32(-1); } else { var size = value.Length; - Write(size); + WriteInt32(size); Prepare(size); Marshal.Copy(value, 0, (IntPtr)myPtr, size); // Unlike MemoryUtil::CopyMemory, this is a CLR intrinsic call myPtr += size; @@ -884,11 +881,11 @@ public void WriteCollection(WriteDelegate writeDelegate, TCol { if (value == null) { - Write(-1); + WriteInt32(-1); } else { - Write(value.Count); + WriteInt32(value.Count); foreach (var x in value) { writeDelegate(this, x); @@ -896,16 +893,18 @@ public void WriteCollection(WriteDelegate writeDelegate, TCol } } - public void Write(WriteDelegate writeKeyDelegate, WriteDelegate writeValueDelegate, TDictionary? value) + public void Write( + WriteDelegate writeKeyDelegate, WriteDelegate writeValueDelegate, TDictionary? value) where TDictionary : IDictionary { if (value == null) { - Write(-1); + WriteInt32(-1); } else { - Write(value.Count); + WriteInt32(value.Count); + foreach (var kv in value) { writeKeyDelegate(this, kv.Key); @@ -920,7 +919,7 @@ public void Write(WriteDelegate writeKeyDelegate, Write public bool WriteNullness([NotNullWhen(true)] T? value) where T : struct { var res = value != null; - Write(res); + WriteBoolean(res); return res; } @@ -928,7 +927,7 @@ public bool WriteNullness([NotNullWhen(true)] T? value) where T : struct public bool WriteNullness([NotNullWhen(true)] T? value) where T : class { var res = value != null; - Write(res); + WriteBoolean(res); return res; } } diff --git a/rd-net/RdFramework.Reflection/CollectionSerializers.cs b/rd-net/RdFramework.Reflection/CollectionSerializers.cs index 4d35832f9..bcaf2ab55 100644 --- a/rd-net/RdFramework.Reflection/CollectionSerializers.cs +++ b/rd-net/RdFramework.Reflection/CollectionSerializers.cs @@ -12,83 +12,104 @@ internal class CollectionSerializers { public static SerializerPair CreateListSerializerPair(SerializerPair itemSerializer) { - CtxReadDelegate?> readListSerializer = (ctx, reader) => reader.ReadList(itemSerializer.GetReader(), ctx); - CtxWriteDelegate> writeListSerializer =(ctx, writer, value) => writer.WriteEnumerable(itemSerializer.GetWriter(), ctx, value); + CtxReadDelegate?> readListSerializer = + (ctx, reader) => reader.ReadList(itemSerializer.GetReader(), ctx); + + CtxWriteDelegate> writeListSerializer = + (ctx, writer, value) => writer.WriteEnumerable(itemSerializer.GetWriter(), ctx, value); + return new SerializerPair(readListSerializer, writeListSerializer); } - public static SerializerPair CreateDictionarySerializerPair(SerializerPair keySerializer, SerializerPair valueSerializer) + public static SerializerPair CreateDictionarySerializerPair( + SerializerPair keySerializer, SerializerPair valueSerializer) { var read = CreateReadDictionary(keySerializer, valueSerializer); + CtxWriteDelegate?> write = (ctx, writer, value) => { if (value is Dictionary val && !Equals(val.Comparer, EqualityComparer.Default)) throw new Exception($"Unable to serialize {value.GetType().ToString(true)}. Custom equality comparers are not supported"); + if (value == null) { - writer.Write(-1); + writer.WriteInt32(-1); return; } - writer.Write(value.Count); - var keyw = keySerializer.GetWriter(); - var valuew = valueSerializer.GetWriter(); + + writer.WriteInt32(value.Count); + + var keyWriter = keySerializer.GetWriter(); + var valueWriter = valueSerializer.GetWriter(); + foreach (var kvp in value) { - keyw(ctx, writer, kvp.Key); - valuew(ctx, writer, kvp.Value); + keyWriter(ctx, writer, kvp.Key); + valueWriter(ctx, writer, kvp.Value); } }; + return new SerializerPair(read, write); } - public static SerializerPair CreateReadOnlyDictionarySerializerPair(SerializerPair keySerializer, SerializerPair valueSerializer) + public static SerializerPair CreateReadOnlyDictionarySerializerPair( + SerializerPair keySerializer, SerializerPair valueSerializer) { #if NET35 throw new NotSupportedException(); #else var read = CreateReadDictionary(keySerializer, valueSerializer); - CtxWriteDelegate?> write = (ctx, writer, value) => + + CtxWriteDelegate?> write = (context, writer, value) => { if (value is Dictionary val && !Equals(val.Comparer, EqualityComparer.Default)) throw new Exception($"Unable to serialize {value.GetType().ToString(true)}. Custom equality comparers are not supported"); + if (value == null) { - writer.Write(-1); + writer.WriteInt32(-1); return; } - writer.Write(value.Count); - var keyw = keySerializer.GetWriter(); - var valuew = valueSerializer.GetWriter(); + + writer.WriteInt32(value.Count); + + var keyWriter = keySerializer.GetWriter(); + var valueWriter = valueSerializer.GetWriter(); + foreach (var kvp in value) { - keyw(ctx, writer, kvp.Key); - valuew(ctx, writer, kvp.Value); + keyWriter(context, writer, kvp.Key); + valueWriter(context, writer, kvp.Value); } }; + return new SerializerPair(read, write); #endif } - - private static CtxReadDelegate?> CreateReadDictionary(SerializerPair keySerializer, SerializerPair valueSerializer) + private static CtxReadDelegate?> CreateReadDictionary( + SerializerPair keySerializer, SerializerPair valueSerializer) { - CtxReadDelegate?> read = (ctx, reader) => + CtxReadDelegate?> read = (context, reader) => { int count = reader.ReadInt(); if (count == -1) return null; + var result = new Dictionary(count); - var keyr = keySerializer.GetReader(); - var valuer = valueSerializer.GetReader(); - for (int i = 0; i < count; i++) + var keyReader = keySerializer.GetReader(); + var valueReader = valueSerializer.GetReader(); + + for (var index = 0; index < count; index++) { - var key = keyr(ctx, reader); - var value = valuer(ctx, reader); + var key = keyReader(context, reader); + var value = valueReader(context, reader); result.Add(key, value); } return result; }; + return read; } } diff --git a/rd-net/RdFramework.Reflection/ReflectionSerializers.cs b/rd-net/RdFramework.Reflection/ReflectionSerializers.cs index e30c3d375..11bf16eaa 100644 --- a/rd-net/RdFramework.Reflection/ReflectionSerializers.cs +++ b/rd-net/RdFramework.Reflection/ReflectionSerializers.cs @@ -253,7 +253,7 @@ private void RegisterModelSerializer() { if (allowNullable) { - unsafeWriter.Write(value != null); + unsafeWriter.WriteBoolean(value != null); if (value == null) return; } diff --git a/rd-net/RdFramework.Reflection/ScalarSerializer.cs b/rd-net/RdFramework.Reflection/ScalarSerializer.cs index 675a755f8..7ebc4fb2b 100644 --- a/rd-net/RdFramework.Reflection/ScalarSerializer.cs +++ b/rd-net/RdFramework.Reflection/ScalarSerializer.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Concurrent; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -154,7 +152,7 @@ private SerializerPair CreateCustomScalar(ISerializersSource serializers) if (allowNullable) { - unsafeWriter.Write(value != null); + unsafeWriter.WriteBoolean(value != null); if (value == null) return; } @@ -207,9 +205,10 @@ private SerializerPair CreateEnumSerializer() var writerCaster = Expression.Lambda>(writerConvert, writerParameter).Compile(); if (Mode.IsAssertion) Assertion.Require(typeof(T).IsSubclassOf(typeof(Enum)), "{0}", typeof(T)); + var result = new SerializerPair( - (CtxReadDelegate) ((ctx, reader) => readerCaster(reader.ReadInt())), - (CtxWriteDelegate) ((ctx, w, o) => w.Write(writerCaster(o)))); + (CtxReadDelegate) ((_, reader) => readerCaster(reader.ReadInt())), + (CtxWriteDelegate) ((_, writer, o) => writer.WriteInt32(writerCaster(o)))); return result; } diff --git a/rd-net/RdFramework/Base/RdExtBase.cs b/rd-net/RdFramework/Base/RdExtBase.cs index b667e4c48..c6f2d52bb 100644 --- a/rd-net/RdFramework/Base/RdExtBase.cs +++ b/rd-net/RdFramework/Base/RdExtBase.cs @@ -25,13 +25,12 @@ public enum ExtState Disconnected } - - + private readonly ExtWire myExtWire = new ExtWire(); [CanBeNull] private IProtocol myExtProtocol; - + public sealed override IProtocol TryGetProto() => myExtProtocol ?? base.TryGetProto(); - + public readonly IReadonlyProperty Connected; protected RdExtBase() { @@ -50,10 +49,9 @@ protected override void Init(Lifetime lifetime, IProtocol parentProto, Serializa Protocol.InitTrace?.Log($"{this} :: binding"); var parentWire = parentProto.Wire; - + parentProto.Serializers.RegisterToplevelOnce(GetType(), Register); - - if (!TryGetSerializationContext(out var serializationContext)) +if (!TryGetSerializationContext(out var serializationContext)) return; var extScheduler = parentProto.Scheduler; @@ -64,26 +62,27 @@ protected override void Init(Lifetime lifetime, IProtocol parentProto, Serializa var parentProtocolImpl = (Protocol)parentProto; var proto = new Protocol(parentProto.Name, parentProto.Serializers, parentProto.Identities, extScheduler, myExtWire, lifetime, parentProtocolImpl, this.CreateExtSignal()); myExtProtocol = proto; - + //protocol must be set first to allow bindable bind to it using (AllowBindCookie.Create()) { base.PreInit(lifetime, proto); base.Init(lifetime, proto, ctx); } - + var bindableParent = Parent as RdBindableBase; var info = new ExtCreationInfo(Location, bindableParent?.RdId, SerializationHash, this); using (Signal.NonPriorityAdviseCookie.Create()) - { - parentProtocolImpl.SubmitExtCreated(info); + + + { + + parentProtocolImpl.SubmitExtCreated(info); } - parentWire.Advise(lifetime, this); - SendState(parentWire, ExtState.Ready); - - Protocol.InitTrace?.Log($"{this} :: bound"); - }, + parentWire.Advise(lifetime, this);SendState(parentWire, ExtState.Ready); + + Protocol.InitTrace?.Log($"{this} :: bound");}, () => { myExtProtocol = null; @@ -106,24 +105,24 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf SendState(myExtWire.RealWire, ExtState.ReceivedCounterPart); myExtWire.Connected.Set(true); break; - + case ExtState.ReceivedCounterPart: myExtWire.Connected.Set(true); //don't set anything if already set break; - + case ExtState.Disconnected: myExtWire.Connected.Set(false); break; - + default: throw new ArgumentOutOfRangeException("Unsupported state: "+remoteState); } - + var counterpartSerializationHash = reader.ReadLong(); if (counterpartSerializationHash != SerializationHash && base.TryGetProto() is {} parentProto) { parentProto.Scheduler.Queue(() => parentProto.OutOfSyncModels.Add(this)); - + var message = $"{this} : SerializationHash doesn't match to counterpart: maybe you forgot to generate models?Our: `${SerializationHash}` counterpart: {counterpartSerializationHash}"; if (parentProto is Protocol { ThrowErrorOnOutOfSyncModels: true }) { @@ -141,17 +140,17 @@ private void SendState(IWire parentWire, ExtState state) var parentProto = base.TryGetProto(); if (parentProto == null) return; - + using(parentProto.Contexts.CreateSendWithoutContextsCookie()) + { parentWire.Send(RdId, writer => { SendTrace?.Log($"{this} : {state}"); - writer.Write((int)state); - writer.Write(SerializationHash); + writer.WriteInt32((int)state); + writer.WriteInt64(SerializationHash); }); + } } - - protected override void InitBindableFields(Lifetime lifetime) { foreach (var pair in BindableChildren) @@ -161,26 +160,26 @@ protected override void InitBindableFields(Lifetime lifetime) using (reactive.UsingLocalChange()) { reactive.BindPolymorphic(); - } + } } else { pair.Value?.BindPolymorphic(); } } + } protected override string ShortName => "ext"; } - - + + class ExtWire : IWire { internal readonly ViewableProperty Connected = new ViewableProperty(false); public IWire RealWire; - private struct QueueItem { public readonly RdId Id; @@ -195,7 +194,7 @@ public QueueItem(RdId id, byte[] bytes, KeyValuePair[] st } } - + private readonly Queue mySendQ = new Queue(); public bool IsStub => RealWire.IsStub; @@ -230,7 +229,7 @@ public ExtWire() { contextValueRestorers.Add(context.UpdateValueBoxed(value)); } - + try { RealWire.Send(p.Id, writer => writer.WriteRaw(p.Bytes, 0, p.Bytes.Length)); @@ -243,11 +242,11 @@ public ExtWire() contextValueRestorers.Clear(); } } - } + } }); } - + public void Send(RdId id, TContext param, Action writer) { if (RealWire.IsStub) @@ -260,8 +259,8 @@ public void Send(RdId id, TContext param, Action>.Instance + var storedContext = Contexts.IsSendWithoutContexts + ? EmptyArray>.Instance : Contexts.RegisteredContexts.Select(it => new KeyValuePair(it, it.ValueBoxed)).ToArray(); mySendQ.Enqueue(new QueueItem(id, cookie.CloneData(), storedContext)); if (!RealWire.Contexts.IsSendWithoutContexts) diff --git a/rd-net/RdFramework/IInternRoot.cs b/rd-net/RdFramework/IInternRoot.cs index 5e7f7946d..5574acad7 100644 --- a/rd-net/RdFramework/IInternRoot.cs +++ b/rd-net/RdFramework/IInternRoot.cs @@ -64,7 +64,10 @@ internal InternId(int value) public static InternId Read(UnsafeReader reader) => new InternId(reader.ReadInt()); - public static void Write(UnsafeWriter writer, InternId value) => writer.Write(value.myValue == InvalidId ? value.myValue : value.myValue ^ 1); + public static void Write(UnsafeWriter writer, InternId value) + { + writer.WriteInt32(value.myValue == InvalidId ? value.myValue : value.myValue ^ 1); + } public bool Equals(InternId other) => myValue == other.myValue; diff --git a/rd-net/RdFramework/IWire.cs b/rd-net/RdFramework/IWire.cs index e0301199d..ee4bfa47c 100644 --- a/rd-net/RdFramework/IWire.cs +++ b/rd-net/RdFramework/IWire.cs @@ -98,7 +98,7 @@ public void Send(RdId id, TParam param, Action wri using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { var bookmark = new UnsafeWriter.Bookmark(cookie.Writer); - cookie.Writer.Write(0); //placeholder for length + cookie.Writer.WriteInt32(0); //placeholder for length id.Write(cookie.Writer); if (!myBackwardsCompatibleWireFormat) diff --git a/rd-net/RdFramework/Impl/ExtCreatedUtils.cs b/rd-net/RdFramework/Impl/ExtCreatedUtils.cs index 30c77aea4..cda1ede2e 100644 --- a/rd-net/RdFramework/Impl/ExtCreatedUtils.cs +++ b/rd-net/RdFramework/Impl/ExtCreatedUtils.cs @@ -23,7 +23,7 @@ public static RdSignal CreateExtSignal(this IRdDynamic @this) { WriteRName(writer, value.Name); writer.WriteNullableStruct((_, w, v) => w.Write(v), ctx, value.Id); - writer.Write(value.Hash); + writer.WriteInt64(value.Hash); } ); var baseId = @this is IRdWireable wireable ? wireable.RdId : RdId.Nil; @@ -31,13 +31,13 @@ public static RdSignal CreateExtSignal(this IRdDynamic @this) signal.Async = true; return signal; } - + internal static RName ReadRName(UnsafeReader reader) { var isEmpty = reader.ReadBool(); if (isEmpty) return RName.Empty; - + var rootName = reader.ReadString() ?? throw new InvalidOperationException(); var last = reader.ReadBoolean(); var rName = new RName(rootName); @@ -53,16 +53,18 @@ internal static RName ReadRName(UnsafeReader reader) internal static void WriteRName(UnsafeWriter writer, RName value) { - writer.Write(value == RName.Empty); + writer.WriteBoolean(value == RName.Empty); TraverseRName(value, true, (rName, last) => { if (rName == RName.Empty) return; + if (rName.Parent != RName.Empty) { - writer.Write(rName.Separator); + writer.WriteString(rName.Separator); } - writer.Write(rName.LocalName.ToString()); - writer.Write(last); + + writer.WriteString(rName.LocalName.ToString()); + writer.WriteBoolean(last); }); } @@ -72,6 +74,7 @@ private static void TraverseRName(RName rName, bool last, Action ha { TraverseRName(rParent, false, handler); } + handler(rName, last); } } diff --git a/rd-net/RdFramework/Impl/HeavySingleContextHandler.cs b/rd-net/RdFramework/Impl/HeavySingleContextHandler.cs index 196dc0bab..65c9659e9 100644 --- a/rd-net/RdFramework/Impl/HeavySingleContextHandler.cs +++ b/rd-net/RdFramework/Impl/HeavySingleContextHandler.cs @@ -52,7 +52,7 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt { base.Init(lifetime, proto, ctx); Assertion.Assert(myHandler.IsSendWithoutContexts,"Must bind context handler without sending contexts to prevent reentrancy"); - + myInternRoot.Bind(); myProtocolValueSet.Bind(); @@ -81,7 +81,7 @@ public void WriteValue(SerializationCtx context, UnsafeWriter writer) if (value == null) { InternId.Write(writer, InternId.Invalid); - writer.Write(false); + writer.WriteBoolean(false); } else { @@ -93,7 +93,7 @@ public void WriteValue(SerializationCtx context, UnsafeWriter writer) InternId.Write(writer, internedId); if (!internedId.IsValid) { - writer.Write(true); + writer.WriteBoolean(true); Context.WriteDelegate(context, writer, value); } } @@ -109,8 +109,11 @@ public void RegisterValueInValueSet() { var value = Context.Value; if (value == null) return; + using (myHandler.CreateSendWithoutContextsCookie()) + { AddValueToProtocolValueSetImpl(value); + } } public T ReadValue(SerializationCtx context, UnsafeReader reader) @@ -133,15 +136,15 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf Assertion.Fail(message); } } - + internal class ConcurrentRdSet : RdReactiveBase, IAppendOnlyViewableConcurrentSet, IRdWireable { private readonly ProtocolContexts myProtocolContexts; private readonly ViewableConcurrentSet mySet; private readonly ThreadLocal myIsThreadLocal = new(); - + public int Count => mySet.Count; - + public CtxReadDelegate ReadValueDelegate { get; } public CtxWriteDelegate WriteValueDelegate { get; } @@ -165,7 +168,7 @@ protected override void Init(Lifetime bindLifetime, IProtocol proto, Serializati View(bindLifetime, (_, value) => { if (!myIsThreadLocal.Value) return; - + SendAdd(proto.Wire, SendContext.Of(ctx, value, this)); }); } @@ -181,7 +184,7 @@ private void SendAdd(IWire wire, SendContext> context) ourLogSend.Trace($"{sendContext.This} :: {kind} :: {value.PrintToString()}"); }); - } + } public override void Print(PrettyPrinter printer) { @@ -205,7 +208,7 @@ public override void Print(PrettyPrinter printer) public bool Add(T value) { Assertion.Assert(!myIsThreadLocal.Value); - + myIsThreadLocal.Value = true; try { diff --git a/rd-net/RdFramework/Impl/LightSingleContextHandler.cs b/rd-net/RdFramework/Impl/LightSingleContextHandler.cs index 3cd6c789b..f09c32f80 100644 --- a/rd-net/RdFramework/Impl/LightSingleContextHandler.cs +++ b/rd-net/RdFramework/Impl/LightSingleContextHandler.cs @@ -26,7 +26,8 @@ public object ReadValueBoxed(SerializationCtx context, UnsafeReader reader) public void WriteValue(SerializationCtx context, UnsafeWriter writer) { var value = Context.Value; - writer.Write(value != null); + writer.WriteBoolean(value != null); + if (value != null) Context.WriteDelegate(context, writer, value); } diff --git a/rd-net/RdFramework/Impl/ProtocolContexts.cs b/rd-net/RdFramework/Impl/ProtocolContexts.cs index 0dd75267a..f18569a8f 100644 --- a/rd-net/RdFramework/Impl/ProtocolContexts.cs +++ b/rd-net/RdFramework/Impl/ProtocolContexts.cs @@ -24,8 +24,8 @@ public class ProtocolContexts : RdReactiveBase private readonly ConcurrentDictionary myHandlersMap = new(); private readonly object myOrderingLock = new(); private readonly ThreadLocal mySendWithoutContexts = new(() => false); - - + + internal readonly struct SendWithoutContextsCookie : IDisposable { private readonly ProtocolContexts myContexts; @@ -47,14 +47,14 @@ public void Dispose() private readonly SerializationCtx mySerializationCtx; internal SendWithoutContextsCookie CreateSendWithoutContextsCookie() => new SendWithoutContextsCookie(this); - public bool IsSendWithoutContexts => mySendWithoutContexts.Value; + public bool IsSendWithoutContexts => mySendWithoutContexts.Value; public ProtocolContexts(SerializationCtx serializationCtx) { Async = true; mySerializationCtx = serializationCtx; } - + public ICollection RegisteredContexts => myHandlersMap.Keys; internal ISingleContextHandler GetHandlerForContext(RdContext context) @@ -67,7 +67,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf var contextBase = RdContextBase.Read(mySerializationCtx, reader); contextBase.RegisterOn(this); - + myCounterpartHandlers.Add(myHandlersMap[contextBase]); } @@ -76,7 +76,7 @@ private void DoAddHandler(RdContext context, ISingleContextHandler hand if (myHandlersMap.TryAdd(context, handler)) { context.RegisterOn(mySerializationCtx.Serializers); - lock (myOrderingLock) + lock (myOrderingLock) myHandlerOrder.Add(handler); } } @@ -89,12 +89,12 @@ private void PreBindHandler(Lifetime lifetime, string key, ISingleContextHandler bindableHandler.PreBind(lifetime, this, key); } } - + private void BindHandler(ISingleContextHandler handler) { if (handler is RdBindableBase bindableHandler) { - using (CreateSendWithoutContextsCookie()) + using (CreateSendWithoutContextsCookie()) bindableHandler.Bind(); } } @@ -105,25 +105,25 @@ private void SendContextToRemote(RdContextBase context) var wire = TryGetProto()?.Wire; if (wire == null) return; - + using(CreateSendWithoutContextsCookie()) wire.Send(RdId, writer => { RdContextBase.Write(mySerializationCtx, writer, context); }); } - + private void EnsureHeavyHandlerExists(RdContext context) { if (Mode.IsAssertion) Assertion.Assert(context.IsHeavy, "key.IsHeavy"); - if (!myHandlersMap.ContainsKey(context)) + if (!myHandlersMap.ContainsKey(context)) DoAddHandler(context, new HeavySingleContextHandler(context, this)); } - + private void EnsureLightHandlerExists(RdContext context) { if (Mode.IsAssertion) Assertion.Assert(!context.IsHeavy, "!key.IsHeavy"); - if (!myHandlersMap.ContainsKey(context)) + if (!myHandlersMap.ContainsKey(context)) DoAddHandler(context, new LightSingleContextHandler(context)); } @@ -147,12 +147,12 @@ public void RegisterContext(RdContext context) else EnsureLightHandlerExists(context); } - + protected override void PreInit(Lifetime lifetime, IProtocol proto) { base.PreInit(lifetime, proto); - + lock (myOrderingLock) { myHandlerOrder.View(lifetime, (handlerLt, _, handler) => @@ -160,7 +160,7 @@ protected override void PreInit(Lifetime lifetime, IProtocol proto) PreBindHandler(handlerLt, handler.ContextBase.Key, handler); }); } - + proto.Wire.Advise(lifetime, this); } @@ -174,7 +174,7 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt BindAndSendHandler(handler); }); } - + } /// @@ -185,7 +185,7 @@ internal MessageContext ReadContextsIntoCookie(UnsafeReader reader) var numContextValues = reader.ReadShort(); if (numContextValues == 0) return default; - + var handlers = myCounterpartHandlers; if (Mode.IsAssertion) Assertion.Assert(numContextValues <= handlers.Count, "We know of {0} other side keys, received {1} instead", handlers.Count, numContextValues); @@ -195,11 +195,11 @@ internal MessageContext ReadContextsIntoCookie(UnsafeReader reader) return new MessageContext(values, handlers.GetStorageUnsafe()); } - + internal readonly ref struct MessageContextCookie { private readonly IDisposable[] myDisposables; - + public MessageContextCookie(IDisposable[] disposables) { myDisposables = disposables; @@ -209,7 +209,7 @@ public void Dispose() { if (myDisposables is { } disposables) { - foreach (var disposable in disposables) + foreach (var disposable in disposables) disposable.Dispose(); } } @@ -250,10 +250,9 @@ public void WriteContexts(UnsafeWriter writer) WriteEmptyContexts(writer); return; } - - // all handlers in myHandlersToWrite have been sent to the remote side +// all handlers in myHandlersToWrite have been sent to the remote side var count = myHandlersToWrite.Count; - writer.Write((short)count); + writer.WriteInt16((short) count); for (var i = 0; i < count; i++) myHandlersToWrite[i].WriteValue(mySerializationCtx, writer); } @@ -265,7 +264,7 @@ public void WriteContexts(UnsafeWriter writer) public void RegisterCurrentValuesInValueSets() { var count = myHandlerOrder.Count; - for (var i = 0; i < count; i++) + for (var i = 0; i < count; i++) myHandlerOrder[i].RegisterValueInValueSet(); } @@ -274,14 +273,14 @@ public void RegisterCurrentValuesInValueSets() /// public static void WriteEmptyContexts(UnsafeWriter writer) { - writer.Write((short) 0); - } + writer.WriteInt16((short) 0); + } private void BindAndSendHandler(ISingleContextHandler handler) { SendContextToRemote(handler.ContextBase); BindHandler(handler); - // add the handler to myHandlersToWrite only after sending the context to remote + // add the handler to myHandlersToWrite only after sending the context to remote myHandlersToWrite.Add(handler); } } diff --git a/rd-net/RdFramework/Impl/RdList.cs b/rd-net/RdFramework/Impl/RdList.cs index 86751a403..9e6060b99 100644 --- a/rd-net/RdFramework/Impl/RdList.cs +++ b/rd-net/RdFramework/Impl/RdList.cs @@ -26,8 +26,7 @@ public class RdList : RdReactiveBase, IViewableList where V : notnull { private readonly ViewableList myList = new(new SynchronizedList()/*to have thread safe print*/); - - + public RdList(CtxReadDelegate readValue, CtxWriteDelegate writeValue, long nextVersion = 1L) { myNextVersion = nextVersion; @@ -35,7 +34,7 @@ public RdList(CtxReadDelegate readValue, CtxWriteDelegate writeValue, long ReadValueDelegate = readValue; WriteValueDelegate = writeValue; - + //WPF integration this.AdviseAddRemove(Lifetime.Eternal, (kind, idx, v) => { @@ -46,9 +45,9 @@ public RdList(CtxReadDelegate readValue, CtxWriteDelegate writeValue, long #endif }); } - + //WPF integration -#if !NET35 +#if !NET35 public event NotifyCollectionChangedEventHandler CollectionChanged; #endif public override event PropertyChangedEventHandler PropertyChanged; @@ -80,7 +79,7 @@ public static RdList Read(SerializationCtx ctx, UnsafeReader reader,CtxReadDe public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdList value) { Assertion.Assert(!value.RdId.IsNil); - writer.Write(value.myNextVersion); + writer.WriteInt64(value.myNextVersion); writer.Write(value.RdId); } #endregion @@ -89,7 +88,7 @@ public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdList va #region Versions private const int versionedFlagShift = 2; //change when you change AddUpdateRemove - + private long myNextVersion; #endregion @@ -113,7 +112,7 @@ protected override void PreInit(Lifetime lifetime, IProtocol proto) if (!OptimizeNested) { var definitions = new SynchronizedList(null, myList.Count); - + for (var index = 0; index < Count; index++) { var item = this[index]; @@ -133,14 +132,14 @@ protected override void PreInit(Lifetime lifetime, IProtocol proto) else return; } - + proto.Wire.Advise(lifetime, this); } protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCtx ctx) { base.Init(lifetime, proto, ctx); - + if (!OptimizeNested) { Change.Advise(lifetime, it => @@ -153,7 +152,7 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt if (it.Kind != AddUpdateRemove.Add) definitions[it.Index]?.Terminate(); - + if (it.Kind == AddUpdateRemove.Remove) definitions.RemoveAt(it.Index); @@ -165,11 +164,11 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt } }); } - + using (UsingLocalChange()) { Advise(lifetime, it => - { + { if (!IsLocalChange) return; proto.Wire.Send(RdId, SendContext.Of(ctx, it, this), static(sendContext, stream) => @@ -178,21 +177,23 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt var evt = sendContext.Event; var me = sendContext.This; - stream.Write((me.myNextVersion++ << versionedFlagShift) | (long)evt.Kind); - - stream.Write(evt.Index); - if (evt.Kind != AddUpdateRemove.Remove) + stream.WriteInt64((me.myNextVersion++ << versionedFlagShift) | (long)evt.Kind); + + stream.WriteInt32(evt.Index); + if (evt.Kind != AddUpdateRemove.Remove) me.WriteValueDelegate(sContext, stream, evt.NewValue); - + SendTrace?.Log($"list `{me.Location}` ({me.RdId}) :: {evt.Kind} :: index={evt.Index} :: " + $"version = {me.myNextVersion - 1}" + $"{(evt.Kind != AddUpdateRemove.Remove ? " :: value = " + evt.NewValue.PrintToString() : "")}"); }); - + if (!OptimizeNested) it.NewValue.BindPolymorphic(); }); } + + } protected override string ShortName => "list"; @@ -206,6 +207,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf var index = stream.ReadInt(); + var kind = (AddUpdateRemove) opType; var value = default(V); var isPut = kind is AddUpdateRemove.Add or AddUpdateRemove.Update; @@ -214,7 +216,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf var lifetime = dispatchHelper.Lifetime; var definition = value != null ? TryPreBindValue(lifetime, value, index, true) : null; - + dispatchHelper.Dispatch(() => { ReceiveTrace?.Log($"list `{Location}` ({RdId}) :: {kind} :: index={index} :: version = {version}{(isPut ? " :: value = " + value.PrintToString() : "")}"); @@ -222,14 +224,15 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf if (version != myNextVersion) { definition?.Terminate(); - Assertion.Fail("Version conflict for {0} Expected version {1} received {2}. Are you modifying a list from two sides?", + Assertion.Fail("Version conflict for {0} Expected version {1} received {2}. Are you modifying a list from two sides?", Location, myNextVersion, version); } - - myNextVersion++; + + myNextVersion++; + switch (kind) { @@ -247,8 +250,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf } break; - } - +} case AddUpdateRemove.Update: { if (TryGetBindDefinitions(lifetime) is {} definitions) @@ -270,7 +272,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf } myList.RemoveAt(index); - break; + break; } default: @@ -278,8 +280,8 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf } }); } - - + + [CanBeNull] [ItemCanBeNull] private SynchronizedList TryGetBindDefinitions(Lifetime lifetime) @@ -287,20 +289,20 @@ private SynchronizedList TryGetBindDefinitions(Lifetime life var definitions = myBindDefinitions; return lifetime.IsAlive ? definitions : null; } - + #nullable restore private LifetimeDefinition? TryPreBindValue(Lifetime lifetime, V? value, int index, bool bindAlso) { if (OptimizeNested || !value.IsBindable()) return null; - + var definition = new LifetimeDefinition { Id = value }; try { value.PreBindPolymorphic(definition.Lifetime, this, "["+index+"]"); //todo name will be not unique when you add elements in the middle of the list if (bindAlso) value.BindPolymorphic(); - + lifetime.Definition.Attach(definition, true); return definition; } @@ -450,14 +452,14 @@ public override void Print(PrettyPrinter printer) using (printer.IndentCookie()) { foreach (var v in this) - { + { v.PrintEx(printer); printer.Println(); } } printer.Println("]"); } - + } } \ No newline at end of file diff --git a/rd-net/RdFramework/Impl/RdMap.cs b/rd-net/RdFramework/Impl/RdMap.cs index 30d81c960..b6a0e6efb 100644 --- a/rd-net/RdFramework/Impl/RdMap.cs +++ b/rd-net/RdFramework/Impl/RdMap.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; using JetBrains.Annotations; using JetBrains.Collections; using JetBrains.Collections.Synchronized; @@ -27,7 +26,7 @@ public RdMap(CtxReadDelegate readKey, CtxWriteDelegate writeKey, CtxReadDe ReadKeyDelegate = readKey; WriteKeyDelegate = writeKey; - + ReadValueDelegate = readValue; WriteValueDelegate = writeValue; } @@ -70,7 +69,7 @@ public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdMap private const int versionedFlagShift = 8; private const int Ack = (int)AddUpdateRemove.Remove + 1; - + public bool IsMaster = false; private long myNextVersion; private readonly Dictionary myPendingForAck = new Dictionary(); @@ -79,7 +78,7 @@ public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdMap #region Init - + public bool OptimizeNested { [PublicAPI] get; set; } private volatile SynchronizedDictionary? myBindDefinitions; @@ -87,10 +86,10 @@ protected override void PreInit(Lifetime lifetime, IProtocol proto) { base.PreInit(lifetime, proto); - if (!OptimizeNested) +if (!OptimizeNested) { - var definitions = new SynchronizedDictionary(myMap.Count); - + var definitions = new SynchronizedDictionary(myMap.Count); + foreach (var (key, value) in this) { if (value != null) @@ -161,21 +160,21 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt var evt = sendContext.Event; var me = sendContext.This; var versionedFlag = me.IsMaster ? 1 << versionedFlagShift : 0; - stream.Write(versionedFlag | (int)evt.Kind); + stream.WriteInt32(versionedFlag | (int)evt.Kind); var version = ++me.myNextVersion; if (me.IsMaster) { lock(me.myPendingForAck) me.myPendingForAck[evt.Key] = version; - - stream.Write(version); - } + stream.WriteInt64(version); + } me.WriteKeyDelegate(sContext, stream, evt.Key); if (evt.IsUpdate || evt.IsAdd) + { me.WriteValueDelegate(sContext, stream, evt.NewValue); - + } SendTrace?.Log($"{me} :: {evt.Kind} :: key = {evt.Key.PrintToString()}" + (me.IsMaster ? " :: version = " + version : "") @@ -244,15 +243,15 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf var isPut = kind is AddUpdateRemove.Add or AddUpdateRemove.Update; var value = isPut ? ReadValueDelegate(ctx, stream) : default; var definition = TryPreBindValue(lifetime, key, value, true); - - ReceiveTrace?.Log($"OnWireReceived:: {getMessage(msgVersioned, version, isPut, value)}"); - dispatchHelper.Dispatch(() => + ReceiveTrace?.Log($"OnWireReceived:: {getMessage(msgVersioned, version, isPut, value)}"); + +dispatchHelper.Dispatch(() => { if (msgVersioned || !IsMaster || !IsPendingForAck(key)) { ReceiveTrace?.Log($"Dispatched:: {getMessage(msgVersioned, version, isPut, value)}"); - + if (isPut) { if (TryGetBindDefinitions(lifetime) is { } definitions) @@ -264,14 +263,14 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf } myMap[key] = value!; - } +} else { if (TryGetBindDefinitions(lifetime) is { } definitions && definitions.TryGetValue(key, out var prevDefinition)) { prevDefinition?.Terminate(); definitions.Remove(key); - } +} myMap.Remove(key); } @@ -285,8 +284,8 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf { proto.Wire.Send(RdId, innerWriter => { - innerWriter.Write((1 << versionedFlagShift) | Ack); - innerWriter.Write(version); + innerWriter.WriteInt32((1 << versionedFlagShift) | Ack); + innerWriter.WriteInt64(version); WriteKeyDelegate.Invoke(ctx, innerWriter, key); SendTrace?.Log($"{this} :: ACK :: key = {key.PrintToString()} :: version = {version}"); @@ -491,7 +490,7 @@ public override void Print(PrettyPrinter printer) { base.Print(printer); if (!printer.PrintContent) return; - + printer.Print(" ["); if (Count > 0) printer.Println(); diff --git a/rd-net/RdFramework/Impl/RdProperty.cs b/rd-net/RdFramework/Impl/RdProperty.cs index 824a03d44..9de4ccb70 100644 --- a/rd-net/RdFramework/Impl/RdProperty.cs +++ b/rd-net/RdFramework/Impl/RdProperty.cs @@ -30,7 +30,7 @@ public RdProperty(CtxReadDelegate readValue, CtxWriteDelegate writeValue) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Value")); }); } - + [PublicAPI] public RdProperty(CtxReadDelegate readValue, CtxWriteDelegate writeValue, T defaultValue) : this(readValue, writeValue) { @@ -67,27 +67,22 @@ public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdProperty @@ -142,12 +137,12 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt if (!IsLocalChange) return; - + if (!OptimizeNested && shouldIdentify) { - // We need to terminate the current lifetime to unbind the existing value before assigning a new value, especially in cases where we are reassigning it. + // We need to terminate the current lifetime to unbind the existing value before assigning a new value, especially in cases where we are reassigning it. Memory.VolatileRead(ref myBindDefinition)?.Terminate(); - + v.IdentifyPolymorphic(proto.Identities, proto.Identities.Next(RdId)); var prevDefinition = Interlocked.Exchange(ref myBindDefinition, TryPreBindValue(lifetime, v, false)); @@ -161,11 +156,11 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt var sContext = sendContext.SzrCtx; var evt = sendContext.Event; var me = sendContext.This; - writer.Write(me.myMasterVersion); + writer.WriteInt32(me.myMasterVersion); me.WriteValueDelegate(sContext, writer, evt); SendTrace?.Log($"{me} :: ver = {me.myMasterVersion}, value = {me.Value.PrintToString()}"); }); - + if (!OptimizeNested && shouldIdentify) v.BindPolymorphic(); }); @@ -184,13 +179,13 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf var lifetime = dispatchHelper.Lifetime; var definition = TryPreBindValue(lifetime, value, true); - + ReceiveTrace?.Log($"OnWireReceived:: {GetMessage(version, value)}"); - + dispatchHelper.Dispatch(() => { var rejected = IsMaster && version < myMasterVersion; - + ReceiveTrace?.Log($"Dispatch:: {GetMessage(version, value)}{(rejected ? " REJECTED" : "")}"); if (rejected) @@ -198,7 +193,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf definition?.Terminate(); return; } - + myMasterVersion = version; using (UsingDebugInfo()) @@ -225,7 +220,7 @@ private string GetMessage(int version, T value) value.PreBindPolymorphic(definition.Lifetime, this, "$"); if (bindAlso) value.BindPolymorphic(); - + lifetime.Definition.Attach(definition, true); return definition; } @@ -263,7 +258,7 @@ public T Value public void Advise(Lifetime lifetime, Action handler) { if (IsBound) AssertThreading(); - + using (UsingDebugInfo()) myProperty.Advise(lifetime, handler); } @@ -296,10 +291,10 @@ public void Advise(Lifetime lifetime, Action handler) public override void Print(PrettyPrinter printer) { base.Print(printer); - + if (!printer.PrintContent) return; - + printer.Print("(ver=" + myMasterVersion + ") ["); if (Maybe.HasValue) { diff --git a/rd-net/RdFramework/Impl/RdSet.cs b/rd-net/RdFramework/Impl/RdSet.cs index f7e82d96b..bfa79f737 100644 --- a/rd-net/RdFramework/Impl/RdSet.cs +++ b/rd-net/RdFramework/Impl/RdSet.cs @@ -58,7 +58,7 @@ public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdSet val #region Init - + public bool OptimizeNested { [PublicAPI] get; set; } protected override void PreInit(Lifetime lifetime, IProtocol proto) @@ -71,7 +71,7 @@ protected override void PreInit(Lifetime lifetime, IProtocol proto) protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCtx ctx) { base.Init(lifetime, proto, ctx); - + using (UsingLocalChange()) { Advise(lifetime, it => @@ -80,7 +80,7 @@ protected override void Init(Lifetime lifetime, IProtocol proto, SerializationCt proto.Wire.Send(RdId, (stream) => { - stream.Write((int)it.Kind); + stream.WriteInt32((int)it.Kind); WriteValueDelegate(ctx, stream, it.Value); @@ -112,6 +112,7 @@ public override void OnWireReceived(IProtocol proto, SerializationCtx ctx, Unsaf default: throw new ArgumentOutOfRangeException(); } + }); } @@ -159,7 +160,7 @@ public bool Remove(T item) using (UsingLocalChange()) return mySet.Remove(item); } - + // ReSharper disable once AssignNullToNotNullAttribute #if NET35 public @@ -194,7 +195,7 @@ public void IntersectWith(IEnumerable other) using (UsingLocalChange()) mySet.IntersectWith(other); } - + public void SymmetricExceptWith(IEnumerable other) { using (UsingLocalChange()) @@ -203,17 +204,17 @@ public void SymmetricExceptWith(IEnumerable other) public void UnionWith(IEnumerable other) { - using (UsingLocalChange()) + using (UsingLocalChange()) mySet.UnionWith(other); } #endif public void Clear() { - using (UsingLocalChange()) + using (UsingLocalChange()) mySet.Clear(); } - + #endregion @@ -236,7 +237,7 @@ public void Clear() #endregion - + public void Advise(Lifetime lifetime, Action> handler) { diff --git a/rd-net/RdFramework/Impl/Serializers.cs b/rd-net/RdFramework/Impl/Serializers.cs index 12e9be045..f8f58f3e8 100644 --- a/rd-net/RdFramework/Impl/Serializers.cs +++ b/rd-net/RdFramework/Impl/Serializers.cs @@ -111,24 +111,24 @@ public Serializers(ITypesRegistrar? registrar) //writers - public static readonly CtxWriteDelegate WriteByte = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteShort = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteInt = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteLong = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteFloat = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteDouble = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteChar = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteBool = (ctx, writer, value) => writer.Write(value); + public static readonly CtxWriteDelegate WriteByte = (ctx, writer, value) => writer.WriteByte(value); + public static readonly CtxWriteDelegate WriteShort = (ctx, writer, value) => writer.WriteInt16(value); + public static readonly CtxWriteDelegate WriteInt = (ctx, writer, value) => writer.WriteInt32(value); + public static readonly CtxWriteDelegate WriteLong = (ctx, writer, value) => writer.WriteInt64(value); + public static readonly CtxWriteDelegate WriteFloat = (ctx, writer, value) => writer.WriteFloat(value); + public static readonly CtxWriteDelegate WriteDouble = (ctx, writer, value) => writer.WriteDouble(value); + public static readonly CtxWriteDelegate WriteChar = (ctx, writer, value) => writer.WriteChar(value); + public static readonly CtxWriteDelegate WriteBool = (ctx, writer, value) => writer.WriteBoolean(value); public static readonly CtxWriteDelegate WriteVoid = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteString = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteGuid = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteDateTime = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteTimeSpan = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteUri = (ctx, writer, value) => writer.Write(value); + public static readonly CtxWriteDelegate WriteString = (ctx, writer, value) => writer.WriteString(value); + public static readonly CtxWriteDelegate WriteGuid = (ctx, writer, value) => writer.WriteGuid(value); + public static readonly CtxWriteDelegate WriteDateTime = (ctx, writer, value) => writer.WriteDateTime(value); + public static readonly CtxWriteDelegate WriteTimeSpan = (ctx, writer, value) => writer.WriteTimeSpan(value); + public static readonly CtxWriteDelegate WriteUri = (ctx, writer, value) => writer.WriteUri(value); public static readonly CtxWriteDelegate WriteRdId = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteSecureString = (ctx, writer, value) => writer.Write(value.Contents); + public static readonly CtxWriteDelegate WriteSecureString = (ctx, writer, value) => writer.WriteString(value.Contents); public static readonly CtxWriteDelegate WriteByteArray = (ctx, writer, value) => writer.WriteArray(WriteByte, ctx, value); public static readonly CtxWriteDelegate WriteShortArray = (ctx, writer, value) => writer.WriteArray(WriteShort, ctx, value); @@ -140,10 +140,10 @@ public Serializers(ITypesRegistrar? registrar) public static readonly CtxWriteDelegate WriteBoolArray = (ctx, writer, value) => writer.WriteArray(WriteBool, ctx, value); - public static readonly CtxWriteDelegate WriteUByte = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteUShort = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteUInt = (ctx, writer, value) => writer.Write(value); - public static readonly CtxWriteDelegate WriteULong = (ctx, writer, value) => writer.Write(value); + public static readonly CtxWriteDelegate WriteUByte = (ctx, writer, value) => writer.WriteByte(value); + public static readonly CtxWriteDelegate WriteUShort = (ctx, writer, value) => writer.WriteUInt16(value); + public static readonly CtxWriteDelegate WriteUInt = (ctx, writer, value) => writer.WriteUInt32(value); + public static readonly CtxWriteDelegate WriteULong = (ctx, writer, value) => writer.WriteUInt64(value); public static readonly CtxWriteDelegate WriteUByteArray = (ctx, writer, value) => writer.WriteArray(WriteByte, ctx, value); public static readonly CtxWriteDelegate WriteUShortArray = (ctx, writer, value) => writer.WriteArray(WriteUShort, ctx, value); @@ -212,7 +212,7 @@ public static void WriteEnum(SerializationCtx ctx, UnsafeWriter writer, T val #endif Enum { - writer.Write(Cast32BitEnum.ToInt(value)); + writer.WriteInt32(Cast32BitEnum.ToInt(value)); } public void RegisterEnum() where T : @@ -326,7 +326,7 @@ bool TryGetTypeMapping(Type type1, out RdId rdId) typeId.Write(writer); var bookmark = new UnsafeWriter.Bookmark(writer); - writer.Write(0); + writer.WriteInt32(0); CtxWriteDelegate writerDelegate; lock (myLock) writerDelegate = myWriters[typeId]; diff --git a/rd-net/RdFramework/Impl/SerializersEx.cs b/rd-net/RdFramework/Impl/SerializersEx.cs index df266f368..2c2274eeb 100644 --- a/rd-net/RdFramework/Impl/SerializersEx.cs +++ b/rd-net/RdFramework/Impl/SerializersEx.cs @@ -25,11 +25,11 @@ public static void WriteList(this UnsafeWriter writer, CtxWriteDelegate it { if (value == null) { - writer.Write(-1); + writer.WriteInt32(-1); return; } - writer.Write(value.Count); + writer.WriteInt32(value.Count); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < value.Count; i++) { @@ -42,12 +42,12 @@ public static void WriteEnumerable(this UnsafeWriter writer, CtxWriteDelegate { if (value == null) { - writer.Write(-1); + writer.WriteInt32(-1); return; } var cookie = new UnsafeWriter.Bookmark(writer); - writer.Write(-1); // length + writer.WriteInt32(-1); // length int i = 0; foreach (var item in value) { @@ -75,11 +75,11 @@ public static void WriteArray(this UnsafeWriter writer, CtxWriteDelegate i { if (value == null) { - writer.Write(-1); + writer.WriteInt32(-1); return; } - writer.Write(value.Length); + writer.WriteInt32(value.Length); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < value.Length; i++) { @@ -123,9 +123,9 @@ public static RdSecureString ReadSecureString(this UnsafeReader reader) [MethodImpl(MethodImplAdvancedOptions.AggressiveInlining)] public static void Write(this UnsafeWriter writer, RdSecureString @string) { - writer.Write(@string.Contents); + writer.WriteString(@string.Contents); } - + public static RdId ReadRdId(this UnsafeReader reader) { return RdId.Read(reader); @@ -193,7 +193,7 @@ public static CtxWriteDelegate> List(this CtxWriteDelegate inner) { return (ctx, reader, value) => reader.WriteNullableStruct(inner, ctx, value); } - + public static CtxWriteDelegate Interned(this CtxWriteDelegate inner, string internKey) { return (ctx, reader, value) => ctx.WriteInterned(reader, value, internKey, inner); diff --git a/rd-net/RdFramework/Impl/SocketWire.cs b/rd-net/RdFramework/Impl/SocketWire.cs index e8ca19620..fbef69a70 100644 --- a/rd-net/RdFramework/Impl/SocketWire.cs +++ b/rd-net/RdFramework/Impl/SocketWire.cs @@ -311,8 +311,8 @@ private void SendAck(long seqN) { using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(ACK_MSG_LEN); - cookie.Writer.Write(seqN); + cookie.Writer.WriteInt32(ACK_MSG_LEN); + cookie.Writer.WriteInt64(seqN); cookie.CopyTo(myAckPkgHeader); } @@ -354,9 +354,9 @@ private void Ping() using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(PING_LEN); - cookie.Writer.Write(myCurrentTimeStamp); - cookie.Writer.Write(myCounterpartTimestamp); + cookie.Writer.WriteInt32(PING_LEN); + cookie.Writer.WriteInt32(myCurrentTimeStamp); + cookie.Writer.WriteInt32(myCounterpartTimestamp); cookie.CopyTo(myPingPkgHeader); } @@ -422,8 +422,8 @@ private void Send0(byte[] data, int offset, int len, ref long seqN) using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(len); - cookie.Writer.Write(seqN); + cookie.Writer.WriteInt32(len); + cookie.Writer.WriteInt64(seqN); cookie.CopyTo(mySendPkgHeader); } diff --git a/rd-net/RdFramework/RdId.cs b/rd-net/RdFramework/RdId.cs index ba9e9b21a..a96f8879f 100644 --- a/rd-net/RdFramework/RdId.cs +++ b/rd-net/RdFramework/RdId.cs @@ -101,10 +101,9 @@ public override string ToString() return $"{(ulong)myValue}"; } - [Pure] public void Write(UnsafeWriter writer) { - writer.Write(myValue); + writer.WriteInt64(myValue); } public static RdId Read(UnsafeReader reader) diff --git a/rd-net/RdFramework/Tasks/RdFault.cs b/rd-net/RdFramework/Tasks/RdFault.cs index cd2021d6f..df156e784 100644 --- a/rd-net/RdFramework/Tasks/RdFault.cs +++ b/rd-net/RdFramework/Tasks/RdFault.cs @@ -7,8 +7,8 @@ namespace JetBrains.Rd.Tasks { - [PublicAPI] - [Serializable] + [PublicAPI] + [Serializable] public class RdFault : Exception { public string ReasonTypeFqn { get; private set; } @@ -29,7 +29,7 @@ protected RdFault(SerializationInfo info, StreamingContext context) : base(info, ReasonText = info.GetString(nameof(ReasonText)); ReasonMessage = info.GetString(nameof(ReasonMessage)); } - + [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { @@ -40,28 +40,28 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont base.GetObjectData(info, context); } - public RdFault(string reasonTypeFqn, string reasonMessage, string reasonText, Exception? reason = null) + public RdFault(string reasonTypeFqn, string reasonMessage, string reasonText, Exception? reason = null) : base(reasonMessage + (reason == null ? ", reason: " + reasonText : ""), reason) { ReasonTypeFqn = reasonTypeFqn; ReasonMessage = reasonMessage; ReasonText = reasonText; } - + public static RdFault Read(SerializationCtx ctx, UnsafeReader reader) { var typeFqn = reader.ReadString().NotNull("typeFqn"); var message = reader.ReadString().NotNull("message"); var body = reader.ReadString().NotNull("body"); - + return new RdFault(typeFqn, message, body); } public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdFault value) { - writer.Write(value.ReasonTypeFqn); - writer.Write(value.ReasonMessage); - writer.Write(value.ReasonText); + writer.WriteString(value.ReasonTypeFqn); + writer.WriteString(value.ReasonMessage); + writer.WriteString(value.ReasonText); } } } \ No newline at end of file diff --git a/rd-net/RdFramework/Tasks/RdTaskResult.cs b/rd-net/RdFramework/Tasks/RdTaskResult.cs index b12aa1246..99a138d9f 100644 --- a/rd-net/RdFramework/Tasks/RdTaskResult.cs +++ b/rd-net/RdFramework/Tasks/RdTaskResult.cs @@ -57,7 +57,7 @@ public static RdTaskResult Read(CtxReadDelegate readDelegate, Serializatio public static void Write(CtxWriteDelegate writeDelegate, SerializationCtx ctx, UnsafeWriter writer, RdTaskResult value) { - writer.Write((int) value.Status); + writer.WriteInt32((int) value.Status); switch (value.Status) { diff --git a/rd-net/RdFramework/Text/Impl/Intrinsics/RdAssertion.cs b/rd-net/RdFramework/Text/Impl/Intrinsics/RdAssertion.cs index 9ca7dc5e2..09be36003 100644 --- a/rd-net/RdFramework/Text/Impl/Intrinsics/RdAssertion.cs +++ b/rd-net/RdFramework/Text/Impl/Intrinsics/RdAssertion.cs @@ -12,7 +12,7 @@ public class RdAssertion : IPrintable, IEquatable { public int MasterVersion {get; private set;} public int SlaveVersion {get; private set;} public string Text {get; private set;} - + //private fields //primary constructor public RdAssertion( @@ -22,28 +22,29 @@ string text ) { if (text == null) throw new ArgumentNullException("text"); - + MasterVersion = masterVersion; SlaveVersion = slaveVersion; Text = text; } //secondary constructor //statics - - public static CtxReadDelegate Read = (ctx, reader) => + + public static CtxReadDelegate Read = (ctx, reader) => { var masterVersion = reader.ReadInt(); var slaveVersion = reader.ReadInt(); var text = reader.ReadString().NotNull("text"); return new RdAssertion(masterVersion, slaveVersion, text); }; - - public static CtxWriteDelegate Write = (ctx, writer, value) => + + public static CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.MasterVersion); - writer.Write(value.SlaveVersion); - writer.Write(value.Text); + writer.WriteInt32(value.MasterVersion); + writer.WriteInt32(value.SlaveVersion); + writer.WriteString(value.Text); }; + //custom body //equals trait public override bool Equals(object? obj) diff --git a/rd-net/RdFramework/Text/Impl/Intrinsics/RdTextBufferChange.cs b/rd-net/RdFramework/Text/Impl/Intrinsics/RdTextBufferChange.cs index ae4948f8c..862fdfb3f 100644 --- a/rd-net/RdFramework/Text/Impl/Intrinsics/RdTextBufferChange.cs +++ b/rd-net/RdFramework/Text/Impl/Intrinsics/RdTextBufferChange.cs @@ -30,10 +30,10 @@ public RdTextBufferChange(TextBufferVersion version, RdChangeOrigin origin, RdTe public static CtxWriteDelegate WriteDelegate = (ctx, writer, value) => { var version = value.Version; - writer.Write(version.Master); - writer.Write(version.Slave); + writer.WriteInt32(version.Master); + writer.WriteInt32(version.Slave); var side = value.Origin; - writer.Write((int)side); + writer.WriteInt32((int)side); var change = value.Change; RdTextChangeSerializer.WriteDelegate(ctx, writer, change); }; diff --git a/rd-net/RdFramework/Text/Intrinsics/RdTextChangeSerializer.cs b/rd-net/RdFramework/Text/Intrinsics/RdTextChangeSerializer.cs index cc26730e1..efafbb6d9 100644 --- a/rd-net/RdFramework/Text/Intrinsics/RdTextChangeSerializer.cs +++ b/rd-net/RdFramework/Text/Intrinsics/RdTextChangeSerializer.cs @@ -16,11 +16,11 @@ public static class RdTextChangeSerializer public static CtxWriteDelegate WriteDelegate = (ctx, writer, value) => { - writer.Write((int)value.Kind); - writer.Write(value.StartOffset); - writer.Write(value.Old); - writer.Write(value.New); - writer.Write(value.FullTextLength); + writer.WriteInt32((int)value.Kind); + writer.WriteInt32(value.StartOffset); + writer.WriteString(value.Old); + writer.WriteString(value.New); + writer.WriteInt32(value.FullTextLength); }; } diff --git a/rd-net/RdFramework/Text/Intrinsics/TextBufferVersionSerializer.cs b/rd-net/RdFramework/Text/Intrinsics/TextBufferVersionSerializer.cs index 32d26ce22..7c2ec3dbd 100644 --- a/rd-net/RdFramework/Text/Intrinsics/TextBufferVersionSerializer.cs +++ b/rd-net/RdFramework/Text/Intrinsics/TextBufferVersionSerializer.cs @@ -11,8 +11,8 @@ public static class TextBufferVersionSerializer public static CtxWriteDelegate WriteDelegate = (ctx, writer, value) => { - writer.Write(value.Master); - writer.Write(value.Slave); + writer.WriteInt32(value.Master); + writer.WriteInt32(value.Slave); }; } } \ No newline at end of file diff --git a/rd-net/Test.Lifetimes/Serialization/NativeMemoryPoolTests.cs b/rd-net/Test.Lifetimes/Serialization/NativeMemoryPoolTests.cs index e5e19edf5..02f01f21d 100644 --- a/rd-net/Test.Lifetimes/Serialization/NativeMemoryPoolTests.cs +++ b/rd-net/Test.Lifetimes/Serialization/NativeMemoryPoolTests.cs @@ -25,7 +25,7 @@ public void Test1() { using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(false); + cookie.Writer.WriteBoolean(false); Assert.AreEqual(1, NativeMemoryPool.SampleUsed()); } Assert.AreEqual(1, NativeMemoryPool.SampleCount()); @@ -75,11 +75,11 @@ public void Perf() MaxDegreeOfParallelism = -1 }, x => { - for (int a = 0; a < 100_000_000; a++) + for (var a = 0; a < 100_000_000; a++) { using (var y = UnsafeWriter.NewThreadLocalWriter()) { - y.Writer.Write("hhhhdd"); + y.Writer.WriteString("hhhhdd"); } } }); @@ -106,7 +106,7 @@ public void M() { using (var y = UnsafeWriter.NewThreadLocalWriter()) { - y.Writer.Write("hhhhdd"); + y.Writer.WriteString("hhhhdd"); } } #endif diff --git a/rd-net/Test.Lifetimes/Serialization/UnsafeMarshallersTest.cs b/rd-net/Test.Lifetimes/Serialization/UnsafeMarshallersTest.cs index 2697f1f8e..10acf3f70 100644 --- a/rd-net/Test.Lifetimes/Serialization/UnsafeMarshallersTest.cs +++ b/rd-net/Test.Lifetimes/Serialization/UnsafeMarshallersTest.cs @@ -20,39 +20,37 @@ public void Test1() UnsafeReader reader; using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(false); - cookie.Writer.Write(true); - cookie.Writer.Write((byte) 0); - cookie.Writer.Write((byte) 10); - cookie.Writer.Write('y'); - cookie.Writer.Write('й'); - cookie.Writer.Write(1234.5678m); - cookie.Writer.Write(1234.5678d); - cookie.Writer.Write((short) 1000); - cookie.Writer.Write((int) 1001); - cookie.Writer.Write((long) -1002); - - - cookie.Writer.Write((string) null); - cookie.Writer.Write(""); - cookie.Writer.Write("abcd = yй"); - - cookie.Writer.Write((int[]) (null)); - cookie.Writer.Write(new int[0]); - cookie.Writer.Write(new[] {1, 2, 3}); - - cookie.Writer.Write(UnsafeWriter.StringDelegate, (string[]) null); - cookie.Writer.Write(UnsafeWriter.StringDelegate, new string[0]); - cookie.Writer.Write(UnsafeWriter.StringDelegate, new[] {"a", "b", "c"}); - - cookie.Writer.Write(UnsafeWriter.StringDelegate, (List) null); - cookie.Writer.Write(UnsafeWriter.StringDelegate, new List()); - cookie.Writer.Write(UnsafeWriter.StringDelegate, new List {"d", "e"}); + cookie.Writer.WriteBoolean(false); + cookie.Writer.WriteBoolean(true); + cookie.Writer.WriteByte(0); + cookie.Writer.WriteByte(10); + cookie.Writer.WriteChar('y'); + cookie.Writer.WriteChar('й'); + cookie.Writer.WriteDecimal(1234.5678m); + cookie.Writer.WriteDouble(1234.5678d); + cookie.Writer.WriteInt16(1000); + cookie.Writer.WriteInt32(1001); + cookie.Writer.WriteInt64(-1002); + + cookie.Writer.WriteString(null); + cookie.Writer.WriteString(""); + cookie.Writer.WriteString("abcd = yй"); + + cookie.Writer.WriteArray((int[]) (null)); + cookie.Writer.WriteArray(new int[0]); + cookie.Writer.WriteArray(new[] {1, 2, 3}); + + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, (string[])null); + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, new string[0]); + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, new[] { "a", "b", "c" }); + + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, (List)null); + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, new List()); + cookie.Writer.WriteCollection(UnsafeWriter.StringDelegate, new List { "d", "e" }); reader = UnsafeReader.CreateReader(cookie.Data, cookie.Count); } - Assert.False(reader.ReadBoolean()); Assert.True(reader.ReadBoolean()); Assert.AreEqual(0, reader.ReadByte()); @@ -199,18 +197,18 @@ public void Setup() throw new Exception($"Assertion mode cannot be initialized. (default value was used: {ModeInitializer.GetIsAssertionUndefined()})"); myCookie = UnsafeWriter.NewThreadLocalWriter(); - myCookie.Writer.Write(false); - myCookie.Writer.Write(true); - myCookie.Writer.Write((byte)0); - myCookie.Writer.Write((byte)10); - myCookie.Writer.Write('y'); - myCookie.Writer.Write('й'); - myCookie.Writer.Write(1234.5678m); - myCookie.Writer.Write(1234.5678d); - myCookie.Writer.Write((short)1000); - myCookie.Writer.Write((int)1001); - myCookie.Writer.Write((long)-1002); - myCookie.Writer.Write("(long)-1002"); + myCookie.Writer.WriteBoolean(false); + myCookie.Writer.WriteBoolean(true); + myCookie.Writer.WriteByte((byte)0); + myCookie.Writer.WriteByte((byte)10); + myCookie.Writer.WriteChar('y'); + myCookie.Writer.WriteChar('й'); + myCookie.Writer.WriteDecimal(1234.5678m); + myCookie.Writer.WriteDouble(1234.5678d); + myCookie.Writer.WriteInt16((short)1000); + myCookie.Writer.WriteInt32((int)1001); + myCookie.Writer.WriteInt64((long)-1002); + myCookie.Writer.WriteString("(long)-1002"); myReader = UnsafeReader.CreateReader(myCookie.Data, myCookie.Count); } diff --git a/rd-net/Test.Lifetimes/Threading/ByteBufferAsyncProcessorTest.cs b/rd-net/Test.Lifetimes/Threading/ByteBufferAsyncProcessorTest.cs index e702496e1..7e65e4524 100644 --- a/rd-net/Test.Lifetimes/Threading/ByteBufferAsyncProcessorTest.cs +++ b/rd-net/Test.Lifetimes/Threading/ByteBufferAsyncProcessorTest.cs @@ -19,11 +19,11 @@ public void TestOneProducer() var buffer = new ByteBufferAsyncProcessor("TestAsyncProcessor", 10, delegate(byte[] data, int offset, int len, ref long seqN) { Assert.Greater(len, 0); - + for (int i = 0; i < len - 1; i++) { Assert.AreEqual(data[offset + i+1], (byte)(data[offset + i]+1)); - + } processed += len; @@ -63,23 +63,23 @@ public void TestClean() { int x = 0; var buffer = new ByteBufferAsyncProcessor("TestAsyncProcessor", 1, delegate(byte[] data, int offset, int len, ref long seqN) { x += data[offset]; }); - + buffer.Put(new byte[]{1}); buffer.Put(new byte[]{2}); buffer.Put(new byte[]{3}); - + Assert.False(buffer.AllDataProcessed); //not started - + buffer.Clear(); Assert.True(buffer.AllDataProcessed); - + buffer.Start(); buffer.Put(new byte[]{1, 2, 3}); SpinWaitEx.SpinUntil(() => buffer.AllDataProcessed); Assert.AreEqual(6, x); } - + [Test] public void TestPause() { @@ -91,17 +91,17 @@ public void TestPause() Assert.False(buffer.Pause(reason1)); Assert.True(buffer.Pause(reason2)); Assert.False(buffer.Pause(reason2)); - + buffer.Start(); buffer.Put(new byte[]{1, 2, 3}); - Thread.Sleep(50); + Thread.Sleep(50); Assert.AreEqual(0, x); - + Assert.True(buffer.Resume(reason1)); - Assert.False(buffer.Resume(reason1)); - Thread.Sleep(50); + Assert.False(buffer.Resume(reason1)); + Thread.Sleep(50); Assert.AreEqual(0, x); - + Assert.True(buffer.Resume(reason2)); Assert.False(buffer.Resume(reason2)); Assert.False(buffer.Resume(reason2)); @@ -109,7 +109,7 @@ public void TestPause() Assert.AreEqual(6, x); } - + #if !NET35 [Test] public unsafe void StressTestWithAck() @@ -130,9 +130,9 @@ public unsafe void StressTestWithAck() l = UnsafeReader.CreateReader(b, 8).ReadLong(); Assert.True(l > prev); prev = l; - if (l % 1 == 0) + if (l % 1 == 0) Ack(l); - + } }); seqN = l; @@ -144,15 +144,16 @@ void Ack(long seqn) { buffer?.Acknowledge(seqn); } - + var start = Environment.TickCount; bool Until() => Environment.TickCount - start < 1000; long next = 0; var tasks = new List(); - - for (int i=0; i<4; i++) + + for (var index = 0; index < 4; index++) + { tasks.Add(Task.Run(() => { var rnd = new Random(); @@ -163,7 +164,7 @@ void Ack(long seqn) { using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(++next); + cookie.Writer.WriteInt64(++next); buffer.Put(cookie); } } @@ -173,7 +174,8 @@ void Ack(long seqn) buffer.Clear(); } })); - + } + Task.WaitAll(tasks.ToArray()); // Console.WriteLine(next); // Console.WriteLine(buffer.ChunkCount); @@ -186,7 +188,7 @@ public unsafe void TestReprocess() long prev = 0; ByteBufferAsyncProcessor buffer = null; List log = new List(); - + buffer = new ByteBufferAsyncProcessor("TestAsyncProcessor", 8, delegate(byte[] data, int offset, int len, ref long seqN) { @@ -199,7 +201,7 @@ public unsafe void TestReprocess() Assert.AreEqual(l, seqN); seqN = l; log.Add(l); - + Assert.True(l > prev); prev = l; } @@ -209,10 +211,10 @@ public unsafe void TestReprocess() Log.Root.Error(e); } }); - + buffer.ShrinkIntervalMs = 10; - buffer.Start(); - + buffer.Start(); + PutLong(buffer, 1); PutLong(buffer, 2); PutLong(buffer, 3); @@ -220,15 +222,15 @@ public unsafe void TestReprocess() SpinWaitEx.SpinUntil(() => buffer.AllDataProcessed); Assert.AreEqual(new List {1, 2, 3, 4}, log); - + buffer.Acknowledge(2); prev = 2; buffer.ReprocessUnacknowledged(); - + PutLong(buffer, 5); SpinWaitEx.SpinUntil(() => buffer.AllDataProcessed); Assert.AreEqual(new List {1, 2, 3, 4, 3, 4, 5}, log); - + buffer.Acknowledge(5); buffer.ReprocessUnacknowledged(); SpinWaitEx.SpinUntil(() => buffer.AllDataProcessed); @@ -239,9 +241,9 @@ private void PutLong(ByteBufferAsyncProcessor buffer, long l) { using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(l); + cookie.Writer.WriteInt64(l); buffer.Put(cookie); - } + } } } } \ No newline at end of file diff --git a/rd-net/Test.RdFramework/Interning/InterningTestModel.cs b/rd-net/Test.RdFramework/Interning/InterningTestModel.cs index d78e018af..94c9af34b 100644 --- a/rd-net/Test.RdFramework/Interning/InterningTestModel.cs +++ b/rd-net/Test.RdFramework/Interning/InterningTestModel.cs @@ -169,7 +169,7 @@ [NotNull] string searchLabel public static CtxWriteDelegate Write = (ctx, writer, value) => { value.RdId.Write(writer); - writer.Write(value.SearchLabel); + writer.WriteString(value.SearchLabel); RdSignal.Write(ctx, writer, value._Signaller); value.mySerializationContext = ctx.WithInternRootsHere(value, "Test"); }; @@ -230,7 +230,7 @@ [CanBeNull] InterningNestedTestModel inner public static CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.Value); + writer.WriteString(value.Value); WriteInterningNestedTestModelInternedNullable(ctx, writer, value.Inner); }; public static CtxWriteDelegate WriteInterningNestedTestModelInternedNullable = InterningNestedTestModel.Write.Interned("Test").NullableClass(); @@ -408,7 +408,7 @@ [NotNull] string searchLabel public static CtxWriteDelegate Write = (ctx, writer, value) => { value.RdId.Write(writer); - writer.Write(value.SearchLabel); + writer.WriteString(value.SearchLabel); RdMap.Write(ctx, writer, value._Issues); }; //custom body @@ -482,7 +482,7 @@ [NotNull] string searchLabel public static CtxWriteDelegate Write = (ctx, writer, value) => { value.RdId.Write(writer); - writer.Write(value.SearchLabel); + writer.WriteString(value.SearchLabel); RdMap.Write(ctx, writer, value._Issues); value.mySerializationContext = ctx.WithInternRootsHere(value, "Test"); }; diff --git a/rd-net/Test.RdFramework/Reflection/GenericBuiltInSerializersTest.cs b/rd-net/Test.RdFramework/Reflection/GenericBuiltInSerializersTest.cs index e11f97de2..1c5fc86e9 100644 --- a/rd-net/Test.RdFramework/Reflection/GenericBuiltInSerializersTest.cs +++ b/rd-net/Test.RdFramework/Reflection/GenericBuiltInSerializersTest.cs @@ -71,7 +71,7 @@ public TypeWithCtx(Guid mark, string alwaysLost) AlwaysLost = alwaysLost; } - public void Write(SerializationCtx ctx, UnsafeWriter writer) => writer.Write(Mark); + public void Write(SerializationCtx ctx, UnsafeWriter writer) => writer.WriteGuid(Mark); public static TypeWithCtx Read(SerializationCtx ctx, UnsafeReader reader) => new(reader.ReadGuid(), null); } @@ -86,7 +86,7 @@ public TypeWithoutCtx(Guid mark, string alwaysLost) AlwaysLost = alwaysLost; } - public void Write(UnsafeWriter writer) => writer.Write(Mark); + public void Write(UnsafeWriter writer) => writer.WriteGuid(Mark); public static TypeWithoutCtx Read(UnsafeReader reader) => new(reader.ReadGuid(), null); } @@ -103,7 +103,7 @@ public TypeWithCtx3(Guid mark, string alwaysLost) AlwaysLost = alwaysLost; } - public void Write(SerializationCtx ctx, UnsafeWriter writer) => writer.Write(Mark); + public void Write(SerializationCtx ctx, UnsafeWriter writer) => writer.WriteGuid(Mark); public static TypeWithCtx3 Read(SerializationCtx ctx, UnsafeReader reader) => new(reader.ReadGuid(), null); } @@ -118,7 +118,7 @@ public TypeWithoutCtx3(Guid mark, string alwaysLost) AlwaysLost = alwaysLost; } - public void Write(UnsafeWriter writer) => writer.Write(Mark); + public void Write(UnsafeWriter writer) => writer.WriteGuid(Mark); public static TypeWithoutCtx3 Read(UnsafeReader reader) => new(reader.ReadGuid(), null); } diff --git a/rd-net/Test.RdFramework/Reflection/PolymorphicScalarBuiltInSerializersTest.cs b/rd-net/Test.RdFramework/Reflection/PolymorphicScalarBuiltInSerializersTest.cs index 4f6e4e0a4..4c87795d2 100644 --- a/rd-net/Test.RdFramework/Reflection/PolymorphicScalarBuiltInSerializersTest.cs +++ b/rd-net/Test.RdFramework/Reflection/PolymorphicScalarBuiltInSerializersTest.cs @@ -91,7 +91,7 @@ public static Base Read(UnsafeReader reader) return new Base { Mark = Guid.NewGuid() }; } - public void Write(UnsafeWriter writer) => writer.Write("base"); + public void Write(UnsafeWriter writer) => writer.WriteString("base"); } [AssertBuiltInType(BuiltInSerializers.BuiltInType.Methods)] @@ -103,7 +103,7 @@ public class Type1 : Base return new Type1 { Mark = Guid.NewGuid() }; } - public new void Write(UnsafeWriter writer) => writer.Write("type1"); + public new void Write(UnsafeWriter writer) => writer.WriteString("type1"); } [AssertBuiltInType(BuiltInSerializers.BuiltInType.None)] diff --git a/rd-net/Test.RdFramework/Reflection/ProxyGeneratorAsyncCallsTest.cs b/rd-net/Test.RdFramework/Reflection/ProxyGeneratorAsyncCallsTest.cs index 3ffbf47dd..5a9471c19 100644 --- a/rd-net/Test.RdFramework/Reflection/ProxyGeneratorAsyncCallsTest.cs +++ b/rd-net/Test.RdFramework/Reflection/ProxyGeneratorAsyncCallsTest.cs @@ -115,7 +115,7 @@ public static FileSystemPath Read(SerializationCtx ctx, UnsafeReader reader) public static void Write(SerializationCtx ctx, UnsafeWriter writer, FileSystemPath value) { - writer.Write(value.myPath.ToLowerInvariant()); + writer.WriteString(value.myPath.ToLowerInvariant()); } } } diff --git a/rd-net/Test.RdFramework/Reflection/ScalarBuiltInSerializerTests.cs b/rd-net/Test.RdFramework/Reflection/ScalarBuiltInSerializerTests.cs index 42badc60e..67b96a361 100644 --- a/rd-net/Test.RdFramework/Reflection/ScalarBuiltInSerializerTests.cs +++ b/rd-net/Test.RdFramework/Reflection/ScalarBuiltInSerializerTests.cs @@ -113,8 +113,8 @@ void Reg(ReflectionSerializers cache) (ctx, reader) => new ScalarTests.ColorFields(0, reader.ReadByte(), reader.ReadByte()), (ctx, writer, value) => { - writer.Write((byte) value.Green); - writer.Write((byte) value.Blue); + writer.WriteByte((byte) value.Green); + writer.WriteByte((byte) value.Blue); }); } @@ -188,8 +188,8 @@ public NoRedBuiltIn1(int red, int green, int blue) public static CtxWriteDelegate Write = (ctx, writer, value) => { // writer.Write((byte) value.Red); - writer.Write((byte) value.Green); - writer.Write((byte) value.Blue); + writer.WriteByte((byte) value.Green); + writer.WriteByte((byte) value.Blue); }; } @@ -218,8 +218,8 @@ public static NoRedBuiltIn2 Read(SerializationCtx ctx, UnsafeReader reader) public static void Write(SerializationCtx ctx, UnsafeWriter writer, NoRedBuiltIn2 value) { // writer.Write((byte) value.Red); - writer.Write((byte) value.Green); - writer.Write((byte) value.Blue); + writer.WriteByte((byte) value.Green); + writer.WriteByte((byte) value.Blue); } } @@ -266,8 +266,8 @@ public static NoRedBuiltIn4 Read(UnsafeReader reader) public void Write(UnsafeWriter writer) { // writer.Write((byte) value.Red); - writer.Write((byte) Green); - writer.Write((byte) Blue); + writer.WriteByte((byte) Green); + writer.WriteByte((byte) Blue); } // Overloads with same name are allowed @@ -291,8 +291,8 @@ public static NoRedBuiltIn5 Read(UnsafeReader reader) public static void Write(UnsafeWriter writer, NoRedBuiltIn5 value) { // writer.Write((byte) value.Red); - writer.Write((byte)value.Green); - writer.Write((byte)value.Blue); + writer.WriteByte((byte)value.Green); + writer.WriteByte((byte)value.Blue); } public virtual bool Equals(NoRedBuiltIn5 other) @@ -325,8 +325,8 @@ public NoRedBuiltIn3 Read(SerializationCtx ctx, UnsafeReader reader) public void Write(SerializationCtx ctx, UnsafeWriter writer, NoRedBuiltIn3 value) { // writer.Write((byte) value.Red); - writer.Write((byte) value.Green); - writer.Write((byte) value.Blue); + writer.WriteByte((byte) value.Green); + writer.WriteByte((byte) value.Blue); } } } diff --git a/rd-net/Test.RdFramework/Reflection/data/Example/CustomReactive.cs b/rd-net/Test.RdFramework/Reflection/data/Example/CustomReactive.cs index be9cceae8..f0876f945 100644 --- a/rd-net/Test.RdFramework/Reflection/data/Example/CustomReactive.cs +++ b/rd-net/Test.RdFramework/Reflection/data/Example/CustomReactive.cs @@ -65,10 +65,10 @@ public static CustomReactive Read(SerializationCtx ctx, UnsafeReader rea public static void Write(SerializationCtx ctx, UnsafeWriter writer, CustomReactive value) { - writer.Write(true); + writer.WriteBoolean(true); ctx.Serializers.Write(ctx, writer, value.t1); ctx.Serializers.Write(ctx, writer, value.t2); - writer.Write(true); + writer.WriteBoolean(true); } #endregion diff --git a/rd-net/Test.RdFramework/Reflection/data/Generated/RefExt.cs b/rd-net/Test.RdFramework/Reflection/data/Generated/RefExt.cs index 592ef4811..2ba6f0e76 100644 --- a/rd-net/Test.RdFramework/Reflection/data/Generated/RefExt.cs +++ b/rd-net/Test.RdFramework/Reflection/data/Generated/RefExt.cs @@ -344,7 +344,7 @@ [NotNull] string @string public static new CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.String); + writer.WriteString(value.String); }; //constants @@ -425,7 +425,7 @@ [NotNull] string openString public static new CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.OpenString); + writer.WriteString(value.OpenString); }; //constants @@ -524,7 +524,7 @@ [NotNull] string field { value.RdId.Write(writer); RdProperty.Write(ctx, writer, value._String); - writer.Write(value.Field); + writer.WriteString(value.Field); }; //constants @@ -592,7 +592,7 @@ [NotNull] string field { value.RdId.Write(writer); RdProperty.Write(ctx, writer, value._String); - writer.Write(value.Field); + writer.WriteString(value.Field); }; //constants @@ -657,8 +657,8 @@ [NotNull] string openString public static new CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.OpenString); - writer.Write(value.OpenDerivedString); + writer.WriteString(value.OpenString); + writer.WriteString(value.OpenDerivedString); }; //constants @@ -739,8 +739,8 @@ [NotNull] string openString public static new CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.OpenDerivedString); - writer.Write(value.OpenString); + writer.WriteString(value.OpenDerivedString); + writer.WriteString(value.OpenString); }; //constants @@ -818,7 +818,7 @@ [NotNull] string openString public static new CtxWriteDelegate Write = (ctx, writer, value) => { - writer.Write(value.OpenString); + writer.WriteString(value.OpenString); }; //constants diff --git a/rd-net/Test.RdFramework/SerializersTest.cs b/rd-net/Test.RdFramework/SerializersTest.cs index 3757f478e..e5449d998 100644 --- a/rd-net/Test.RdFramework/SerializersTest.cs +++ b/rd-net/Test.RdFramework/SerializersTest.cs @@ -41,7 +41,7 @@ private class MyTestObject return new MyTestObject(data); }; - public static CtxWriteDelegate Write = (ctx, writer, value) => { writer.Write(value.Data); }; + public static CtxWriteDelegate Write = (ctx, writer, value) => { writer.WriteString(value.Data); }; } } } \ No newline at end of file diff --git a/rd-net/Test.RdFramework/UnsafeWriterTest.cs b/rd-net/Test.RdFramework/UnsafeWriterTest.cs index 800fefb8c..1230b7b32 100644 --- a/rd-net/Test.RdFramework/UnsafeWriterTest.cs +++ b/rd-net/Test.RdFramework/UnsafeWriterTest.cs @@ -47,20 +47,24 @@ public void TestFreeMemoryStress() bool run = true; var thread = new Thread(() => { - while (run) NativeMemoryPool.TryFreeMemory(); + while (run) + { + NativeMemoryPool.TryFreeMemory(); + } }); + thread.Start(); var sw = Stopwatch.StartNew(); while (sw.ElapsedMilliseconds < 500) { using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(1); + cookie.Writer.WriteInt32(1); } using (var cookie = UnsafeWriter.NewThreadLocalWriter()) { - cookie.Writer.Write(1); + cookie.Writer.WriteInt32(1); } }