1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
3 #include "base/ringbuffer.hpp"
4 #include "base/objectlock.hpp"
5 #include "base/utility.hpp"
8 using namespace icinga;
10 RingBuffer::RingBuffer(RingBuffer::SizeType slots)
11 : m_Slots(slots, 0), m_TimeValue(0), m_InsertedValues(0)
14 RingBuffer::SizeType RingBuffer::GetLength() const
16 boost::mutex::scoped_lock lock(m_Mutex);
17 return m_Slots.size();
20 void RingBuffer::InsertValue(RingBuffer::SizeType tv, int num)
22 boost::mutex::scoped_lock lock(m_Mutex);
24 InsertValueUnlocked(tv, num);
27 void RingBuffer::InsertValueUnlocked(RingBuffer::SizeType tv, int num)
29 RingBuffer::SizeType offsetTarget = tv % m_Slots.size();
34 if (tv > m_TimeValue) {
35 RingBuffer::SizeType offset = m_TimeValue % m_Slots.size();
37 /* walk towards the target offset, resetting slots to 0 */
38 while (offset != offsetTarget) {
41 if (offset >= m_Slots.size())
46 if (m_TimeValue != 0 && m_InsertedValues < m_Slots.size())
53 m_Slots[offsetTarget] += num;
56 int RingBuffer::UpdateAndGetValues(RingBuffer::SizeType tv, RingBuffer::SizeType span)
58 boost::mutex::scoped_lock lock(m_Mutex);
60 return UpdateAndGetValuesUnlocked(tv, span);
63 int RingBuffer::UpdateAndGetValuesUnlocked(RingBuffer::SizeType tv, RingBuffer::SizeType span)
65 InsertValueUnlocked(tv, 0);
67 if (span > m_Slots.size())
68 span = m_Slots.size();
70 int off = m_TimeValue % m_Slots.size();
85 double RingBuffer::CalculateRate(RingBuffer::SizeType tv, RingBuffer::SizeType span)
87 boost::mutex::scoped_lock lock(m_Mutex);
89 int sum = UpdateAndGetValuesUnlocked(tv, span);
90 return sum / static_cast<double>(std::min(span, m_InsertedValues));