/// <summary> /// Append an unfragmented message to the the term buffer. /// </summary> /// <param name="header"> for writing the default header. </param> /// <param name="srcBuffer"> containing the message. </param> /// <param name="srcOffset"> at which the message begins. </param> /// <param name="length"> of the message in the source buffer. </param> /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/> /// packed with the termId if a padding record was inserted at the end. </returns> public virtual long AppendUnfragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length) { int frameLength = length + DataHeaderFlyweight.HEADER_LENGTH; int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); long rawTail = GetAndAddRawTail(alignedLength); long termOffset = rawTail & 0xFFFFFFFFL; IAtomicBuffer termBuffer = _termBuffer; int termLength = termBuffer.Capacity; long resultingOffset = termOffset + alignedLength; if (resultingOffset > termLength) { resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, TermId(rawTail)); } else { int offset = (int)termOffset; header.Write(termBuffer, offset, frameLength, TermId(rawTail)); termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer, srcOffset, length); FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength); } return(resultingOffset); }
/// <summary> /// Claim length of a the term buffer for writing in the message with zero copy semantics. /// </summary> /// <param name="header"> for writing the default header. </param> /// <param name="length"> of the message to be written. </param> /// <param name="bufferClaim"> to be updated with the claimed region. </param> /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/> /// packed with the termId if a padding record was inserted at the end. </returns> public long Claim(HeaderWriter header, int length, BufferClaim bufferClaim) { int frameLength = length + DataHeaderFlyweight.HEADER_LENGTH; int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); long rawTail = GetAndAddRawTail(alignedLength); long termOffset = rawTail & 0xFFFFFFFFL; IAtomicBuffer termBuffer = _termBuffer; int termLength = termBuffer.Capacity; long resultingOffset = termOffset + alignedLength; if (resultingOffset > termLength) { resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, TermId(rawTail)); } else { int offset = (int)termOffset; header.Write(termBuffer, offset, frameLength, TermId(rawTail)); bufferClaim.Wrap(termBuffer, offset, frameLength); } return(resultingOffset); }
public void ShouldCompareAndSetLongToNativeBuffer(IAtomicBuffer buffer) { Marshal.WriteInt64(buffer.BufferPointer, Index, LongValue); Assert.True(buffer.CompareAndSetLong(Index, LongValue, LongValue + 1)); Assert.That(Marshal.ReadInt64(buffer.BufferPointer, Index), Is.EqualTo(LongValue + 1)); }
/// <summary> /// Scan a term buffer for a block of messages from and offset up to a limit. /// </summary> /// <param name="termBuffer"> to scan for messages. </param> /// <param name="offset"> at which the scan should begin. </param> /// <param name="limit"> at which the scan should stop. </param> /// <returns> the offset at which the scan terminated. </returns> public static int Scan(IAtomicBuffer termBuffer, int offset, int limit) { do { int frameLength = FrameDescriptor.FrameLengthVolatile(termBuffer, offset); if (frameLength <= 0) { break; } int alignedFrameLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); offset += alignedFrameLength; if (offset >= limit) { if (offset > limit) { offset -= alignedFrameLength; } break; } } while (true); return(offset); }
/// <summary> /// Read all the errors in a log since a given timestamp. /// </summary> /// <param name="buffer"> containing the <seealso cref="DistinctErrorLog"/>. </param> /// <param name="consumer"> to be called for each exception encountered. </param> /// <param name="sinceTimestamp"> for filtering errors that have been recorded since this time. </param> /// <returns> the number of entries that has been read. </returns> public static int Read(IAtomicBuffer buffer, ErrorConsumer consumer, long sinceTimestamp) { int entries = 0; int offset = 0; int capacity = buffer.Capacity; while (offset < capacity) { int length = buffer.GetIntVolatile(offset + DistinctErrorLog.LengthOffset); if (0 == length) { break; } long lastObservationTimestamp = buffer.GetLongVolatile(offset + DistinctErrorLog.LastObservationTimestampOffset); if (lastObservationTimestamp >= sinceTimestamp) { ++entries; consumer( buffer.GetInt(offset + DistinctErrorLog.ObservationCountOffset), buffer.GetLong(offset + DistinctErrorLog.FirstObservationTimestampOffset), lastObservationTimestamp, buffer.GetStringUtf8(offset + DistinctErrorLog.EncodedErrorOffset, length - DistinctErrorLog.EncodedErrorOffset)); } offset += BitUtil.Align(length, DistinctErrorLog.RecordAlignment); } return(entries); }
/// <summary> /// Read all the errors in a log since a given timestamp. /// </summary> /// <param name="buffer"> containing the <seealso cref="DistinctErrorLog"/>. </param> /// <param name="consumer"> to be called for each exception encountered. </param> /// <param name="sinceTimestamp"> for filtering errors that have been recorded since this time. </param> /// <returns> the number of entries that has been read. </returns> public static int Read(IAtomicBuffer buffer, ErrorConsumer consumer, long sinceTimestamp) { int entries = 0; int offset = 0; int capacity = buffer.Capacity; while (offset < capacity) { int length = buffer.GetIntVolatile(offset + DistinctErrorLog.LengthOffset); if (0 == length) { break; } long lastObservationTimestamp = buffer.GetLongVolatile(offset + DistinctErrorLog.LastObservationTimestampOffset); if (lastObservationTimestamp >= sinceTimestamp) { ++entries; consumer( buffer.GetInt(offset + DistinctErrorLog.ObservationCountOffset), buffer.GetLong(offset + DistinctErrorLog.FirstObservationTimestampOffset), lastObservationTimestamp, buffer.GetStringUtf8(offset + DistinctErrorLog.EncodedErrorOffset, length - DistinctErrorLog.EncodedErrorOffset)); } offset += BitUtil.Align(length, DistinctErrorLog.RecordAlignment); } return entries; }
public void ShouldGetFloatFromNativeBuffer(IAtomicBuffer buffer) { var asInt = BitConverter.ToInt32(BitConverter.GetBytes(FloatValue), 0); Marshal.WriteInt32(buffer.BufferPointer, Index, asInt); Assert.That(buffer.GetFloat(Index), Is.EqualTo(FloatValue)); }
public void SetUp() { _buffer = A.Fake<IAtomicBuffer>(); A.CallTo(() => _buffer.Capacity).Returns(TotalBufferLength); _ringBuffer = new ManyToOneRingBuffer(_buffer); }
public void SetUp() { _buffer = A.Fake <IAtomicBuffer>(); A.CallTo(() => _buffer.Capacity).Returns(TotalBufferLength); _ringBuffer = new ManyToOneRingBuffer(_buffer); }
internal AtomicCounter(IAtomicBuffer buffer, int counterId, CountersManager countersManager) { _buffer = buffer; _counterId = counterId; _countersManager = countersManager; _offset = CountersReader.CounterOffset(counterId); buffer.PutLong(_offset, 0); }
/// <summary> /// Map a counter over a buffer. This version will free the counter on close. /// </summary> /// <param name="buffer"> containing the counter. </param> /// <param name="counterId"> identifier for the counter. </param> /// <param name="countersManager"> to be called to free the counter on close. </param> public AtomicCounter(IAtomicBuffer buffer, int counterId, CountersManager countersManager) { _buffer = buffer; Id = counterId; _countersManager = countersManager; _offset = CountersReader.CounterOffset(counterId); buffer.BoundsCheck(_offset, BitUtil.SIZE_OF_LONG); }
public void ShouldGetDoubleFromNativeBuffer(IAtomicBuffer buffer) { var asLong = BitConverter.ToInt64(BitConverter.GetBytes(DoubleValue), 0); Marshal.WriteInt64(buffer.BufferPointer, Index, asLong); Assert.That(buffer.GetDouble(Index), Is.EqualTo(DoubleValue)); }
public void SetUp() { header = new Header(INITIAL_TERM_ID, TERM_BUFFER_CAPACITY); termBuffer = A.Fake <IAtomicBuffer>(); errorHandler = A.Fake <ErrorHandler>(); handler = A.Fake <FragmentHandler>(); A.CallTo(() => termBuffer.Capacity).Returns(TERM_BUFFER_CAPACITY); }
/// <summary> /// Create a new counter buffer manager over two buffers. /// </summary> /// <param name="metaDataBuffer"> containing the types, keys, and labels for the counters. </param> /// <param name="valuesBuffer"> containing the values of the counters themselves. </param> public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer) : base(metaDataBuffer, valuesBuffer) { valuesBuffer.VerifyAlignment(); if (metaDataBuffer.Capacity < valuesBuffer.Capacity * 2) { throw new ArgumentException("Meta data buffer not sufficiently large"); } }
public void ShouldPutFloatToNativeBuffer(IAtomicBuffer buffer) { buffer.PutFloat(Index, FloatValue); var valueAsInt = Marshal.ReadInt32(buffer.BufferPointer, Index); var valueAsFloat = BitConverter.ToSingle(BitConverter.GetBytes(valueAsInt), 0); Assert.That(valueAsFloat, Is.EqualTo(FloatValue)); }
/// <summary> /// Create a new counter buffer manager over two buffers. /// </summary> /// <param name="metaDataBuffer"> containing the types, keys, and labels for the counters. </param> /// <param name="valuesBuffer"> containing the values of the counters themselves. </param> public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer) : base(metaDataBuffer, valuesBuffer) { valuesBuffer.VerifyAlignment(); if (metaDataBuffer.Capacity < valuesBuffer.Capacity*2) { throw new ArgumentException("Meta data buffer not sufficiently large"); } }
/// <summary> /// Create a new counter buffer manager over two buffers. /// </summary> /// <param name="metaDataBuffer"> containing the types, keys, and labels for the counters. </param> /// <param name="valuesBuffer"> containing the values of the counters themselves. </param> /// <param name="labelCharset"> for the label encoding. </param> public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer, Encoding labelCharset) : this(metaDataBuffer, valuesBuffer, labelCharset, new NullEpochClock(), 0) { valuesBuffer.VerifyAlignment(); if (metaDataBuffer.Capacity < (valuesBuffer.Capacity * 2)) { throw new ArgumentException("Meta data buffer not sufficiently large"); } }
public static void FrameLengthOrdered(IAtomicBuffer buffer, int termOffset, int frameLength) { //if (ByteOrder.NativeOrder() != LITTLE_ENDIAN) //{ // frameLength = Integer.ReverseBytes(frameLength); //} buffer.PutIntOrdered(termOffset, frameLength); }
/// <summary> /// Insert a packet of frames into the log at the appropriate offset as indicated by the term offset header. /// </summary> /// <param name="termBuffer"> into which the packet should be inserted. </param> /// <param name="offset"> offset in the term at which the packet should be inserted. </param> /// <param name="packet"> containing a sequence of frames. </param> /// <param name="length"> of the sequence of frames in bytes. </param> public static void Insert(IAtomicBuffer termBuffer, int offset, UnsafeBuffer packet, int length) { var firstFrameLength = packet.GetInt(0); // LITTLE_ENDIAN packet.PutIntOrdered(0, 0); termBuffer.PutBytes(offset, packet, 0, length); FrameDescriptor.FrameLengthOrdered(termBuffer, offset, firstFrameLength); }
public void SetUp() { header = new Header(INITIAL_TERM_ID, TERM_BUFFER_CAPACITY); termBuffer = A.Fake<IAtomicBuffer>(); errorHandler = A.Fake<ErrorHandler>(); handler = A.Fake<FragmentHandler>(); A.CallTo(() => termBuffer.Capacity).Returns(TERM_BUFFER_CAPACITY); }
public void ShouldPutDoubleToNativeBuffer(IAtomicBuffer buffer) { buffer.PutDouble(Index, DoubleValue); var valueAsLong = Marshal.ReadInt64(buffer.BufferPointer, Index); var valueAsDouble = BitConverter.ToDouble(BitConverter.GetBytes(valueAsLong), 0); Assert.That(valueAsDouble, Is.EqualTo(DoubleValue)); }
public void ShouldAddLongOrderedToNativeBuffer(IAtomicBuffer buffer) { var initialValue = int.MaxValue + 7L; const long increment = 9L; buffer.PutLongOrdered(Index, initialValue); buffer.AddLongOrdered(Index, increment); Assert.That(Marshal.ReadInt64(buffer.BufferPointer, Index), Is.EqualTo(initialValue + increment)); }
public void ShouldAddIntOrderedToNativeBuffer(IAtomicBuffer buffer) { const int initialValue = 7; const int increment = 9; buffer.PutIntOrdered(Index, initialValue); buffer.AddIntOrdered(Index, increment); Assert.That(Marshal.ReadInt32(buffer.BufferPointer, Index), Is.EqualTo(initialValue + increment)); }
public void ShouldGetAndAddIntToNativeBuffer(IAtomicBuffer buffer) { Marshal.WriteInt32(buffer.BufferPointer, Index, IntValue); const int delta = 1; var beforeValue = buffer.GetAndAddInt(Index, delta); Assert.That(beforeValue, Is.EqualTo(IntValue)); Assert.That(Marshal.ReadInt32(buffer.BufferPointer, Index), Is.EqualTo(IntValue + delta)); }
/// <summary> /// Insert a packet of frames into the log at the appropriate offset as indicated by the term termOffset header. /// </summary> /// <param name="termBuffer"> into which the packet should be inserted. </param> /// <param name="termOffset"> offset in the term at which the packet should be inserted. </param> /// <param name="packet"> containing a sequence of frames. </param> /// <param name="length"> of the sequence of frames in bytes. </param> public static void Insert(IAtomicBuffer termBuffer, int termOffset, UnsafeBuffer packet, int length) { var firstFrameLength = packet.GetInt(0); // LITTLE_ENDIAN packet.PutIntOrdered(0, 0); Thread.MemoryBarrier(); // UnsafeAccess.UNSAFE.storeFence(); termBuffer.PutBytes(termOffset, packet, 0, length); FrameDescriptor.FrameLengthOrdered(termBuffer, termOffset, firstFrameLength); }
/// <summary> /// Append a fragmented message to the the term buffer. /// The message will be split up into fragments of MTU length minus header. /// </summary> /// <param name="header"> for writing the default header. </param> /// <param name="srcBuffer"> containing the message. </param> /// <param name="srcOffset"> at which the message begins. </param> /// <param name="length"> of the message in the source buffer. </param> /// <param name="maxPayloadLength"> that the message will be fragmented into. </param> /// <returns> the resulting offset of the term after the append on success otherwise <seealso cref="#TRIPPED"/> or <seealso cref="#FAILED"/> /// packed with the termId if a padding record was inserted at the end. </returns> public long AppendFragmentedMessage(HeaderWriter header, IDirectBuffer srcBuffer, int srcOffset, int length, int maxPayloadLength) { int numMaxPayloads = length / maxPayloadLength; int remainingPayload = length % maxPayloadLength; int lastFrameLength = remainingPayload > 0 ? BitUtil.Align(remainingPayload + DataHeaderFlyweight.HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT) : 0; int requiredLength = (numMaxPayloads * (maxPayloadLength + DataHeaderFlyweight.HEADER_LENGTH)) + lastFrameLength; long rawTail = GetAndAddRawTail(requiredLength); int termId = TermId(rawTail); long termOffset = rawTail & 0xFFFFFFFFL; IAtomicBuffer termBuffer = _termBuffer; int termLength = termBuffer.Capacity; long resultingOffset = termOffset + requiredLength; if (resultingOffset > termLength) { resultingOffset = HandleEndOfLogCondition(termBuffer, termOffset, header, termLength, termId); } else { int offset = (int)termOffset; byte flags = FrameDescriptor.BEGIN_FRAG_FLAG; int remaining = length; do { int bytesToWrite = Math.Min(remaining, maxPayloadLength); int frameLength = bytesToWrite + DataHeaderFlyweight.HEADER_LENGTH; int alignedLength = BitUtil.Align(frameLength, FrameDescriptor.FRAME_ALIGNMENT); header.Write(termBuffer, offset, frameLength, termId); termBuffer.PutBytes(offset + DataHeaderFlyweight.HEADER_LENGTH, srcBuffer, srcOffset + (length - remaining), bytesToWrite); if (remaining <= maxPayloadLength) { flags |= FrameDescriptor.END_FRAG_FLAG; } FrameDescriptor.FrameFlags(termBuffer, offset, flags); FrameDescriptor.FrameLengthOrdered(termBuffer, offset, frameLength); flags = 0; offset += alignedLength; remaining -= bytesToWrite; } while (remaining > 0); } return(resultingOffset); }
/// <summary> /// Create a new counter buffer manager over two buffers. /// </summary> /// <param name="metaDataBuffer"> containing the types, keys, and labels for the counters. </param> /// <param name="valuesBuffer"> containing the values of the counters themselves. </param> /// <param name="labelCharset"> for the label encoding. </param> /// <param name="epochClock"> to use for determining time for keep counter from being reused after being freed. </param> /// <param name="freeToReuseTimeoutMs"> timeout (in milliseconds) to keep counter from being reused after being freed. </param> public CountersManager(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer, Encoding labelCharset, IEpochClock epochClock, long freeToReuseTimeoutMs) : base(metaDataBuffer, valuesBuffer, labelCharset) { valuesBuffer.VerifyAlignment(); _epochClock = epochClock; _freeToReuseTimeoutMs = freeToReuseTimeoutMs; if (metaDataBuffer.Capacity < (valuesBuffer.Capacity * 2)) { throw new ArgumentException("Meta data buffer not sufficiently large"); } }
public void ShouldCopyMemory(IAtomicBuffer buffer) { var testBytes = Encoding.UTF8.GetBytes("xxxxxxxxxxx"); buffer.SetMemory(0, testBytes.Length, (byte)'x'); for (var i = 0; i < testBytes.Length; i++) { Assert.That(Marshal.ReadByte(buffer.BufferPointer, i), Is.EqualTo(testBytes[i])); } }
/// <summary> /// Construct a new broadcast receiver based on an underlying <seealso cref="IAtomicBuffer"/>. /// The underlying buffer must a power of 2 in size plus sufficient space /// for the <seealso cref="BroadcastBufferDescriptor.TrailerLength"/>. /// </summary> /// <param name="buffer"> via which messages will be exchanged. </param> /// <exception cref="InvalidOperationException"> if the buffer capacity is not a power of 2 /// plus <seealso cref="BroadcastBufferDescriptor.TrailerLength"/> in capacity. </exception> public BroadcastReceiver(IAtomicBuffer buffer) { _buffer = buffer; _capacity = buffer.Capacity - BroadcastBufferDescriptor.TrailerLength; BroadcastBufferDescriptor.CheckCapacity(_capacity); buffer.VerifyAlignment(); _tailIntentCounterIndex = _capacity + BroadcastBufferDescriptor.TailIntentCounterOffset; _tailCounterIndex = _capacity + BroadcastBufferDescriptor.TailCounterOffset; _latestCounterIndex = _capacity + BroadcastBufferDescriptor.LatestCounterOffset; }
public void SetUp() { _defaultHeader = new UnsafeBuffer(new byte[DataHeaderFlyweight.HEADER_LENGTH]); _termBuffer = A.Fake <IAtomicBuffer>(x => x.Wrapping(new UnsafeBuffer(new byte[TermBufferLength]))); _metaDataBuffer = A.Fake <IAtomicBuffer>(); _headerWriter = A.Fake <HeaderWriter>(x => x.Wrapping(new HeaderWriter(DataHeaderFlyweight.CreateDefaultHeader(0, 0, TermID)))); A.CallTo(() => _termBuffer.Capacity).Returns(TermBufferLength); A.CallTo(() => _metaDataBuffer.Capacity).Returns(MetaDataBufferLength); _termAppender = new TermAppender(_termBuffer, _metaDataBuffer); }
private static int SaveErrorLog(TextWriter writer, IAtomicBuffer errorBuffer) { void ErrorConsumer(int count, long firstTimestamp, long lastTimestamp, string ex) { writer.WriteLine($"***{writer.NewLine}{count} observations from {firstTimestamp} to {lastTimestamp} for:{writer.NewLine} {ex}"); } var distinctErrorCount = ErrorLogReader.Read(errorBuffer, ErrorConsumer); writer.WriteLine($"{writer.NewLine}{distinctErrorCount} distinct errors observed."); return(distinctErrorCount); }
/// <summary> /// Write a header to the term buffer in <seealso cref="ByteOrder.LittleEndian"/> format using the minimum instructions. /// </summary> /// <param name="termBuffer"> to be written to. </param> /// <param name="offset"> at which the header should be written. </param> /// <param name="length"> of the fragment including the header. </param> /// <param name="termId"> of the current term buffer. </param> public virtual void Write(IAtomicBuffer termBuffer, int offset, int length, int termId) { var lengthVersionFlagsType = _versionFlagsType | (-length & 0xFFFFFFFFL); var termOffsetSessionId = _sessionId | (uint)offset; var streamAndTermIds = _streamId | ((long)termId << 32); //TODO why not just putlongvolatile? termBuffer.PutLongOrdered(offset + HeaderFlyweight.FRAME_LENGTH_FIELD_OFFSET, lengthVersionFlagsType); Thread.MemoryBarrier(); termBuffer.PutLong(offset + DataHeaderFlyweight.TERM_OFFSET_FIELD_OFFSET, termOffsetSessionId); termBuffer.PutLong(offset + DataHeaderFlyweight.STREAM_ID_FIELD_OFFSET, streamAndTermIds); }
/// <summary> /// Insert a packet of frames into the log at the appropriate termOffset as indicated by the term termOffset header. /// /// If the packet has already been inserted then this is a noop. /// </summary> /// <param name="termBuffer"> into which the packet should be inserted. </param> /// <param name="termOffset"> in the term at which the packet should be inserted. </param> /// <param name="packet"> containing a sequence of frames. </param> /// <param name="length"> of the packet of frames in bytes. </param> public static void Insert(IAtomicBuffer termBuffer, int termOffset, UnsafeBuffer packet, int length) { if (0 == termBuffer.GetInt(termOffset)) { termBuffer.PutBytes(termOffset + DataHeaderFlyweight.HEADER_LENGTH, packet, DataHeaderFlyweight.HEADER_LENGTH, length - DataHeaderFlyweight.HEADER_LENGTH); termBuffer.PutLong(termOffset + 24, packet.GetLong(24)); termBuffer.PutLong(termOffset + 16, packet.GetLong(16)); termBuffer.PutLong(termOffset + 8, packet.GetLong(8)); termBuffer.PutLongOrdered(termOffset, packet.GetLong(0)); } }
/// <summary> /// Construct a new <seealso cref="RingBuffer"/> based on an underlying <seealso cref="IAtomicBuffer"/>. /// The underlying buffer must a power of 2 in size plus sufficient space /// for the <seealso cref="RingBufferDescriptor.TrailerLength"/>. /// </summary> /// <param name="buffer"> via which events will be exchanged. </param> /// <exception cref="InvalidOperationException"> if the buffer capacity is not a power of 2 /// plus <seealso cref="RingBufferDescriptor.TrailerLength"/> in capacity. </exception> public ManyToOneRingBuffer(IAtomicBuffer buffer) { _buffer = buffer; RingBufferDescriptor.CheckCapacity(buffer.Capacity); _capacity = buffer.Capacity - RingBufferDescriptor.TrailerLength; buffer.VerifyAlignment(); _maxMsgLength = _capacity/8; _tailPositionIndex = _capacity + RingBufferDescriptor.TailPositionOffset; _headCachePositionIndex = _capacity + RingBufferDescriptor.HeadCachePositionOffset; _headPositionIndex = _capacity + RingBufferDescriptor.HeadPositionOffset; _correlationIdCounterIndex = _capacity + RingBufferDescriptor.CorrelationCounterOffset; _consumerHeartbeatIndex = _capacity + RingBufferDescriptor.ConsumerHeartbeatOffset; }
/// <summary> /// Construct a new <seealso cref="RingBuffer"/> based on an underlying <seealso cref="IAtomicBuffer"/>. /// The underlying buffer must a power of 2 in size plus sufficient space /// for the <seealso cref="RingBufferDescriptor.TrailerLength"/>. /// </summary> /// <param name="buffer"> via which events will be exchanged. </param> /// <exception cref="InvalidOperationException"> if the buffer capacity is not a power of 2 /// plus <seealso cref="RingBufferDescriptor.TrailerLength"/> in capacity. </exception> public ManyToOneRingBuffer(IAtomicBuffer buffer) { _buffer = buffer; RingBufferDescriptor.CheckCapacity(buffer.Capacity); _capacity = buffer.Capacity - RingBufferDescriptor.TrailerLength; buffer.VerifyAlignment(); _maxMsgLength = _capacity / 8; _tailPositionIndex = _capacity + RingBufferDescriptor.TailPositionOffset; _headCachePositionIndex = _capacity + RingBufferDescriptor.HeadCachePositionOffset; _headPositionIndex = _capacity + RingBufferDescriptor.HeadPositionOffset; _correlationIdCounterIndex = _capacity + RingBufferDescriptor.CorrelationCounterOffset; _consumerHeartbeatIndex = _capacity + RingBufferDescriptor.ConsumerHeartbeatOffset; }
private int ClaimCapacity(IAtomicBuffer buffer, int requiredCapacity) { var capacity = _capacity; var tailPositionIndex = _tailPositionIndex; var headCachePositionIndex = _headCachePositionIndex; var mask = capacity - 1; var head = buffer.GetLongVolatile(headCachePositionIndex); long tail; int tailIndex; int padding; do { tail = buffer.GetLongVolatile(tailPositionIndex); var availableCapacity = capacity - (int) (tail - head); if (requiredCapacity > availableCapacity) { head = buffer.GetLongVolatile(_headPositionIndex); if (requiredCapacity > (capacity - (int) (tail - head))) { return InsufficientCapacity; } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = 0; tailIndex = (int) tail & mask; var toBufferEndLength = capacity - tailIndex; if (requiredCapacity > toBufferEndLength) { var headIndex = (int) head & mask; if (requiredCapacity > headIndex) { head = buffer.GetLongVolatile(_headPositionIndex); headIndex = (int) head & mask; if (requiredCapacity > headIndex) { return InsufficientCapacity; } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = toBufferEndLength; } } while (!buffer.CompareAndSetLong(tailPositionIndex, tail, tail + requiredCapacity + padding)); if (0 != padding) { buffer.PutLongOrdered(tailIndex, RecordDescriptor.MakeHeader(padding, PaddingMsgTypeId)); tailIndex = 0; } return tailIndex; }
private static bool ScanBackToConfirmStillZeroed(IAtomicBuffer buffer, int from, int limit) { var i = from - RecordDescriptor.Alignment; var allZeros = true; while (i >= limit) { if (0 != buffer.GetIntVolatile(i)) { allZeros = false; break; } i -= RecordDescriptor.Alignment; } return allZeros; }
/// <summary> /// Create a new error log that will be written to a provided <seealso cref="IAtomicBuffer"/>. /// </summary> /// <param name="buffer"> into which the observation records are recorded. </param> /// <param name="clock"> to be used for time stamping records. </param> public DistinctErrorLog(IAtomicBuffer buffer, IEpochClock clock) { buffer.VerifyAlignment(); _clock = clock; _buffer = buffer; }
/// <summary> /// Construct a view over a term buffer and state buffer for appending frames. /// </summary> /// <param name="termBuffer"> for where messages are stored. </param> /// <param name="metaDataBuffer"> for where the state of writers is stored manage concurrency. </param> public TermAppender(IAtomicBuffer termBuffer, IAtomicBuffer metaDataBuffer) { this._termBuffer = termBuffer; this._metaDataBuffer = metaDataBuffer; }
/// <summary> /// Construct a reader over buffers containing the values and associated metadata. /// </summary> /// <param name="metaDataBuffer"> containing the counter metadata. </param> /// <param name="valuesBuffer"> containing the counter values. </param> public CountersReader(IAtomicBuffer metaDataBuffer, IAtomicBuffer valuesBuffer) { ValuesBuffer = valuesBuffer; MetaDataBuffer = metaDataBuffer; }
/// <summary> /// Read all the errors in a log since the creation of the log. /// </summary> /// <param name="buffer"> containing the <seealso cref="DistinctErrorLog"/>. </param> /// <param name="consumer"> to be called for each exception encountered. </param> /// <returns> the number of entries that has been read. </returns> public static int Read(IAtomicBuffer buffer, ErrorConsumer consumer) { return Read(buffer, consumer, 0); }
/// <summary> /// Write the flags field for a frame. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <param name="flags"> value for the frame. </param> public static void FrameFlags(IAtomicBuffer buffer, int termOffset, byte flags) { buffer.PutByte(FlagsOffset(termOffset), flags); }
public void SetUp() { _termBuffer = A.Fake<IAtomicBuffer>(); A.CallTo(() => _termBuffer.Capacity).Returns(LogBufferDescriptor.TERM_MIN_LENGTH); }
/// <summary> /// Is the frame starting at the termOffset a padding frame at the end of a buffer? /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <returns> true if the frame is a padding frame otherwise false. </returns> public static bool IsPaddingFrame(IAtomicBuffer buffer, int termOffset) { return buffer.GetShort(TypeOffset(termOffset)) == PADDING_FRAME_TYPE; }
/// <summary> /// Read the type of of the frame from header. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <returns> the value of the frame type header. </returns> public static int FrameType(IAtomicBuffer buffer, int termOffset) { //return buffer.GetShort(TypeOffset(termOffset), LITTLE_ENDIAN) & 0xFFFF; return buffer.GetShort(TypeOffset(termOffset)) & 0xFFFF; }
private long HandleEndOfLogCondition(IAtomicBuffer termBuffer, long termOffset, HeaderWriter header, int termLength, int termId) { int resultingOffset = FAILED; if (termOffset <= termLength) { resultingOffset = TRIPPED; if (termOffset < termLength) { int offset = (int) termOffset; int paddingLength = termLength - offset; header.Write(termBuffer, offset, paddingLength, termId); FrameDescriptor.FrameType(termBuffer, offset, FrameDescriptor.PADDING_FRAME_TYPE); FrameDescriptor.FrameLengthOrdered(termBuffer, offset, paddingLength); } } return Pack(termId, resultingOffset); }
/// <summary> /// Get the length of a frame from the header as a volatile read. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <returns> the value for the frame length. </returns> public static int FrameLengthVolatile(IAtomicBuffer buffer, int termOffset) { int frameLength = buffer.GetIntVolatile(termOffset); return frameLength; }
/// <summary> /// Write the length header for a frame in a memory ordered fashion. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <param name="frameLength"> field to be set for the frame. </param> public static void FrameLengthOrdered(IAtomicBuffer buffer, int termOffset, int frameLength) { //if (ByteOrder.NativeOrder() != LITTLE_ENDIAN) //{ // frameLength = Integer.ReverseBytes(frameLength); //} buffer.PutIntOrdered(termOffset, frameLength); }
public void SetUp() { _buffer = A.Fake<IAtomicBuffer>(); A.CallTo(() => _buffer.Capacity).Returns(TotalBufferLength); _broadcastReceiver = new BroadcastReceiver(_buffer); }
/// <summary> /// Read the type of of the frame from header. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <returns> the value of the frame type header. </returns> public static int FrameVersion(IAtomicBuffer buffer, int termOffset) { return buffer.GetByte(VersionOffset(termOffset)); }
/// <summary> /// Get the length of a frame from the header. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <returns> the value for the frame length. </returns> public static int FrameLength(IAtomicBuffer buffer, int termOffset) { return buffer.GetInt(termOffset); }
/// <summary> /// Write the type field for a frame. /// </summary> /// <param name="buffer"> containing the frame. </param> /// <param name="termOffset"> at which a frame begins. </param> /// <param name="type"> type value for the frame. </param> public static void FrameType(IAtomicBuffer buffer, int termOffset, int type) { buffer.PutShort(TypeOffset(termOffset), (short) type); }