Ejemplo n.º 1
0
        public void CopyToTests()
        {
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            SpanByte span = new SpanByte(array);
            // First a copy to with the full span
            SpanByte toCopy = new byte[span.Length];

            span.CopyTo(toCopy);
            for (int i = 0; i < span.Length; i++)
            {
                Assert.Equal(toCopy[i], span[i], "SpanByte value should be the same as from the original array");
            }

            // Now create a larger span
            toCopy = new byte[span.Length + 1];
            span.CopyTo(toCopy);
            for (int i = 0; i < span.Length; i++)
            {
                Assert.Equal(toCopy[i], span[i], "SpanByte value should be the same as from the original array");
            }

            Assert.Equal(toCopy[span.Length], (byte)0);
        }
 /// <inheritdoc />
 public unsafe override void SingleReader(ref SpanByte key, ref SpanByte input, ref SpanByte value, ref SpanByteAndMemory dst)
 {
     if (wireFormat == WireFormat.Binary)
     {
         CopyWithHeaderTo(ref value, ref dst, memoryPool);
     }
 }
Ejemplo n.º 3
0
        public unsafe void SpanByteTest1()
        {
            Span <byte> output = stackalloc byte[20];
            SpanByte    input  = default;

            using var log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "/hlog1.log", deleteOnClose: true);
            using var fht = new FasterKV <SpanByte, SpanByte>
                                (128, new LogSettings { LogDevice = log, MemorySizeBits = 17, PageSizeBits = 12 });
            using var s = fht.NewSession(new SpanByteFunctions <Empty>());

            var key1    = MemoryMarshal.Cast <char, byte>("key1".AsSpan());
            var value1  = MemoryMarshal.Cast <char, byte>("value1".AsSpan());
            var output1 = SpanByteAndMemory.FromFixedSpan(output);

            s.Upsert(key1, value1);

            s.Read(key1, ref input, ref output1);

            Assert.IsTrue(output1.IsSpanByte);
            Assert.IsTrue(output1.SpanByte.AsReadOnlySpan().SequenceEqual(value1));

            var key2    = MemoryMarshal.Cast <char, byte>("key2".AsSpan());
            var value2  = MemoryMarshal.Cast <char, byte>("value2value2value2".AsSpan());
            var output2 = SpanByteAndMemory.FromFixedSpan(output);

            s.Upsert(key2, value2);

            s.Read(key2, ref input, ref output2);

            Assert.IsTrue(!output2.IsSpanByte);
            Assert.IsTrue(output2.Memory.Memory.Span.Slice(0, output2.Length).SequenceEqual(value2));
        }
Ejemplo n.º 4
0
        public void ConstructorsOfAllKindsTests()
        {
            // Empty span
            SpanByte span = new SpanByte();

            Assert.Equal(span.Length, 0, "Empty SpanByte should have length of 0");
            Assert.True(span.IsEmpty, "Empty SpanByte should be IsEmpty");

            // Empty span
            span = new SpanByte(null, 0, 0);
            Assert.Equal(span.Length, 0, "Empty SpanByte should have length of 0");
            Assert.True(span.IsEmpty, "Empty SpanByte should be IsEmpty");

            // Empty span
            span = SpanByte.Empty;
            Assert.Equal(span.Length, 0, "Empty SpanByte should have length of 0");
            Assert.True(span.IsEmpty, "Empty SpanByte should be IsEmpty");

            // Span from normal array
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            span = new SpanByte(array);
            Assert.Equal(span.Length, array.Length, $"SpanByte should have length of the array it takes: {array.Length}");
            Assert.False(span.IsEmpty, "SpanByte should NOT be IsEmpty");

            // Span from normal array with different start and length
            span = new SpanByte(array, 2, 8);
            Assert.Equal(span.Length, 8, $"SpanByte should have length of 8");
            Assert.False(span.IsEmpty, "SpanByte should NOT be IsEmpty");
        }
Ejemplo n.º 5
0
 /// <inheritdoc />
 public unsafe override void ConcurrentReader(ref SpanByte key, ref SpanByte input, ref SpanByte value, ref SpanByteAndMemory dst)
 {
     if (wireFormat != WireFormat.ASCII)
     {
         CopyWithHeaderTo(ref value, ref dst, memoryPool);
     }
 }
Ejemplo n.º 6
0
        private bool SendRequest(CommandSet cmd, byte dataHi, byte dataLo)
        {
            msg[3] = (byte)cmd;
            msg[5] = dataHi;
            msg[6] = dataLo;

            var    data = new SpanByte(msg, 1, msg.Length - 1);
            UInt16 chk  = CalcCheckSum(data, msg[2]);

            msg[7] = (byte)(chk >> 8);
            msg[8] = (byte)(chk & 0x00ff);

            outputDataWriter.WriteBytes(msg);
            outputDataWriter.Store();
            bufIdx = 0;

            Thread.Sleep(20);

            timeSent     = DateTime.UtcNow;
            status.Code  = StatusCode.STS_OK;
            waitResponse = true;

            do
            {
                Thread.Sleep(10);
            } while (!Check());

            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Copy to given SpanByteAndMemory (header length and payload copied to actual span/memory)
        /// </summary>
        /// <param name="src"></param>
        /// <param name="dst"></param>
        /// <param name="memoryPool"></param>
        private unsafe void CopyWithHeaderTo(ref SpanByte src, ref SpanByteAndMemory dst, MemoryPool <byte> memoryPool)
        {
            if (dst.IsSpanByte)
            {
                if (dst.Length >= src.TotalSize)
                {
                    dst.Length = src.TotalSize;
                    var span = dst.SpanByte.AsSpan();

                    fixed(byte *ptr = span)
                    * (int *)ptr = src.Length;

                    src.AsReadOnlySpan().CopyTo(span.Slice(sizeof(int)));
                    return;
                }
                dst.ConvertToHeap();
            }

            dst.Length = src.TotalSize;
            dst.Memory = memoryPool.Rent(src.TotalSize);
            dst.Length = src.TotalSize;

            fixed(byte *ptr = dst.Memory.Memory.Span)
            * (int *)ptr = src.Length;

            src.AsReadOnlySpan().CopyTo(dst.Memory.Memory.Span.Slice(sizeof(int)));
        }
        /// <inheritdoc/>
        public override void CopyUpdater(ref SpanByte key, ref SpanByte input, ref SpanByte oldValue, ref SpanByte newValue)
        {
            long curr = Utils.BytesToLong(oldValue.AsSpan());
            long next = curr + Utils.BytesToLong(input.AsSpan());

            Debug.Assert(Utils.NumDigits(next) == newValue.Length, "Unexpected destination length in CopyUpdater");
            Utils.LongToBytes(next, newValue.AsSpan());
        }
Ejemplo n.º 9
0
        public unsafe void MultiReadSpanByteKeyTest()
        {
            using var log = Devices.CreateLogDevice(TestContext.CurrentContext.TestDirectory + "/MultiReadSpanByteKeyTest.log", deleteOnClose: true);
            using var fht = new FasterKV <SpanByte, long>(
                      size: 1L << 20,
                          new LogSettings { LogDevice = log, MemorySizeBits = 15, PageSizeBits = 12 });
            using var session = fht.For(new MultiReadSpanByteKeyTestFunctions()).NewSession <MultiReadSpanByteKeyTestFunctions>();

            for (int i = 0; i < 3000; i++)
            {
                var key = MemoryMarshal.Cast <char, byte>($"{i}".AsSpan());

                fixed(byte *_ = key)
                session.Upsert(SpanByte.FromFixedSpan(key), i);
            }

            // Evict all records to disk
            fht.Log.FlushAndEvict(true);

            for (long key = 0; key < 50; key++)
            {
                // read each key multiple times
                for (int i = 0; i < 10; i++)
                {
                    Assert.AreEqual(key, ReadKey($"{key}"));
                }
            }

            long ReadKey(string keyString)
            {
                Status status;

                var key = MemoryMarshal.Cast <char, byte>(keyString.AsSpan());

                fixed(byte *_ = key)
                status = session.Read(key: SpanByte.FromFixedSpan(key), out var unused);

                // All keys need to be fetched from disk
                Assert.AreEqual(Status.PENDING, status);

                session.CompletePendingWithOutputs(out var completedOutputs, wait: true);

                var count = 0;
                var value = 0L;

                using (completedOutputs)
                {
                    while (completedOutputs.Next())
                    {
                        count++;
                        Assert.AreEqual(Status.OK, completedOutputs.Current.Status);
                        value = completedOutputs.Current.Output;
                    }
                }
                Assert.AreEqual(1, count);
                return(value);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Reads an System.Int32 from the beginning of a read-only span of bytes, as little endian.
        /// </summary>
        /// <param name="source">The read-only span to read.</param>
        /// <returns>The little endian value.</returns>
        public static int ReadInt32LittleEndian(SpanByte source)
        {
            if (source.Length < 4)
            {
                throw new ArgumentOutOfRangeException($"source is too small to contain an System.Int32.");
            }

            return((int)(source[3] << 24 | source[2] << 16 | source[1] << 8 | source[0]));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Reads an System.Int16 from the beginning of a read-only span of bytes, as little endian.
        /// </summary>
        /// <param name="source">The read-only span to read.</param>
        /// <returns>The little endian value.</returns>
        public static short ReadInt16LittleEndian(SpanByte source)
        {
            if (source.Length < 2)
            {
                throw new ArgumentOutOfRangeException($"source is too small to contain an System.Int16.");
            }

            return((short)(source[1] << 8 | source[0]));
        }
Ejemplo n.º 12
0
        /// <inheritdoc/>
        public override bool CopyUpdater(ref SpanByte key, ref SpanByte input, ref SpanByte oldValue, ref SpanByte newValue, ref SpanByteAndMemory output, ref RMWInfo rmwInfo)
        {
            long curr = Utils.BytesToLong(oldValue.AsSpan());
            long next = curr + Utils.BytesToLong(input.AsSpan());

            Debug.Assert(Utils.NumDigits(next) == newValue.Length, "Unexpected destination length in CopyUpdater");
            Utils.LongToBytes(next, newValue.AsSpan());
            return(true);
        }
Ejemplo n.º 13
0
        public void ToArrayTest()
        {
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            SpanByte span = new SpanByte(array);

            byte[] toArray = span.ToArray();
            Assert.Equal(array, toArray, "Original array and SpanByte.ToArray should be the same");
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Reads an System.Int64 from the beginning of a read-only span of bytes, as little endian.
        /// </summary>
        /// <param name="source">The read-only span to read.</param>
        /// <returns>The little endian value.</returns>
        public static long ReadInt64LittleEndian(SpanByte source)
        {
            if (source.Length < 8)
            {
                throw new ArgumentOutOfRangeException($"source is too small to contain an System.Int64.");
            }

            return((long)source[0] << 56 | (long)source[1] << 48 | (long)source[2] << 40 | (long)source[3] << 32 |
                   (long)source[4] << 24 | (long)source[5] << 16 | (long)source[6] << 8 | (long)source[7]);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Writes a System.UInt16 into a span of bytes, as little endian.
        /// </summary>
        /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
        /// <param name="value">The value to write into the span of bytes.</param>
        public static void WriteUInt16LittleEndian(SpanByte destination, ushort value)
        {
            if (destination.Length < 2)
            {
                throw new ArgumentOutOfRangeException($"destination is too small to contain an System.Int16.");
            }

            destination[1] = (byte)(value >> 8);
            destination[0] = (byte)value;
        }
Ejemplo n.º 16
0
        public void RaisingExceptionsOfAllKindsTests()
        {
            // Should raise an exception on creation
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(null, 1, 2); }, "ArgumentOutOfRangeException when array is null, start is 1 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 1, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 1 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 0, 2); }, "ArgumentOutOfRangeException when array is new byte[1], start is 0 and length is 2");
            Assert.Throws(typeof(ArgumentOutOfRangeException), () => { SpanByte span = new SpanByte(new byte[1], 2, 0); }, "ArgumentOutOfRangeException when array is new byte[1], start is 2 and length is 0");

            // Exception on index access
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var data      = span[span.Length];
            });
            Assert.Throws(typeof(IndexOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var data      = span[-1];
            });

            // Copy to with too small destination
            Assert.Throws(typeof(ArgumentException), () =>
            {
                SpanByte span        = new SpanByte(array);
                SpanByte destination = new byte[span.Length - 1];
                span.CopyTo(destination);
            });

            // Slicing arguments
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(span.Length + 1);
            });
            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(1, span.Length);
            });

            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(-1, span.Length);
            });

            Assert.Throws(typeof(ArgumentOutOfRangeException), () =>
            {
                SpanByte span = new SpanByte(array);
                var sliced    = span.Slice(1, -1);
            });
        }
Ejemplo n.º 17
0
        // Low level code
        private UInt16 CalcCheckSum(SpanByte data, int len)
        {
            UInt16 sum = 0;

            for (int i = 0; i < len; i++)
            {
                sum += data[i];
            }

            return((UInt16)(-sum));
        }
        /// <inheritdoc/>
        public override bool InPlaceUpdater(ref SpanByte key, ref SpanByte input, ref SpanByte value)
        {
            long curr = Utils.BytesToLong(value.AsSpan());
            long next = curr + Utils.BytesToLong(input.AsSpan());

            if (Utils.NumDigits(next) > value.Length)
            {
                return(false);
            }
            Utils.LongToBytes(next, value.AsSpan());
            return(true);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Writes a System.UInt32 into a span of bytes, as big endian.
        /// </summary>
        /// <param name="destination">The span of bytes where the value is to be written, as big endian.</param>
        /// <param name="value">The value to write into the span of bytes.</param>
        public static void WriteUInt32BigEndian(SpanByte destination, uint value)
        {
            if (destination.Length < 4)
            {
                throw new ArgumentOutOfRangeException($"destination is too small to contain an System.Int32.");
            }

            destination[0] = (byte)(value >> 24);
            destination[1] = (byte)(value >> 16);
            destination[2] = (byte)(value >> 8);
            destination[3] = (byte)value;
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Copies the contents of this System.Span into a destination System.Span.
        /// </summary>
        /// <param name="destination"> The destination System.Span object.</param>
        /// <exception cref="System.ArgumentException">
        /// destination is shorter than the source System.Span.
        /// </exception>
        public void CopyTo(SpanByte destination)
        {
            if (destination.Length < _length)
            {
                throw new ArgumentException($"Destination too small");
            }

            for (int i = 0; i < _length; i++)
            {
                destination[i] = _array[_start + i];
            }
        }
Ejemplo n.º 21
0
        public MpuValue(SpanByte arr)
        {
            AccelX = (short)((arr[0] << 8) | arr[1]);
            AccelY = (short)((arr[2] << 8) | arr[3]);
            AccelZ = (short)((arr[4] << 8) | arr[5]);

            //skip 6, 7

            GyroX = (short)((arr[8] << 8) | arr[9]);
            GyroY = (short)((arr[10] << 8) | arr[11]);
            GyroZ = (short)((arr[12] << 8) | arr[13]);
        }
Ejemplo n.º 22
0
        public void EmptySpanTests()
        {
            // Empty span
            SpanByte span = SpanByte.Empty;
            // Create a destination span larger
            SpanByte destination = new byte[1];

            span.CopyTo(destination);

            // Now also empty
            destination = SpanByte.Empty;
            span.CopyTo(destination);
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Copies the contents of this System.Span into a destination System.Span.
        /// </summary>
        /// <param name="destination"> The destination System.Span object.</param>
        /// <exception cref="System.ArgumentException">
        /// destination is shorter than the source <see cref="SpanByte"/>.
        /// </exception>
        public void CopyTo(SpanByte destination)
        {
            if (destination.Length < _length)
            {
#pragma warning disable S3928 // Parameter names used into ArgumentException constructors should match an existing one
                throw new ArgumentException();
#pragma warning restore S3928 // Parameter names used into ArgumentException constructors should match an existing one
            }

            for (int i = 0; i < _length; i++)
            {
                destination[i] = _array[_start + i];
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Writes a System.UInt64 into a span of bytes, as little endian.
        /// </summary>
        /// <param name="destination">The span of bytes where the value is to be written, as little endian.</param>
        /// <param name="value">The value to write into the span of bytes.</param>
        public static void WriteUInt64LittleEndian(SpanByte destination, ulong value)
        {
            if (destination.Length < 8)
            {
                throw new ArgumentOutOfRangeException($"destination is too small to contain an System.Int64.");
            }

            destination[7] = (byte)(value >> 56);
            destination[6] = (byte)(value >> 48);
            destination[5] = (byte)(value >> 40);
            destination[4] = (byte)(value >> 32);
            destination[3] = (byte)(value >> 24);
            destination[2] = (byte)(value >> 16);
            destination[1] = (byte)(value >> 8);
            destination[0] = (byte)value;
        }
Ejemplo n.º 25
0
            /// <summary>
            /// Puts a new record or replace the existing one in the store.
            /// </summary>
            /// <param name="key">The key of the record.</param>
            /// <param name="value">The record value.</param>
            public void Put(ulong key, ref Span <byte> value)
            {
                var status    = Status.OK;
                var context   = Context.WithUpsert(s => { status = s; });
                var fixedSpan = SpanByte.FromFixedSpan(value);

                status = _session?.Upsert(ref key, ref fixedSpan, context, 0) ?? Status.ERROR;
                if (status == Status.PENDING)
                {
                    _session?.CompletePending(true);
                }
                if (status == Status.ERROR)
                {
                    throw new InvalidOperationException("Error ocurred when inserting data.");
                }
            }
Ejemplo n.º 26
0
        // Read completion callback
        public override void ReadCompletionCallback(ref SpanByte key, ref SpanByte input, ref byte[] output, byte ctx, Status status, RecordMetadata recordMetadata)
        {
            if (!status.Found)
            {
                Console.WriteLine("Error!");
                return;
            }

            for (int i = 0; i < output.Length; i++)
            {
                if (output[i] != ctx)
                {
                    Console.WriteLine("Error!");
                    return;
                }
            }
        }
Ejemplo n.º 27
0
        public unsafe void SpanByteUnitTest1()
        {
            Span <byte> payload    = stackalloc byte[20];
            Span <byte> serialized = stackalloc byte[24];

            SpanByte sb = SpanByte.FromFixedSpan(payload);

            Assert.IsFalse(sb.Serialized);
            Assert.AreEqual(20, sb.Length);
            Assert.AreEqual(24, sb.TotalSize);
            Assert.AreEqual(20, sb.AsSpan().Length);
            Assert.AreEqual(20, sb.AsReadOnlySpan().Length);

            fixed(byte *ptr = serialized)
            sb.CopyTo(ptr);

            ref SpanByte ssb = ref SpanByte.ReinterpretWithoutLength(serialized);
Ejemplo n.º 28
0
        public void SliceTests()
        {
            // Span from normal array
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            SpanByte span = new SpanByte(array);
            // Slice 2 elements and check
            var sliced = span.Slice(0, 2);

            Assert.Equal(sliced.Length, 2, "Sliced span lenght must be 2");
            Assert.Equal(sliced[0], (byte)0x00, "Sliced first element must be value 0");
            Assert.Equal(sliced[1], (byte)0x01, "Sliced first element must be value 1");

            // Slide 4 elements starting at index 2 and check
            sliced = span.Slice(2, 4);
            Assert.Equal(sliced.Length, 4, "Sliced span lenght must be 4");
            Assert.Equal(sliced[0], (byte)0x02, "Sliced first element must be value 2");
            Assert.Equal(sliced[1], (byte)0x03, "Sliced first element must be value 3");
            Assert.Equal(sliced[2], (byte)0x04, "Sliced first element must be value 4");
            Assert.Equal(sliced[3], (byte)0x05, "Sliced first element must be value 5");

            // Slide starting 4 at element check
            sliced = span.Slice(4);
            Assert.Equal(sliced.Length, 12, "Sliced span lenght must be 12");
            for (int i = 0; i < sliced.Length; i++)
            {
                Assert.Equal(sliced[i], span[i + 4], "SpanByte value should be the same as from the original span");
            }

            // Slice of slice
            var secondSliced = sliced.Slice(2, 4);

            Assert.Equal(secondSliced.Length, 4, "Sliced span lenght must be 12");
            for (int i = 0; i < secondSliced.Length; i++)
            {
                Assert.Equal(secondSliced[i], sliced[i + 2], "SpanByte value should be the same as from the original span");
            }

            // Should be an empty one
            var empty = span.Slice(span.Length);

            Assert.Equal(empty.Length, 0, "slicing all the span should result in an empty span");
            Assert.True(empty.IsEmpty, "Empty span should be empty");
        }
Ejemplo n.º 29
0
        public void GetElementsTests()
        {
            // Span from normal array
            byte[] array = new byte[16] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
            };
            SpanByte span = new SpanByte(array);

            for (int i = 0; i < span.Length; i++)
            {
                Assert.Equal(span[i], array[i], "SpanByte value should be the same as from the original array");
            }

            // Partial span
            span = new SpanByte(array, 2, 8);
            for (int i = 0; i < span.Length; i++)
            {
                Assert.Equal(span[i], array[i + 2], "SpanByte value should be the same as from the original array");
            }
        }
Ejemplo n.º 30
0
 public void ConcurrentReader(ref SpanByte key, ref TValue input, ref TValue value, ref TValue dst)
 {
     dst = value;
 }