зеркало из https://github.com/akkadotnet/Hyperion.git
added custom LinkedList serializer + tests + perf tests
This commit is contained in:
Родитель
f9487dd154
Коммит
4b7c78bc49
|
@ -142,15 +142,14 @@ namespace Hyperion.Tests.Performance.Deserialization
|
|||
InitStreamWith(new LinkedList<string>(new[] { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }));
|
||||
}
|
||||
|
||||
[NBenchFact(Skip = "FIXME: some problem with recursion, StackOverflowException")]
|
||||
[NBenchFact]
|
||||
[PerfBenchmark(
|
||||
Description = "Benchmark linked list deserialization",
|
||||
NumberOfIterations = StandardIterationCount,
|
||||
RunMode = RunMode.Throughput,
|
||||
RunTimeMilliseconds = StandardRunTime,
|
||||
TestMode = TestMode.Test,
|
||||
Skip = "FIXME: some problem with recursion, StackOverflowException")]
|
||||
[CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 80000)]
|
||||
TestMode = TestMode.Test)]
|
||||
[CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 150000)]
|
||||
public void Deserialize_LinkedList()
|
||||
{
|
||||
Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work
|
||||
|
|
|
@ -80,15 +80,14 @@ namespace Hyperion.Tests.Performance.Serialization
|
|||
SerializeAndCount(new List<string> { "asdad", "asdabs3", "sfsdf44g", "asdf4r", "sfsdf44g" });
|
||||
}
|
||||
|
||||
[NBenchFact(Skip = "FIXME: Stack overflow exception")]
|
||||
[NBenchFact]
|
||||
[PerfBenchmark(
|
||||
Description = "Benchmark linked list serialization",
|
||||
NumberOfIterations = StandardIterationCount,
|
||||
RunMode = RunMode.Throughput,
|
||||
RunTimeMilliseconds = StandardRunTime,
|
||||
TestMode = TestMode.Test,
|
||||
Skip = "FIXME: Stack overflow exception")]
|
||||
[CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 210000)]
|
||||
TestMode = TestMode.Test)]
|
||||
[CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 500000)]
|
||||
public void Serialize_LinkedList()
|
||||
{
|
||||
var list = new LinkedList<string>(new[] { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" });
|
||||
|
|
|
@ -167,6 +167,30 @@ namespace Hyperion.Tests
|
|||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanSerializeLinkedList()
|
||||
{
|
||||
var expected = new LinkedList<Something>(new[]
|
||||
{
|
||||
new Something
|
||||
{
|
||||
BoolProp = true,
|
||||
Else = new Else
|
||||
{
|
||||
Name = "Yoho"
|
||||
},
|
||||
Int32Prop = 999,
|
||||
StringProp = "Yesbox!"
|
||||
},
|
||||
new Something(), new Something(), null
|
||||
});
|
||||
|
||||
Serialize(expected);
|
||||
Reset();
|
||||
var actual = Deserialize<LinkedList<Something>>();
|
||||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact(Skip = "add support for multi dimentional arrays")]
|
||||
public void CanSerializeMultiDimentionalArray()
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
<Compile Include="SerializerFactories\FSharpMapSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\ImmutableCollectionsSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\ISerializableSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\LinkedListSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\MethodInfoSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\ToSurrogateSerializerFactory.cs" />
|
||||
<Compile Include="SerializerFactories\ValueSerializerFactory.cs" />
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#region copyright
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="LinkedListSerializerFactory.cs" company="Akka.NET Team">
|
||||
// Copyright (C) 2015-2016 AsynkronIT <https://github.com/AsynkronIT>
|
||||
// Copyright (C) 2016-2016 Akka.NET Team <https://github.com/akkadotnet>
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Hyperion.Extensions;
|
||||
using Hyperion.ValueSerializers;
|
||||
|
||||
namespace Hyperion.SerializerFactories
|
||||
{
|
||||
public sealed class LinkedListSerializerFactory : ValueSerializerFactory
|
||||
{
|
||||
private static readonly Type LinkedListType = typeof(LinkedList<>);
|
||||
|
||||
public override bool CanSerialize(Serializer serializer, Type type) => type.IsGenericType && type.GetGenericTypeDefinition() == LinkedListType;
|
||||
|
||||
public override bool CanDeserialize(Serializer serializer, Type type) => CanSerialize(serializer, type);
|
||||
|
||||
private static void WriteValues<T>(LinkedList<T> list, Stream stream, Type elementType, ValueSerializer elementSerializer, SerializerSession session)
|
||||
{
|
||||
Int32Serializer.WriteValueImpl(stream, list.Count, session);
|
||||
var preserveObjectReferences = session.Serializer.Options.PreserveObjectReferences;
|
||||
foreach (var value in list)
|
||||
{
|
||||
stream.WriteObject(value, elementType, elementSerializer, preserveObjectReferences, session);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReadValues<T>(int length, Stream stream, DeserializerSession session, LinkedList<T> list)
|
||||
{
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var value = (T)stream.ReadObject(session);
|
||||
list.AddLast(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static Type GetLinkedListType(Type type)
|
||||
{
|
||||
return type.GetTypeInfo().GetGenericArguments()[0];
|
||||
}
|
||||
|
||||
public override ValueSerializer BuildSerializer(Serializer serializer, Type type,
|
||||
ConcurrentDictionary<Type, ValueSerializer> typeMapping)
|
||||
{
|
||||
var elementType = GetLinkedListType(type);
|
||||
var elementSerializer = serializer.GetSerializerByType(elementType);
|
||||
var preserveObjectReferences = serializer.Options.PreserveObjectReferences;
|
||||
//TODO: code gen this part
|
||||
ObjectReader reader = (stream, session) =>
|
||||
{
|
||||
var length = stream.ReadInt32(session);
|
||||
var array = Activator.CreateInstance(type);
|
||||
if (preserveObjectReferences)
|
||||
{
|
||||
session.TrackDeserializedObject(array);
|
||||
}
|
||||
|
||||
ReadValues(length, stream, session, (dynamic)array);
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
ObjectWriter writer = (stream, arr, session) =>
|
||||
{
|
||||
if (preserveObjectReferences)
|
||||
{
|
||||
session.TrackSerializedObject(arr);
|
||||
}
|
||||
|
||||
WriteValues((dynamic)arr, stream, elementType, elementSerializer, session);
|
||||
|
||||
};
|
||||
|
||||
var ser = new ObjectSerializer(type);
|
||||
ser.Initialize(reader, writer);
|
||||
typeMapping.TryAdd(type, ser);
|
||||
|
||||
return ser;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ namespace Hyperion
|
|||
new DefaultDictionarySerializerFactory(),
|
||||
new DictionarySerializerFactory(),
|
||||
new ArraySerializerFactory(),
|
||||
new LinkedListSerializerFactory(),
|
||||
#if SERIALIZATION
|
||||
new ISerializableSerializerFactory(), //TODO: this will mess up the indexes in the serializer payload
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче