예제 #1
0
        /// <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;
        }
예제 #2
0
        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;
        }
예제 #3
0
        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();
        }
예제 #4
0
        public void ShouldGetLongVolatileFromNativeBuffer(IAtomicBuffer buffer)
        {
            Marshal.WriteInt64(buffer.BufferPointer, Index, LongValue);

            Assert.That(buffer.GetLongVolatile(Index), Is.EqualTo(LongValue));
        }
예제 #5
0
        /// <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());
        }
예제 #7
0
 /// <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));
 }
예제 #8
0
 /// <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));
 }
예제 #9
0
 private bool Validate(long cursor)
 {
     return(cursor + _capacity > _buffer.GetLongVolatile(_tailIntentCounterIndex));
 }
예제 #10
0
        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);
        }
예제 #11
0
 /// <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));
 }