geopm 3.1.1.dev456+g3ba31824
GEOPM - Global Extensible Open Power Manager
Loading...
Searching...
No Matches
CircularBuffer.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 - 2024 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#ifndef CIRCULARBUFFER_HPP_INCLUDE
7#define CIRCULARBUFFER_HPP_INCLUDE
8
9#include <stdlib.h>
10
11#include <vector>
12
13#include "geopm_public.h"
14
15#include "Exception.hpp"
16
17namespace geopm
18{
22 template <class type>
24 {
25 public:
32 CircularBuffer(unsigned int size);
34 virtual ~CircularBuffer();
44 void set_capacity(const unsigned int size);
48 void clear(void);
54 //
56 int size(void) const;
63 int capacity(void) const;
73 void insert(const type value);
92 const type& value(const int index) const;
96 std::vector<type> make_vector(void) const;
106 std::vector<type> make_vector(const unsigned int start, const unsigned int end) const;
107 private:
109 std::vector<type> m_buffer;
111 unsigned long m_head;
113 unsigned long m_count;
115 size_t m_max_size;
116 };
117
118 template <class type>
124
125 template <class type>
127 : m_buffer(size)
128 , m_head(0)
129 , m_count(0)
130 , m_max_size(size)
131 {
132
133 }
134
135 template <class type>
140
141 template <class type>
143 {
144 return m_count;
145 }
146
147 template <class type>
149 {
150 return m_max_size;
151 }
152
153 template <class type>
155 {
156 m_head = 0;
157 m_count = 0;
158 }
159
160 template <class type>
161 void CircularBuffer<type>::set_capacity(const unsigned int size)
162 {
163 // If the requested new capacity is less than the size.
164 if (size < m_count && m_max_size > 0) {
165 int size_diff = m_count - size;
166 std::vector<type> temp;
167 for (size_t idx = size_diff; idx < m_count; ++idx) {
168 temp.push_back(value(idx));
169 }
170 //now re-size and swap out with tmp vector data
171 m_buffer.resize(size);
172 m_buffer.swap(temp);
173 m_count = size;
174 }
175 else {
176 m_buffer.resize(size);
177 }
178 m_head = 0;
179 m_max_size = size;
180 }
181
182 template <class type>
183 void CircularBuffer<type>::insert(const type value)
184 {
185 if (m_max_size < 1) {
186 throw Exception("CircularBuffer::insert(): Cannot insert into a buffer of 0 size", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
187 }
188 if (m_count < m_max_size) {
189 m_buffer.at(m_count) = value;
190 m_count++;
191 }
192 else {
193 m_buffer.at(m_head) = value;
194 m_head = ((m_head + 1) % m_max_size);
195 }
196 }
197
198 template <class type>
199 const type& CircularBuffer<type>::value(const int index) const
200 {
201 if (index >= static_cast<int>(m_count) || index < -static_cast<int>(m_count)) {
202 throw Exception(std::string("CircularBuffer::value(): index [") + std::to_string(index) + "] is out of bounds",
203 GEOPM_ERROR_INVALID, __FILE__, __LINE__);
204 }
205 if (index < 0) {
206 const int new_index = m_count + index;
207 return m_buffer.at((m_head + new_index) % m_max_size);
208 } else {
209 return m_buffer.at((m_head + index) % m_max_size);
210 }
211 }
212
213 template <class type>
214 std::vector<type> CircularBuffer<type>::make_vector(void) const
215 {
216 std::vector<type> result(size());
217 if (m_head == 0) {
218 std::copy(m_buffer.begin(), m_buffer.begin() + m_count, result.begin());
219 }
220 else {
221 std::copy(m_buffer.begin() + m_head, m_buffer.end(), result.begin());
222 std::copy(m_buffer.begin(), m_buffer.begin() + m_head, result.end() - m_head);
223 }
224 return result;
225 }
226
227 template <class type>
228 std::vector<type> CircularBuffer<type>::make_vector(const unsigned int idx_start, const unsigned int idx_end) const
229 {
230 if (idx_start >= (unsigned int)size()) {
231 throw Exception("CircularBuffer::make_vector(): start is out of bounds", GEOPM_ERROR_INVALID, __FILE__, __LINE__);
232 }
233 if (idx_end > (unsigned int)size()) {
234 throw Exception("CircularBuffer::make_vector(): end is out of bounds", GEOPM_ERROR_INVALID, __FILE__, __LINE__);
235 }
236 if (idx_end <= idx_start) {
237 throw Exception("CircularBuffer::make_vector(): end index is smaller than start index", GEOPM_ERROR_INVALID, __FILE__, __LINE__);
238 }
239
240 int slice_length = idx_end - idx_start;
241 std::vector<type> result(slice_length);
242
243 unsigned int start=(m_head + idx_start) % capacity();
244 unsigned int end=(((m_head + idx_end) - 1) % capacity()) + 1;
245
246 if(end > start) {
247 std::copy(m_buffer.begin() + start, m_buffer.begin() + end, result.begin());
248 }
249 else {
250 std::copy(m_buffer.begin() + start, m_buffer.end(), result.begin());
251 std::copy(m_buffer.begin(), m_buffer.begin() + end, result.begin() + capacity() - start);
252 }
253 return result;
254 }
255
256}
257
258#endif
Templated container for a circular buffer implementation. The CircularBuffer container implements a f...
Definition CircularBuffer.hpp:24
virtual ~CircularBuffer()
CircularBuffer destructor, virtual.
Definition CircularBuffer.hpp:136
std::vector< type > make_vector(void) const
Create a vector from the entire circular buffer contents.
Definition CircularBuffer.hpp:214
int capacity(void) const
Capacity of the buffer.
Definition CircularBuffer.hpp:148
int size(void) const
Size of the buffer contents.
Definition CircularBuffer.hpp:142
const type & value(const int index) const
Returns a constant reference to the value from the buffer.
Definition CircularBuffer.hpp:199
void clear(void)
Clears all entries from the buffer.
Definition CircularBuffer.hpp:154
CircularBuffer()
Definition CircularBuffer.hpp:119
void set_capacity(const unsigned int size)
Re-size the circular buffer.
Definition CircularBuffer.hpp:161
std::vector< type > make_vector(const unsigned int start, const unsigned int end) const
Create a vector slice from the circular buffer contents.
Definition CircularBuffer.hpp:228
void insert(const type value)
Insert a value into the buffer.
Definition CircularBuffer.hpp:183
CircularBuffer(unsigned int size)
Constructor for the CircularBuffer template.
Definition CircularBuffer.hpp:126
Class for all GEOPM-specific exceptions.
Definition Exception.hpp:48
@ GEOPM_ERROR_INVALID
Definition geopm_error.h:20
@ GEOPM_ERROR_RUNTIME
Definition geopm_error.h:18
Definition Agg.cpp:20