Пример #1
0
        internal unsafe GamepadState(IGamepad gamepad, MemoryPool <byte> pool)
        {
            Name        = gamepad.Name;
            Index       = gamepad.Index;
            IsConnected = gamepad.IsConnected;
            var srcButtons     = gamepad.Buttons;
            var srcThumbsticks = gamepad.Thumbsticks;
            var srcTriggers    = gamepad.Triggers;

            _buttons     = pool.Rent((_buttonCount = srcButtons.Count) * sizeof(Button));
            _thumbsticks = pool.Rent((_thumbstickCount = srcThumbsticks.Count) * sizeof(Thumbstick));
            _triggers    = pool.Rent((_triggerCount = srcTriggers.Count) * sizeof(Trigger));
            var dstButtons     = GetButtons();
            var dstThumbsticks = GetThumbsticks();
            var dstTriggers    = GetTriggers();

            for (var i = 0; i < _buttonCount; i++)
            {
                dstButtons[i] = srcButtons[i];
            }

            for (var i = 0; i < _thumbstickCount; i++)
            {
                dstThumbsticks[i] = srcThumbsticks[i];
            }

            for (var i = 0; i < _triggerCount; i++)
            {
                dstTriggers[i] = srcTriggers[i];
            }
            Deadzone = gamepad.Deadzone;
        }
Пример #2
0
        internal unsafe JoystickState(IJoystick joystick, MemoryPool <byte> pool)
        {
            Name        = joystick.Name;
            Index       = joystick.Index;
            IsConnected = joystick.IsConnected;
            var srcAxes    = joystick.Axes;
            var srcButtons = joystick.Buttons;
            var srcHats    = joystick.Hats;

            _axes    = pool.Rent((_axisCount = srcAxes.Count) * sizeof(Axis));
            _buttons = pool.Rent((_buttonCount = srcButtons.Count) * sizeof(Button));
            _hats    = pool.Rent((_hatCount = srcHats.Count) * sizeof(Hat));
            var dstAxes    = GetAxes();
            var dstButtons = GetButtons();
            var dstHats    = GetHats();

            for (var i = 0; i < _axisCount; i++)
            {
                dstAxes[i] = srcAxes[i];
            }

            for (var i = 0; i < _buttonCount; i++)
            {
                dstButtons[i] = srcButtons[i];
            }

            for (var i = 0; i < _hatCount; i++)
            {
                dstHats[i] = srcHats[i];
            }

            Deadzone = joystick.Deadzone;
        }
Пример #3
0
    /// <summary>
    /// Compares the bytes in two streams for equality.
    /// </summary>
    /// <param name="left"><see cref="Stream"/> to compare.</param>
    /// <param name="right"><see cref="Stream"/> to compare.</param>
    /// <returns>TRUE if all bytes are equal in value, FALSE otherwise.</returns>
    public static async Task <bool> EqualsAsync(Stream left, Stream right)
    {
        const int           wantedBuffersize = InternalUtils.StreamBufferSize;
        MemoryPool <byte>   pool             = MemoryPool <byte> .Shared;
        IMemoryOwner <byte> leftOwner        = pool.Rent(wantedBuffersize);
        IMemoryOwner <byte> rightOwner       = pool.Rent(wantedBuffersize);
        Memory <byte>       leftBuffer       = leftOwner.Memory;
        Memory <byte>       rightBuffer      = rightOwner.Memory;

        try
        {
            int leftRead;
            while ((leftRead = await left.ReadAsync(leftBuffer)) > 0)
            {
                int rightRead = await right.ReadAsync(rightBuffer);

                if (leftRead != rightRead)
                {
                    return(false);
                }

                if (!Equals(leftBuffer.Span, rightBuffer.Span))
                {
                    return(false);
                }
            }

            return(true);
        }
        finally
        {
            leftOwner.Dispose();
            rightOwner.Dispose();
        }
    }
Пример #4
0
        private void Ensure(int i)
        {
            var length = _memory.Length;

            if (length == 0)
            {
                var chunk = _pool.Rent(i);
                _owned  = chunk;
                _memory = chunk.Memory;

                return;
            }

            var required = _next + i;

            if (required < length)
            {
                return;
            }

            while (required >= length)
            {
                length *= 2;
            }

            var newChunk = _pool.Rent(length);

            _memory.CopyTo(newChunk.Memory);

            _owned.Dispose();
            _owned  = newChunk;
            _memory = newChunk.Memory;
        }
Пример #5
0
        public async Task SendCommand(Command command)
        {
            var line = $"{command.Id} {command.Name} {command.Text}\n";

            if (line.Length > MaxCommandLength)
            {
                throw new InvalidOperationException("The command was too long.");
            }

            //log.Info("Sending '{command}'..", line);

            using (var buffer = Buffers.Rent(line.Length))
            {
                var byteLength = Encoding.ASCII.GetBytes(line, buffer.Memory.Span);
                if (byteLength != line.Length)
                {
                    throw new InvalidOperationException("Go search for a bug!");
                }

                var dataToSend = buffer.Memory.Slice(0, byteLength);
                while (!dataToSend.IsEmpty)
                {
                    var bytesSent = await client.SendAsync(dataToSend, SocketFlags.None);

                    if (bytesSent == 0)
                    {
                        throw new InvalidOperationException("0 bytes sent");
                    }
                    dataToSend = dataToSend.Slice(bytesSent);
                }
            }
        }
Пример #6
0
        public static async Task WriteFromBase64Urlsafe(
            this Stream stream, PipeReader base64Pipe,
            CancellationToken cancelToken = default)
        {
            if (stream is null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (base64Pipe is null)
            {
                throw new ArgumentNullException(nameof(base64Pipe));
            }

            try
            {
                using (var base64Buffer = bytesPool.Rent())
                {
                    Memory <byte> base64Memory    = base64Buffer.Memory;
                    int           base64Remaining = 0;
                    while (true)
                    {
                        ReadResult readResult = await base64Pipe
                                                .ReadAsync(cancelToken)
                                                .ConfigureAwait(false);

                        (base64Remaining, _) = await stream
                                               .WritePartialFromBase64Urlsafe(readResult.Buffer, base64Memory, base64Remaining, cancelToken)
                                               .ConfigureAwait(false);

                        base64Pipe.AdvanceTo(readResult.Buffer.End);

                        if (readResult.IsCompleted)
                        {
                            break;
                        }
                    }

                    base64Memory = base64Memory.Slice(0, base64Remaining);
                    await stream.WriteFinalFromBase64Urlsafe(base64Memory, cancelToken)
                    .ConfigureAwait(false);
                }

                await stream.FlushAsync(cancelToken).ConfigureAwait(false);

                base64Pipe.Complete();
            }
            catch (Exception e)
            {
                base64Pipe.Complete(e);
                throw;
            }
        }
Пример #7
0
        public static void MemoryPool_byte_WrapSlice_start_noop()
        {
            MemoryPool <byte> pool = MemoryPool <byte> .Shared;

            IMemoryOwner <byte> owner1 = pool.Rent(99);
            IMemoryOwner <byte> owner2 = owner1.Slice(10);

            Assert.False(ReferenceEquals(owner1, owner2));

            IMemoryOwner <byte> owner3 = pool.Rent(0);
            IMemoryOwner <byte> owner4 = owner3.Slice(0);

            Assert.True(ReferenceEquals(owner3, owner4));
        }
Пример #8
0
 private void AllocateReadTail()
 {
     if (_readHead == null)
     {
         Debug.Assert(_readTail == null);
         _readHead = CreateBufferSegment();
         _readHead.SetMemory(_pool.Rent(GetSegmentSize()));
         _readTail = _readHead;
     }
     else if (_readTail.WritableBytes < _minimumReadThreshold)
     {
         CreateNewTailSegment();
     }
 }
Пример #9
0
        internal unsafe MouseState(IMouse mouse, MemoryPool <byte> pool)
        {
            // Set properties
            Name        = mouse.Name;
            Index       = mouse.Index;
            IsConnected = mouse.IsConnected;

            // Initial rentals
            var srcButtons = mouse.SupportedButtons;                      // get the source's supported buttons

            _buttonCount = srcButtons.Count;                              // assign the button count
            _buttons     = pool.Rent(_buttonCount * sizeof(MouseButton)); // do a full rental of all supported buttons
            // we don't know how many buttons are pressed, do a full rental
            _pressedButtons     = pool.Rent(_buttonCount * sizeof(MouseButton));
            _pressedButtonCount = _buttonCount;         // set the pressed button count to span the entire initial rental
            var buttons        = GetSupportedButtons(); // get the span over the supported buttons
            var pressedButtons = GetPressedButtons();   // get the full span of the initial rental of the pressed buttons

            _pressedButtonCount = 0;                    // set the pressed button count to zero to actually count how many are pressed
            for (var i = 0; i < _buttonCount; i++)
            {
                buttons[i] = srcButtons[i];
                if (mouse.IsButtonPressed(buttons[i]))
                {
                    pressedButtons[_pressedButtonCount++] = buttons[i];
                }
            }

            // Trim the pressed button rental
            using var wip = _pressedButtons;                                        // get the original rental, and dispose of it when we're done
            var wipSpan = GetPressedButtons();                                      // get the trimmed span over the full initial rental

            _pressedButtons = pool.Rent(_pressedButtonCount * sizeof(MouseButton)); // create the trimmed rental
            pressedButtons  = GetPressedButtons();                                  // get the span over the trimmed rental
            wipSpan.CopyTo(pressedButtons);                                         // copy the trimmed span over the full rental to the trimmed rental

            // Scroll wheels
            var srcWheels = mouse.ScrollWheels;

            _scrollWheelCount = srcWheels.Count;
            _scrollWheels     = pool.Rent(_scrollWheelCount * sizeof(ScrollWheel));
            var dstWheels = GetScrollWheels();

            for (var i = 0; i < _scrollWheelCount; i++)
            {
                dstWheels[i] = srcWheels[i];
            }

            Position = mouse.Position;
        }
        public static uint ToUInt24(ReadOnlySpan <byte> buffer, bool littleEndian = false)
        {
            using (var owner = _memoryPool.Rent(4))
            {
                var memory = owner.Memory.Slice(0, 4);
                memory.Span.Clear();
                buffer.CopyTo(memory.Span.Slice(1));
                if (!littleEndian)
                {
                    memory.Span.Reverse();
                }

                return(BitConverter.ToUInt32(memory.Span));
            }
        }
Пример #11
0
        protected unsafe override void Deserialize(
            ReadOnlySpan <byte> span,
            MemoryPool <byte> memoryPool,
            out ReadOnlyMemory <byte> memory,
            out IMemoryOwner <byte> owner,
            out PublicKeyBytes publicKeyBytes)
        {
            if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_sign_ed25519_PUBLICKEYBYTES)
            {
                throw Error.InvalidOperation_InternalError();
            }

            Debug.Assert(span.Length == crypto_sign_ed25519_SEEDBYTES);

            owner  = memoryPool.Rent(crypto_sign_ed25519_SECRETKEYBYTES);
            memory = owner.Memory.Slice(0, crypto_sign_ed25519_SECRETKEYBYTES);

            fixed(PublicKeyBytes *pk = &publicKeyBytes)
            fixed(byte *sk    = owner.Memory.Span)
            fixed(byte *seed_ = span)
            {
                int error = crypto_sign_ed25519_seed_keypair(pk, sk, seed_);

                Debug.Assert(error == 0);
            }
        }
Пример #12
0
        private void AddToPushback(ReadOnlySpan <char> c)
        {
            if (!PushBackOwner.HasValue)
            {
                PushBackOwner.Value = MemoryPool.Rent(BufferSizeHint);
            }

            var pushBackOwnerValue = PushBackOwner.Value;

            if (PushBackLength + c.Length > pushBackOwnerValue.Memory.Length)
            {
                var oldSize = pushBackOwnerValue.Memory.Length;

                var newSize  = (PushBackLength + c.Length) * 2;   // double size, because we're sharing the buffer
                var newOwner = Utils.RentMustIncrease(MemoryPool, newSize, oldSize);
                pushBackOwnerValue.Memory.CopyTo(newOwner.Memory);

                pushBackOwnerValue.Dispose();
                PushBackOwner.Value = pushBackOwnerValue = newOwner;
            }

            if (PushBackLength + c.Length > pushBackOwnerValue.Memory.Length)
            {
                Throw.InvalidOperationException($"Could not allocate large enough buffer to read headers");
            }

            c.CopyTo(PushBack.Span.Slice(PushBackLength));
            PushBackLength += c.Length;
        }
Пример #13
0
        public static void MemoryPoolPinOffsetAtEnd()
        {
            MemoryPool <int>  pool  = MemoryPool <int> .Shared;
            OwnedMemory <int> block = pool.Rent(10);
            Span <int>        sp    = block.Span;

            Assert.Equal(block.Length, sp.Length);

            int byteOffset = 0;

            try
            {
                byteOffset = checked (block.Length * sizeof(int));
            }
            catch (OverflowException)
            {
                return; // The pool gave us a very large block - too big to compute the byteOffset needed to carry out this test. Skip.
            }

            using (MemoryHandle newMemoryHandle = block.Pin(byteOffset: byteOffset))
            {
                unsafe
                {
                    void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp));
                    Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer) - byteOffset);
                }
            }
        }
Пример #14
0
        internal BufferWithPushback(MemoryPool <char> memoryPool, int initialBufferSize)
        {
            MemoryPool   = memoryPool;
            BackingOwner = MemoryPool.Rent(initialBufferSize);

            UpdateBufferAndPushBack();
        }
        public static async IAsyncEnumerator <string> ReadTextMessages(this WebSocket socket,
                                                                       MemoryPool <byte> memoryPool, int minBufferSize,
                                                                       CancellationToken cancellationToken)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }
            if (memoryPool == null)
            {
                throw new ArgumentNullException(nameof(memoryPool));
            }

            while (true)
            {
                ValueWebSocketReceiveResult result;
                using var buffer = memoryPool.Rent(minBufferSize);
                using var ms     = new MemoryStream(buffer.Memory.Length);
                do
                {
                    result = await socket.ReceiveAsync(buffer.Memory, cancellationToken);

#pragma warning disable IDE0010 // Add missing cases (all are covered)
                    switch (result.MessageType)
#pragma warning restore IDE0010 // Add missing cases
                    {
                    case WebSocketMessageType.Close:
                        yield break;

                    case var type and not WebSocketMessageType.Text:
                        throw new NotSupportedException($"Invalid message type received: {type}");
                    }

                    ms.Write(buffer.Memory.Span[..result.Count]);
Пример #16
0
        private async ValueTask <LTrieNodeExternalLinkStruct> GetRemainingExternalLink(LTrieNodeStruct gn, byte value)
        {
            IMemoryOwner <byte>?owner = null;
            var restLength            = gn.GetRestLength();
            var secondLinkPointer     = gn.GetSecondExternalLinkOwnPointer();

            if (!Storage.TryDirectRead(secondLinkPointer, restLength, out var memory))
            {
                owner = MemoryPool.Rent(restLength);
                var outputMemory = owner.Memory.Slice(0, restLength);
                await Storage.Read(secondLinkPointer, outputMemory);

                memory = outputMemory;
            }
            for (int linkIndex = 0; linkIndex < gn.ExternalLinkSlotCount - 1; linkIndex++)
            {
                var linkOwnPointer = secondLinkPointer + linkIndex * Sizes.ExternalLinkLength;
                var l = new LTrieNodeExternalLinkStruct(linkOwnPointer, memory.Span.Slice(linkIndex * Sizes.ExternalLinkLength, Sizes.ExternalLinkLength));
                if (l.Pointer != 0 && l.Value == value)
                {
                    owner?.Dispose();
                    return(l);
                }
            }
            owner?.Dispose();
            return(default);
Пример #17
0
        internal override unsafe void CreateKey(
            ReadOnlySpan <byte> seed,
            MemoryPool <byte> memoryPool,
            out ReadOnlyMemory <byte> memory,
            out IMemoryOwner <byte> owner,
            out PublicKey?publicKey)
        {
            if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_sign_ed25519_PUBLICKEYBYTES)
            {
                throw Error.InvalidOperation_InternalError();
            }

            Debug.Assert(seed.Length == crypto_sign_ed25519_SEEDBYTES);

            publicKey = new PublicKey(this);
            owner     = memoryPool.Rent(crypto_sign_ed25519_SECRETKEYBYTES);
            memory    = owner.Memory.Slice(0, crypto_sign_ed25519_SECRETKEYBYTES);

            fixed(PublicKeyBytes *pk = publicKey)
            fixed(byte *sk    = owner.Memory.Span)
            fixed(byte *seed_ = seed)
            {
                int error = crypto_sign_ed25519_seed_keypair(pk, sk, seed_);

                Debug.Assert(error == 0);
            }
        }
Пример #18
0
 public async Task UsageWithLifeAsync(int size)
 {
     using (var array = _memPool.Rent(size))
     {
         await DoSomethingAsync(array.Memory);
     }
 }
Пример #19
0
        // To be used by HttpSys
        internal NativeRequestContext(SafeNativeOverlapped nativeOverlapped, MemoryPool <Byte> memoryPool, uint?bufferSize, ulong requestId)
        {
            _nativeOverlapped = nativeOverlapped;

            // TODO:
            // Apparently the HttpReceiveHttpRequest memory alignment requirements for non - ARM processors
            // are different than for ARM processors. We have seen 4 - byte - aligned buffers allocated on
            // virtual x64/x86 machines which were accepted by HttpReceiveHttpRequest without errors. In
            // these cases the buffer alignment may cause reading values at invalid offset. Setting buffer
            // alignment to 0 for now.
            //
            // _bufferAlignment = (int)(requestAddress.ToInt64() & 0x07);
            _bufferAlignment = 0;

            var newSize = (int)(bufferSize ?? DefaultBufferSize) + AlignmentPadding;

            if (newSize <= memoryPool.MaxBufferSize)
            {
                _backingBuffer = memoryPool.Rent(newSize);
            }
            else
            {
                // No size limit
                _backingBuffer = MemoryPool <byte> .Shared.Rent(newSize);
            }
            _backingBuffer.Memory.Span.Fill(0);// Zero the buffer
            _memoryHandle  = _backingBuffer.Memory.Pin();
            _nativeRequest = (HttpApiTypes.HTTP_REQUEST *)((long)_memoryHandle.Pointer + _bufferAlignment);

            RequestId = requestId;
        }
        public void MemoryPoolBlockReferenceTests()
        {
            var pool = new MemoryPool();

            BufferReferenceTests.TestOwnedBuffer(() => pool.Rent(1024), block => pool.Return((MemoryPoolBlock)block));
            pool.Dispose();
        }
Пример #21
0
        /// <summary>
        /// GetNext supporting memory pools
        /// </summary>
        /// <param name="pool">Memory pool</param>
        /// <param name="entry">Copy of entry, if found</param>
        /// <param name="entryLength">Actual length of entry</param>
        /// <param name="currentAddress">Logical address of entry</param>
        /// <param name="nextAddress">Logical address of next entry</param>
        /// <returns></returns>
        public unsafe bool GetNext(MemoryPool <byte> pool, out IMemoryOwner <byte> entry, out int entryLength, out long currentAddress, out long nextAddress)
        {
            if (disposed)
            {
                entry          = default;
                entryLength    = default;
                currentAddress = default;
                nextAddress    = default;
                return(false);
            }

            epoch.Resume();
            if (GetNextInternal(out long physicalAddress, out entryLength, out currentAddress, out nextAddress))
            {
                entry = pool.Rent(entryLength);

                fixed(byte *bp = &entry.Memory.Span.GetPinnableReference())
                Buffer.MemoryCopy((void *)(headerSize + physicalAddress), bp, entryLength, entryLength);

                epoch.Suspend();
                return(true);
            }

            entry       = default;
            entryLength = default;
            epoch.Suspend();
            return(false);
        }
Пример #22
0
        internal override unsafe void CreateKey(
            ReadOnlySpan <byte> seed,
            MemoryPool <byte> memoryPool,
            out ReadOnlyMemory <byte> memory,
            out IMemoryOwner <byte> owner,
            out PublicKey?publicKey)
        {
            if (Unsafe.SizeOf <PublicKeyBytes>() != crypto_scalarmult_curve25519_SCALARBYTES)
            {
                throw Error.InvalidOperation_InternalError();
            }

            Debug.Assert(seed.Length == crypto_scalarmult_curve25519_SCALARBYTES);

            publicKey = new PublicKey(this);
            owner     = memoryPool.Rent(crypto_scalarmult_curve25519_SCALARBYTES);
            memory    = owner.Memory.Slice(0, crypto_scalarmult_curve25519_SCALARBYTES);
            seed.CopyTo(owner.Memory.Span);

            fixed(PublicKeyBytes *q = publicKey)
            fixed(byte *n = owner.Memory.Span)
            {
                int error = crypto_scalarmult_curve25519_base(q, n);

                Debug.Assert(error == 0);
                Debug.Assert((((byte *)q)[crypto_scalarmult_curve25519_SCALARBYTES - 1] & 0x80) == 0);
            }
        }
Пример #23
0
        private bool AssembleMessage(RtmpMessageEntry messageEntry, RtmpChunk chunk, out RtmpMessage message)
        {
            message = null;
            var currentMessage = messageEntry.Message;

            if (currentMessage == null)
            {
                var payload = _memoryPool.Rent(chunk.Message.Length);
                currentMessage       = new RtmpMessage(chunk.Header, chunk.Message, payload);
                messageEntry.Message = currentMessage;
            }

            var memory = currentMessage.Payload.Slice(messageEntry.BytesRead, chunk.PayloadLength);
            var reader = new SequenceReader <byte>(chunk.Payload);

            reader.TryCopyTo(memory.Span);
            messageEntry.BytesRead += chunk.PayloadLength;
            // if message is complete .. return it.
            if (messageEntry.BytesRemaining == 0)
            {
                message = messageEntry.Message;
                _logger.LogInformation($"Parsed message :{message.Header}: Message: {message.Message}");
                messageEntry.BytesRead = 0;
                messageEntry.Message   = null;
                return(true);
            }
            return(false);
        }
Пример #24
0
        internal RequiredSet(MemoryPool <char> pool, int numMembers)
        {
            var neededChars = (numMembers / BITS_PER_CHAR);

            if ((numMembers % BITS_PER_CHAR > 0))
            {
                neededChars++;
            }

            var space = neededChars * 2;

            Owner = pool.Rent(space);

            Owner.Memory.Span.Slice(0, space).Clear();

            Required = Owner.Memory.Slice(0, neededChars);
            Set      = Owner.Memory.Slice(neededChars, neededChars);

            LongsInLength = neededChars / CHARS_PER_LONG;

            var leftOver = neededChars % CHARS_PER_LONG;

            if (leftOver >= CHARS_PER_INT)
            {
                HasIntInLength = true;
                leftOver      -= CHARS_PER_INT;
            }
            else
            {
                HasIntInLength = false;
            }

            HasCharInLength = leftOver != 0;
        }
Пример #25
0
        /// <summary>
        /// Convert payload to specified (disposable) memory owner
        /// </summary>
        public (IMemoryOwner <byte> memory, int length) ToMemoryOwner(MemoryPool <byte> pool)
        {
            var dst = pool.Rent(Length);

            AsReadOnlySpan().CopyTo(dst.Memory.Span);
            return(dst, Length);
        }
Пример #26
0
 public void UsageWithLife(int size)
 {
     using (var array = _memPool.Rent(size))
     {
         DoSomething(array.Memory);
     }
 }
Пример #27
0
        internal async ValueTask <LTrieValue> ReadValue(long pointer)
        {
            //1byte - protocol, FullKeyLen (2 bytes), FullValueLen (4 bytes),[Reserved Space For Update- 4 bytes],FullKey,FullValue
            //1 + 2 + 4 + 4 + 100 = 111
            int readLen = 256;
            var owner   = MemoryPool.Rent(readLen);
            var memory  = owner.Memory.Slice(0, readLen);
            await Storage.Read(pointer, memory);

            var    protocol   = memory.Span[0];
            var    headerSize = protocol == 0 ? 7 : 11;
            ushort keySize    = memory.ToReadOnly().Span.Slice(1).ReadUInt16BigEndian();

            if (keySize > (readLen - headerSize))
            {
                readLen = keySize + headerSize;
                owner.Dispose();
                owner  = MemoryPool.Rent(readLen);
                memory = owner.Memory.Slice(0, readLen);
                await Storage.Read(pointer, memory);
            }
            bool nullValue = (memory.Span[3] & 0x80) != 0;
            int  valueSize = (int)(nullValue ? 0U : memory.ToReadOnly().Span.Slice(3).ReadUInt32BigEndian());

            return(new LTrieValue(this, owner.Slice(headerSize, keySize), valueSize)
            {
                Protocol = protocol,
                Pointer = pointer,
                ValuePointer = pointer + headerSize + keySize,
                ValueMaxLength = protocol == 0 ? valueSize : (int)memory.Slice(7).ToReadOnly().Span.ReadUInt32BigEndian()
            });
        }
Пример #28
0
 internal Partition(DirectoryInfo location, int bufferSize, int recordsPerPartition, long partitionNumber, MemoryPool <LogEntryMetadata>?cachePool, int readersCount)
     : base(Path.Combine(location.FullName, partitionNumber.ToString(InvariantCulture)), bufferSize, readersCount, FileOptions.RandomAccess | FileOptions.WriteThrough | FileOptions.Asynchronous)
 {
     Capacity    = recordsPerPartition;
     FirstIndex  = partitionNumber * recordsPerPartition;
     lookupCache = cachePool?.Rent(recordsPerPartition);
 }
Пример #29
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)));
        }
Пример #30
0
        /// <summary>
        /// Copy to given SpanByteAndMemory (header and payload copied to actual span/memory)
        /// </summary>
        /// <param name="dst"></param>
        /// <param name="memoryPool"></param>
        public void CopyWithHeaderTo(ref SpanByteAndMemory dst, MemoryPool <byte> memoryPool)
        {
            if (dst.IsSpanByte)
            {
                if (dst.Length >= TotalSize)
                {
                    dst.Length = TotalSize;
                    var span = dst.SpanByte.AsSpan();

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

                    dst.SpanByte.ExtraMetadata = ExtraMetadata;

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

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

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

            dst.SpanByte.ExtraMetadata = ExtraMetadata;
            AsReadOnlySpan().CopyTo(dst.Memory.Memory.Span.Slice(sizeof(int) + MetadataSize));
        }