Esempio n. 1
0
        public void ShouldLimitReadOfMessages()
        {
            const int  msgLength           = 16;
            var        recordLength        = RingBufferDescriptor.HeaderLength + msgLength;
            var        alignedRecordLength = recordLength.AlignToMultipleOf(RingBufferDescriptor.RecordAlignment);
            const long head      = 0L;
            const int  headIndex = (int)head;

            _atomicLong.Read(Head).Returns(head);
            _atomicLong.VolatileRead(new IntPtr(headIndex))
            .Returns(RingBufferDescriptor.MakeHeader(recordLength, MessageTypeId));

            var            counter      = 0;
            MessageHandler h            = (id, chunk) => counter++;
            var            messagesRead = _ringBuffer.Read(h, 1);

            Assert.AreEqual(1, messagesRead);
            Assert.AreEqual(1, counter);

            Received.InOrder(() =>
            {
                _buffer.ZeroMemory(headIndex, alignedRecordLength);
                _atomicLong.VolatileWrite(Head, head + alignedRecordLength);
            });
        }
Esempio n. 2
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);
        }