diff --git a/benchmarks/NexusMods.EventSourcing.Benchmarks/Program.cs b/benchmarks/NexusMods.EventSourcing.Benchmarks/Program.cs index c59d9099..f52291fc 100644 --- a/benchmarks/NexusMods.EventSourcing.Benchmarks/Program.cs +++ b/benchmarks/NexusMods.EventSourcing.Benchmarks/Program.cs @@ -28,8 +28,8 @@ #if DEBUG var benchmarks = new EntityContextBenchmarks(); -benchmarks.EventCount = 10000; -benchmarks.EntityCount = 10; +benchmarks.EventCount = 100; +benchmarks.EntityCount = 1000; benchmarks.EventStoreType = typeof(RocksDBEventStore); benchmarks.Setup(); diff --git a/src/NexusMods.EventSourcing.Abstractions/IndexedMultiEntityAttributeDefinition.cs b/src/NexusMods.EventSourcing.Abstractions/IndexedMultiEntityAttributeDefinition.cs index ad5430e4..1cc1adec 100644 --- a/src/NexusMods.EventSourcing.Abstractions/IndexedMultiEntityAttributeDefinition.cs +++ b/src/NexusMods.EventSourcing.Abstractions/IndexedMultiEntityAttributeDefinition.cs @@ -107,10 +107,10 @@ public int ReadFrom(ref ReadOnlySpan input, ISerializationRegistry registr for (var idx = 0; idx < count; idx++) { - var written = registry.Deserialize(data, out TKey key); - data = data.Slice(written); - written = registry.Deserialize(data, out EntityId value); - data = data.Slice(written); + var amountRead = registry.Deserialize(data, out TKey key); + data = data.Slice(amountRead); + amountRead = registry.Deserialize(data, out EntityId value); + data = data.Slice(amountRead); _values.Add(key, value); _keys.Add(value, key); } diff --git a/src/NexusMods.EventSourcing/AEventStore.cs b/src/NexusMods.EventSourcing/AEventStore.cs index fb7cb156..9eb5e7e2 100644 --- a/src/NexusMods.EventSourcing/AEventStore.cs +++ b/src/NexusMods.EventSourcing/AEventStore.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using NexusMods.EventSourcing.Abstractions; using NexusMods.EventSourcing.Abstractions.Serialization; +using NexusMods.EventSourcing.Serialization; using Reloaded.Memory.Extensions; namespace NexusMods.EventSourcing; @@ -12,7 +13,7 @@ namespace NexusMods.EventSourcing; /// public abstract class AEventStore : IEventStore { - private readonly IVariableSizeSerializer _stringSerializer; + private readonly StringSerializer _stringSerializer; private readonly IFixedSizeSerializer _entityDefinitionSerializer; private readonly ISerializationRegistry _serializationRegistry; private readonly PooledMemoryBufferWriter _writer; @@ -23,7 +24,7 @@ public abstract class AEventStore : IEventStore /// public AEventStore(ISerializationRegistry serializationRegistry) { - _stringSerializer = (serializationRegistry.GetSerializer(typeof(string)) as IVariableSizeSerializer)!; + _stringSerializer = (StringSerializer)(serializationRegistry.GetSerializer(typeof(string)) as IVariableSizeSerializer)!; _entityDefinitionSerializer = (serializationRegistry.GetSerializer(typeof(EntityDefinition)) as IFixedSizeSerializer)!; _serializationRegistry = serializationRegistry; _writer = new PooledMemoryBufferWriter(); @@ -41,6 +42,9 @@ public AEventStore(ISerializationRegistry serializationRegistry) protected bool DeserializeSnapshot(out IAccumulator loadedDefinition, out (IAttribute Attribute, IAccumulator Accumulator)[] loadedAttributes, ReadOnlySpan snapshot) { + + var snapshotOld = snapshot; + var entityDefinition = _entityDefinitionSerializer.Deserialize(snapshot.SliceFast(0, 18)); var typeAccumulator = IEntity.TypeAttribute.CreateAccumulator(); @@ -72,7 +76,7 @@ protected bool DeserializeSnapshot(out IAccumulator loadedDefinition, snapshot = snapshot.SliceFast(read); if (!attributes.TryGetValue(attributeName, out var attribute)) - throw new Exception("Entity definition does not match the current structure registry."); + throw new Exception($"Entity definition does not match the current structure registry. No definition for {attributeName} found, valid options are {string.Join(",", attributes.Keys)}"); var accumulator = attribute.CreateAccumulator(); diff --git a/src/NexusMods.EventSourcing/PooledMemoryBufferWriter.cs b/src/NexusMods.EventSourcing/PooledMemoryBufferWriter.cs index 629c6b94..84df04dd 100644 --- a/src/NexusMods.EventSourcing/PooledMemoryBufferWriter.cs +++ b/src/NexusMods.EventSourcing/PooledMemoryBufferWriter.cs @@ -1,5 +1,6 @@ using System; using System.Buffers; +using System.Diagnostics; using System.Runtime.CompilerServices; using Reloaded.Memory.Extensions; @@ -14,6 +15,7 @@ public sealed class PooledMemoryBufferWriter : IBufferWriter private Memory _data; private int _idx; private int _size; + private readonly bool _isActive; /// /// Constructs a new pooled memory buffer writer, with the given initial capacity. diff --git a/src/NexusMods.EventSourcing/Serialization/ArraySerializer.cs b/src/NexusMods.EventSourcing/Serialization/ArraySerializer.cs index 84464576..24ad1327 100644 --- a/src/NexusMods.EventSourcing/Serialization/ArraySerializer.cs +++ b/src/NexusMods.EventSourcing/Serialization/ArraySerializer.cs @@ -99,11 +99,12 @@ public override int Deserialize(ReadOnlySpan from, out TItem[] value) from = from.SliceFast(lengthSize); for (var i = 0; i < length; i++) { - array[i] = itemSerializer.Deserialize(from.SliceFast(i * itemSize, itemSize)); + array[i] = itemSerializer.Deserialize(from.SliceFast(0, itemSize)); + from = from.SliceFast(itemSize); } value = array; - return lengthSize + itemSize * length; + return lengthSize + (itemSize * length); } } @@ -113,7 +114,7 @@ public override int Deserialize(ReadOnlySpan from, out TItem[] value) /// /// /// -public class VariableItemSizeSerializer(TItemSerializer itemSerializer) : IVariableSizeSerializer +public class VariableItemSizeSerializer(TItemSerializer itemSerializer) : AVariableSizeSerializer where TItemSerializer : IVariableSizeSerializer { /// @@ -135,11 +136,9 @@ public bool TryGetFixedSize(Type valueType, out int size) } /// - public void Serialize(TItem[] value, TWriter output) where TWriter : IBufferWriter + public override void Serialize(TItem[] value, TWriter output) { - var span = output.GetSpan(sizeof(ushort)); - BinaryPrimitives.WriteUInt16BigEndian(span, (ushort)value.Length); - output.Advance(sizeof(ushort)); + WriteLength(output, value.Length); foreach (var item in value) { @@ -148,12 +147,12 @@ public void Serialize(TItem[] value, TWriter output) where TWriter : IB } /// - public int Deserialize(ReadOnlySpan from, out TItem[] value) + public override int Deserialize(ReadOnlySpan from, out TItem[] value) { - var size = BinaryPrimitives.ReadUInt16BigEndian(from); + var lengthSize = ReadLength(from, out var size); var array = GC.AllocateUninitializedArray(size); - var offset = sizeof(ushort); + var offset = lengthSize; for (var i = 0; i < size; i++) { offset += itemSerializer.Deserialize(from.SliceFast(offset), out var item);