public unsafe int Read(ref DirectBuffer source, out VectorStorage <T> value) { var arraySize = source.Read <int>(0); if (arraySize > 0) { ThrowHelper.ThrowNotImplementedException("Non-shuffled arrays are not implemented yet"); // TODO } arraySize = -arraySize; // var position = 4; var payloadSize = arraySize * Unsafe.SizeOf <T>(); if (4 + payloadSize > source.Length || arraySize < 0) { value = default; return(-1); } if (arraySize > 0) { var byteLen = Unsafe.SizeOf <T>() * arraySize; var rm = BufferPool <T> .MemoryPool.RentMemory(arraySize) as ArrayMemory <T>; Debug.Assert(rm != null); // ReSharper disable once PossibleNullReferenceException fixed(byte *dPtr = &Unsafe.As <T, byte>(ref rm.Vec.DangerousGetRef(0))) { var srcDb = source.Slice(4); var destDb = new DirectBuffer(byteLen, dPtr); // srcDb.CopyTo(destDb); BinarySerializer.Unshuffle(in srcDb, in destDb, (byte)Unsafe.SizeOf <T>()); } if (TypeHelper <T> .IsIDelta) { var first = (IDelta <T>)rm.Array[0]; for (int i = 1; i < arraySize; i++) { rm.Array[i] = first.AddDelta(rm.Array[i]); } } var vs = VectorStorage.Create <T>(rm, 0, arraySize); value = new VectorStorage <T>(vs); } else { value = new VectorStorage <T>(VectorStorage.Empty); } return(4 + payloadSize); }
public void CouldWriteArrayToBuffer() { var ptr = Marshal.AllocHGlobal(1024); var buffer = new DirectBuffer(1024, ptr); var myArray = new int[2]; myArray[0] = 123; myArray[1] = 456; buffer.Write(0, myArray); var newArray = buffer.Read <int[]>(0); Assert.IsTrue(myArray.SequenceEqual(newArray)); }
public void CouldWritePOCOToBuffer() { var ptr = Marshal.AllocHGlobal(1024); var buffer = new DirectBuffer(1024, ptr); var myPoco = new MyPoco { String = "MyString", Long = 123 }; buffer.Write(0, myPoco); var newPoco = buffer.Read <MyPoco>(0); Assert.AreEqual(myPoco.String, newPoco.String); Assert.AreEqual(myPoco.Long, newPoco.Long); }
public void CouldWriteComplexTypeWithConverterToBuffer() { var ptr = Marshal.AllocHGlobal(1024); var buffer = new DirectBuffer(1024, ptr); var myStruct = new SetRemoveCommandBody <long, string>() { key = 123, value = "string value" }; buffer.Write(0, myStruct); var newStruct = buffer.Read <SetRemoveCommandBody <long, string> >(0); Assert.AreEqual(myStruct.key, newStruct.key); Assert.AreEqual(myStruct.value, newStruct.value); }
private Timestamped <T> Deserialize(DirectBuffer db) { Timestamp timestamp = default; Debug.Assert(!Inner.StreamLog.NoTimestamp); timestamp = db.Read <Timestamp>(0); db = db.Slice(Timestamp.Size); var len = BinarySerializer.Read <T>(Inner.ItemDth, db, out var value); if (len <= 0) { ThrowCannotDeserialize(); } return(new Timestamped <T>(timestamp, value)); void ThrowCannotDeserialize() { throw new InvalidDataException("Cannot deserialize data"); } }
public void CouldSerializeVectorStorage() { var rng = new Random(42); var count = 100_000; var arr = new SmallDecimal[count]; arr[0] = new SmallDecimal(1000 * 1.0, 4); for (int i = 1; i < count; i++) { arr[i] = arr[i - 1] + new SmallDecimal((double)arr[i - 1] * (0.02 + -0.04 * rng.NextDouble()), 4); } // arr = Enumerable.Range(0, count).Select(x => new SmallDecimal(1000 + (double)x + (double)Math.Round(0.1 * rng.NextDouble(), 5), precision:3)).ToArray(); var r = ArrayMemory <SmallDecimal> .Create(arr, 0, arr.Length, externallyOwned : true, pin : true); var vs = VectorStorage.Create(r, 0, r.Length); var vsT = new VectorStorage <SmallDecimal>(vs); var payload = count * Unsafe.SizeOf <double>() + 4; foreach (SerializationFormat format in ((SerializationFormat[])Enum.GetValues(typeof(SerializationFormat))).OrderBy(e => e.ToString())) { var len = BinarySerializer.SizeOf(in vsT, out var rm, format); var destination = BufferPool.Retain(len); var destinationDb = new DirectBuffer(destination); var len1 = BinarySerializer.Write(in vsT, ref destinationDb, in rm, format); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len1); var flags = destinationDb.Read <VersionAndFlags>(0); Assert.AreEqual(format, flags.SerializationFormat); var header = destinationDb.Read <DataTypeHeader>(0); Assert.AreEqual(TypeEnum.VectorStorage, header.TypeEnum); Assert.AreEqual(TypeEnum.SmallDecimal, header.ElementTypeEnum); Assert.AreEqual(Unsafe.SizeOf <SmallDecimal>(), header.TypeSize); var len2 = BinarySerializer.Read(ref destinationDb, out VectorStorage <SmallDecimal> value); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len2); Assert.AreEqual(vs.Length, value.Storage.Length); for (int i = 0; i < count; i++) { SmallDecimal left; SmallDecimal right; if ((left = vs.Vec.DangerousGetRef <SmallDecimal>(i)) != (right = value.Storage.DangerousGetRef <SmallDecimal>(i))) { Console.WriteLine("Not equals"); } } Assert.IsTrue(vs.Vec.Slice(0, vs.Length).AsSpan <SmallDecimal>().SequenceEqual(value.Storage.Vec.Slice(0, value.Storage.Length).AsSpan <SmallDecimal>())); Console.WriteLine($"{format} len: {len:N0} x{Math.Round((double)payload/len, 2)}"); destination.Dispose(); value.Storage.Dispose(); } vs.Dispose(); Assert.IsTrue(vs.IsDisposed); }
public void CouldSerializeVectorStorage() { var rng = new Random(42); var count = 100_000; var arr = new SmallDecimal[count]; var r = PrivateMemory <SmallDecimal> .Create(count); var vec = r.GetVec(); vec[0] = new SmallDecimal(1000 * 1.0, 4); for (int i = 1; i < count; i++) { vec[i] = vec[i - 1] + new SmallDecimal((double)vec[i - 1] * (0.02 + -0.04 * rng.NextDouble()), 4); } var vs = RetainedVec.Create(r, 0, r.Length); var vsT = new RetainedVec <SmallDecimal>(vs); var payload = count * Unsafe.SizeOf <double>() + 4; foreach (SerializationFormat format in ((SerializationFormat[])Enum.GetValues(typeof(SerializationFormat))).OrderBy(e => e.ToString())) { var len = BinarySerializer.SizeOf(in vsT, out var rm, format); var destination = BufferPool.Retain(len); var destinationDb = new DirectBuffer(destination); var len1 = BinarySerializer.Write(in vsT, destinationDb, rm, format); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len1); var flags = destinationDb.Read <VersionAndFlags>(0); Assert.AreEqual(format, flags.SerializationFormat); var header = destinationDb.Read <DataTypeHeader>(0); Assert.AreEqual(TypeEnum.Array, header.TEOFS.TypeEnum); Assert.AreEqual(TypeEnum.SmallDecimal, header.TEOFS1.TypeEnum); Assert.AreEqual(Unsafe.SizeOf <SmallDecimal>(), header.TEOFS1.Size); var len2 = BinarySerializer.Read(destinationDb, out RetainedVec <SmallDecimal> value); Assert.AreEqual(destination.Length, destinationDb.Length); Assert.AreEqual(len, len2); Assert.AreEqual(vs.Vec.Length, value.Storage.Vec.Length); for (int i = 0; i < count; i++) { SmallDecimal left; SmallDecimal right; if ((left = vs.Vec.DangerousGetUnaligned <SmallDecimal>(i)) != (right = value.Storage.Vec.DangerousGetUnaligned <SmallDecimal>(i))) { Console.WriteLine("Not equals"); } } Assert.IsTrue(vs.Vec.Slice(0, vs.Vec.Length).AsSpan <SmallDecimal>().SequenceEqual(value.Storage.Vec.Slice(0, value.Storage.Vec.Length).AsSpan <SmallDecimal>())); Console.WriteLine($"{format} len: {len:N0} x{Math.Round((double) payload / len, 2)}"); destination.Dispose(); value.Storage.Dispose(); } vs.Dispose(); }