public void MessageHandler(int messageTypeId, ByteChunk chunk) { var hash = HashMessageId(messageTypeId); var actors = _messageMap[hash]; for (var i = 0; i < _count; i++) { // invoke only if the mask matches the actors, to limit the overhead of calling unneeded actors if ((GetActorMask(i) & actors) != 0) { _readers[i].MessageHandlerImpl(messageTypeId, chunk); } } }
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 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 void ShouldRejectWriteWhenInsufficientSpace() { const int length = 200; const long head = 0; var tail = head + (Capacity - (length - RingBufferDescriptor.RecordAlignment).AlignToMultipleOf( RingBufferDescriptor.RecordAlignment)); _atomicLong.VolatileRead(Head).Returns(head); _atomicLong.Read(Tail).Returns(tail); var chunk = new ByteChunk(null, length); Assert.False(_ringBuffer.Write(MessageTypeId, chunk)); _atomicInt.ReceivedWithAnyArgs(0); _atomicLong.DidNotReceiveWithAnyArgs().CompareExchange(IntPtr.Zero, 0, 0); _atomicLong.DidNotReceiveWithAnyArgs().VolatileWrite(IntPtr.Zero, 0); _buffer.DidNotReceiveWithAnyArgs().Write(0, new ByteChunk(null, 0)); }
public void ShouldInsertPaddingRecordPlusMessageOnBufferWrapWithHeadEqualToTail() { const int length = 200; var recordLength = length + RingBufferDescriptor.HeaderLength; var alignedRecordLength = recordLength.AlignToMultipleOf(RingBufferDescriptor.RecordAlignment); var tail = Capacity - RingBufferDescriptor.HeaderLength; var head = tail; _atomicLong.VolatileRead(Head).Returns(head); _atomicLong.Read(Tail).Returns(tail); var chunk = new ByteChunk(null, length); Assert.IsTrue(_ringBuffer.Write(MessageTypeId, chunk)); Received.InOrder(() => { // padding first _atomicLong.VolatileWrite(new IntPtr(tail), RingBufferDescriptor.MakeHeader(RingBufferDescriptor.HeaderLength, ManyToOneRingBuffer.PaddingMsgTypeId)); // message then _buffer.Write(RingBufferDescriptor.EncodedMsgOffset(0), chunk); _atomicLong.VolatileWrite(new IntPtr(0), RingBufferDescriptor.MakeHeader(recordLength, MessageTypeId)); _atomicLong.VolatileWrite(Tail, tail + alignedRecordLength + RingBufferDescriptor.HeaderLength); }); }
public bool Equals(ByteChunk other) { return(Pointer == other.Pointer && Length == other.Length); }
public void Write(ByteChunk chunk) { var slice = new ByteSlice(chunk); WriteImpl(ref slice); }
public int Read(ByteChunk chunk) { var slice = new ByteSlice(chunk); return(ReadImpl(ref slice)); }
// ReSharper disable once UnusedParameter.Local private void ValidateLength(ByteChunk chunk) { if (chunk.Length > MaximumMessageLength) { throw new ArgumentException(""); } }
public int Read(ByteChunk chunk) { var slice = new ByteSlice(chunk); return ReadImpl(ref slice); }
public void Write(int offset, ByteChunk chunk) { Native.MemcpyUnmanaged(RawBytes + offset, chunk.Pointer, chunk.Length); }
public void Write(int offset, ByteChunk chunk) { Native.MemcpyUnmanaged(RawBytes + offset, chunk.Pointer, chunk.Length); }
public void ShouldInsertPaddingRecordPlusMessageOnBufferWrap() { const int length = 200; var recordLength = length + RingBufferDescriptor.HeaderLength; var alignedRecordLength = recordLength.AlignToMultipleOf(RingBufferDescriptor.RecordAlignment); long tail = Capacity - RingBufferDescriptor.HeaderLength; var head = tail - RingBufferDescriptor.RecordAlignment*4; _atomicLong.VolatileRead(Head).Returns(head); _atomicLong.VolatileRead(Tail).Returns(tail); _atomicLong.CompareExchange(Tail, tail + alignedRecordLength + RingBufferDescriptor.RecordAlignment, tail) .Returns(tail); var chunk = new ByteChunk(null, length); Assert.True(_ringBuffer.Write(MessageTypeId, chunk)); Received.InOrder(() => { // padding first _atomicLong.VolatileWrite(new IntPtr(tail), RingBufferDescriptor.MakeHeader(RingBufferDescriptor.HeaderLength, ManyToOneRingBuffer.PaddingMsgTypeId)); // then write from the start _atomicLong.VolatileWrite(new IntPtr(0), RingBufferDescriptor.MakeHeader(-recordLength, MessageTypeId)); _buffer.Write(RingBufferDescriptor.EncodedMsgOffset(0), chunk); _buffer.GetAtomicInt(0); _atomicInt.VolatileWrite(new IntPtr(0), recordLength); }); }
public void Write(ByteChunk chunk) { var slice = new ByteSlice(chunk); WriteImpl(ref slice); }
public bool Equals(ByteChunk other) { return Pointer == other.Pointer && Length == other.Length; }
public static unsafe Envelope T(ByteChunk ch) { return *((Envelope*) (ch.Pointer + 2)); }
public void MessageHandlerImpl(int messageTypeId, ByteChunk chunk) { _reader(this, messageTypeId, chunk); }
public bool Write(int messageTypeId, ByteChunk chunk) { ValidateMessageTypeId(messageTypeId); ValidateLength(chunk); var recordLength = chunk.Length + HeaderLength; var requiredCapacity = recordLength.AlignToMultipleOf(RecordAlignment); var head = _headCache.Read(); var tail = _tail.Read(); var availableCapacity = Capacity - (int)(tail - head); if (requiredCapacity > availableCapacity) { head = _head.VolatileRead(); if (requiredCapacity > Capacity - (int)(tail - head)) { return false; } _headCache.Write(head); } var padding = 0; var recordIndex = (int)tail & _mask; var toBufferEndLength = Capacity - recordIndex; if (requiredCapacity > toBufferEndLength) { var headIndex = (int)head & _mask; if (requiredCapacity > headIndex) { head = _head.VolatileRead(); headIndex = (int)head & _mask; if (requiredCapacity > headIndex) { return false; } _headCache.Write(head); } padding = toBufferEndLength; } if (0 != padding) { var tailAtomic = _buffer.GetAtomicLong(recordIndex); tailAtomic.VolatileWrite(MakeHeader(padding, PaddingMsgTypeId)); recordIndex = 0; } var offset = EncodedMsgOffset(recordIndex); _buffer.Write(offset, chunk); var index = _buffer.GetAtomicLong(recordIndex); index.VolatileWrite(MakeHeader(recordLength, messageTypeId)); _tail.VolatileWrite(tail + requiredCapacity + padding); return true; }