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); }); }
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); }
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); }
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); }
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); }
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); }