示例#1
0
        public void ShouldWriteToEmptyBuffer()
        {
            const int length              = 8;
            var       recordLength        = length + RingBufferDescriptor.HeaderLength;
            var       alignedRecordLength = recordLength.AlignToMultipleOf(RingBufferDescriptor.RecordAlignment);

            const int headValue = 0;

            _atomicLong.VolatileRead(Arg.Is(Head)).Returns(headValue);
            const int tailValue = 0;

            _atomicLong.Read(Arg.Is(Tail)).Returns(tailValue);

            var block = stackalloc byte[100];

            var chunk = new ByteChunk(block, length);

            Assert.IsTrue(_ringBuffer.Write(MessageTypeId, chunk));

            Received.InOrder(() =>
            {
                _buffer.Write(RingBufferDescriptor.EncodedMsgOffset(tailValue), chunk);
                _buffer.GetAtomicLong(tailValue);
                _atomicLong.VolatileWrite(CurrentSlot, RingBufferDescriptor.MakeHeader(recordLength, MessageTypeId));
                _atomicLong.VolatileWrite(Tail, tailValue + alignedRecordLength);
            });
        }
示例#2
0
        public ManyToOneRingBuffer(IUnsafeBuffer buffer)
        {
            _buffer = buffer;

            EnsureCapacity(buffer);
            Capacity = buffer.Size - TrailerLength;

            _mask = Capacity - 1;
            MaximumMessageLength = Capacity / 8;
            _tail      = buffer.GetAtomicLong(Capacity + TailPositionOffset);
            _headCache = buffer.GetAtomicLong(Capacity + HeadCachePositionOffset);
            _head      = buffer.GetAtomicLong(Capacity + HeadPositionOffset);
        }
示例#3
0
        public ManyToOneRingBuffer(IUnsafeBuffer buffer)
        {
            _buffer = buffer;

            EnsureCapacity(buffer);
            Capacity = buffer.Size - TrailerLength;

            _mask = Capacity - 1;
            MaximumMessageLength = Capacity / 8;
            _tail = buffer.GetAtomicLong(Capacity + TailPositionOffset);
            _headCache = buffer.GetAtomicLong(Capacity + HeadCachePositionOffset);
            _head = buffer.GetAtomicLong(Capacity + HeadPositionOffset);
        }
示例#4
0
        public int Read(MessageHandler handler, int messageProcessingLimit)
        {
            var messagesRead = 0;

            var head = _head.Read();

            var bytesRead = 0;

            var headIndex             = (int)head & _mask;
            var contiguousBlockLength = Capacity - headIndex;

            try
            {
                while ((bytesRead < contiguousBlockLength) && (messagesRead < messageProcessingLimit))
                {
                    var recordIndex = headIndex + bytesRead;
                    var header      = _buffer.GetAtomicLong(recordIndex).VolatileRead();

                    var recordLength = RecordLength(header);
                    if (recordLength <= 0)
                    {
                        break;
                    }

                    bytesRead += recordLength.AlignToMultipleOf(RecordAlignment);

                    var messageTypeId = MessageTypeId(header);
                    if (PaddingMsgTypeId == messageTypeId)
                    {
                        continue;
                    }

                    ++messagesRead;
                    unsafe
                    {
                        handler(messageTypeId, new ByteChunk(_buffer.RawBytes + recordIndex + HeaderLength, recordLength - HeaderLength));
                    }
                }
            }
            finally
            {
                if (bytesRead != 0)
                {
                    _buffer.ZeroMemory(headIndex, bytesRead);
                    _head.VolatileWrite(head + bytesRead);
                }
            }

            return(messagesRead);
        }
示例#5
0
        public void SetUp()
        {
            _buffer = Substitute.For <IUnsafeBuffer>();
            _buffer.Size.Returns(TotalBufferLength);

            _buffer.GetAtomicLong(Arg.Any <long>()).Returns(ci => new AtomicLong((byte *)ci.Arg <long>()));
            _buffer.GetAtomicInt(Arg.Any <long>()).Returns(ci => new AtomicInt((byte *)ci.Arg <long>()));

            _atomicLong      = Substitute.For <Mocks.IAtomicLong>();
            Mocks.AtomicLong = _atomicLong;
            _atomicInt       = Substitute.For <Mocks.IAtomicInt>();
            Mocks.AtomicInt  = _atomicInt;

            _ringBuffer = new ManyToOneRingBuffer(_buffer);
        }
示例#6
0
        public bool Write(int messageTypeId, ByteChunk chunk)
        {
            ValidateMessageTypeId(messageTypeId);
            ValidateLength(chunk);

            var isSuccessful = false;

            var recordLength     = chunk.Length + HeaderLength;
            var requiredCapacity = recordLength.AlignToMultipleOf(RecordAlignment);
            var recordIndex      = ClaimCapacity(requiredCapacity);

            if (InsufficientCapacity != recordIndex)
            {
                var index = _buffer.GetAtomicLong(recordIndex);
                index.VolatileWrite(MakeHeader(-recordLength, messageTypeId));
                var offset = EncodedMsgOffset(recordIndex);
                _buffer.Write(offset, chunk);
                _buffer.GetAtomicInt(recordIndex).VolatileWrite(recordLength);

                isSuccessful = true;
            }

            return(isSuccessful);
        }
示例#7
0
        public void SetUp()
        {
            _buffer = Substitute.For<IUnsafeBuffer>();
            _buffer.Size.Returns(TotalBufferLength);

            _buffer.GetAtomicLong(Arg.Any<long>()).Returns(ci => new AtomicLong((byte*) ci.Arg<long>()));
            _buffer.GetAtomicInt(Arg.Any<long>()).Returns(ci => new AtomicInt((byte*) ci.Arg<long>()));

            _atomicLong = Substitute.For<Mocks.IAtomicLong>();
            Mocks.AtomicLong = _atomicLong;
            _atomicInt = Substitute.For<Mocks.IAtomicInt>();
            Mocks.AtomicInt = _atomicInt;

            _ringBuffer = new OneToOneRingBuffer(_buffer);
        }