/// <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; }
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; }
public void ShouldReceiveFirstMessageFromBuffer() { const int length = 8; var recordLength = length + RecordDescriptor.HeaderLength; var recordLengthAligned = BitUtil.Align(recordLength, RecordDescriptor.RecordAlignment); long tail = recordLengthAligned; var latestRecord = tail - recordLengthAligned; var recordOffset = (int)latestRecord; A.CallTo(() => _buffer.GetLongVolatile(TailIntentCounterOffset)).Returns(tail); A.CallTo(() => _buffer.GetLongVolatile(TailCounterIndex)).Returns(tail); A.CallTo(() => _buffer.GetInt(RecordDescriptor.GetLengthOffset(recordOffset))).Returns(recordLength); A.CallTo(() => _buffer.GetInt(RecordDescriptor.GetTypeOffset(recordOffset))).Returns(MsgTypeID); Assert.True(_broadcastReceiver.ReceiveNext()); Assert.AreEqual(MsgTypeID, _broadcastReceiver.TypeId()); Assert.AreEqual(_buffer, _broadcastReceiver.Buffer()); Assert.AreEqual(RecordDescriptor.GetMsgOffset(recordOffset), _broadcastReceiver.Offset()); Assert.AreEqual(length, _broadcastReceiver.Length()); Assert.True(_broadcastReceiver.Validate()); A.CallTo(() => _buffer.GetLongVolatile(TailCounterIndex)).MustHaveHappened(); A.CallTo(() => _buffer.GetLongVolatile(TailIntentCounterOffset)).MustHaveHappened(); }
public void ShouldGetLongVolatileFromNativeBuffer(IAtomicBuffer buffer) { Marshal.WriteInt64(buffer.BufferPointer, Index, LongValue); Assert.That(buffer.GetLongVolatile(Index), Is.EqualTo(LongValue)); }
/// <summary> /// Get the latest value for the counter with volatile semantics. /// <para> /// <b>Note:</b>The user should call <seealso cref="#isClosed()"/> and ensure the result is false to avoid a race on reading /// a closed counter. /// /// </para> /// </summary> /// <returns> the latest value for the counter. </returns> public virtual long Get() { // return UnsafeAccess.UNSAFE.getLongVolatile(buffer, addressOffset); return(valuesBuffer.GetLongVolatile(addressOffset)); }
public void ShouldWriteToEmptyBuffer() { const int length = 8; var recordLength = length + RecordDescriptor.HeaderLength; var alignedRecordLength = BitUtil.Align(recordLength, RecordDescriptor.Alignment); const long tail = 0L; const long head = 0L; A.CallTo(() => _buffer.GetLongVolatile(HeadCounterIndex)).Returns(head); A.CallTo(() => _buffer.GetLongVolatile(TailCounterIndex)).Returns(tail); A.CallTo(() => _buffer.CompareAndSetLong(TailCounterIndex, tail, tail + alignedRecordLength)).Returns(true); var srcBuffer = new UnsafeBuffer(new byte[1024]); const int srcIndex = 0; Assert.True(_ringBuffer.Write(MsgTypeID, srcBuffer, srcIndex, length)); A.CallTo(() => _buffer.PutLongOrdered((int)tail, RecordDescriptor.MakeHeader(-recordLength, MsgTypeID))).MustHaveHappened() .Then(A.CallTo(() => _buffer.PutBytes(RecordDescriptor.EncodedMsgOffset((int)tail), srcBuffer, srcIndex, length)).MustHaveHappened()) .Then(A.CallTo(() => _buffer.PutIntOrdered(RecordDescriptor.LengthOffset((int)tail), recordLength)).MustHaveHappened()); }
/// <summary> /// Get the raw value current tail value in a volatile memory ordering fashion. /// </summary> /// <returns> the current tail value. </returns> public long RawTailVolatile() { return(_metaDataBuffer.GetLongVolatile(LogBufferDescriptor.TERM_TAIL_COUNTER_OFFSET)); }
/// <summary> /// Get the latest value for the counter with volatile semantics. /// </summary> /// <returns> the latest value for the counter. </returns> public long Get() { return(_buffer.GetLongVolatile(_offset)); }
private bool Validate(long cursor) { return(cursor + _capacity > _buffer.GetLongVolatile(_tailIntentCounterIndex)); }
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); }
/// <summary> /// The time of the last consumer heartbeat. /// </summary> /// <returns> the time of the last consumer heartbeat. </returns> public long ConsumerHeartbeatTime() { return(_buffer.GetLongVolatile(_consumerHeartbeatIndex)); }