https://mooseframework.inl.gov
Loading...
Searching...
No Matches
CircularBuffer.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12#include "Buffer.h"
13
14namespace MooseUtils
15{
16
35template <typename T>
36class CircularBuffer : public Buffer<T>
37{
38public:
40
41 CircularBuffer(const std::size_t capacity);
42
43 virtual void erase(const std::size_t num) override;
44 virtual void eraseChunk(const std::size_t chunk_size) override;
45
46 virtual typename Buffer<T>::iterator beginChunk(const std::size_t chunk_size) override;
47 virtual typename Buffer<T>::const_iterator
48 beginChunk(const std::size_t chunk_size) const override;
49 virtual typename Buffer<T>::iterator endChunk(const std::size_t chunk_size) override;
50 virtual typename Buffer<T>::const_iterator endChunk(const std::size_t chunk_size) const override;
51
52protected:
53 virtual std::size_t newEnd(const std::size_t new_end) override;
54};
55
56template <typename T>
60
61template <typename T>
62CircularBuffer<T>::CircularBuffer(const std::size_t capacity) : Buffer<T>(capacity)
63{
64}
65
66template <typename T>
67void
68CircularBuffer<T>::erase(const std::size_t num)
69{
70 mooseAssert(num <= this->size(), "Cannot erase past the last entry");
71
72 this->_begin_pos += num;
73
74 // If there's nothing in the buffer - let's reset the positions
75 if (this->_begin_pos == this->_end_pos)
76 this->clear();
77}
78
79template <typename T>
80void
81CircularBuffer<T>::eraseChunk(const std::size_t chunk_size)
82{
83 if (chunk_size > this->size())
84 this->erase(this->size());
85 else
86 this->erase(chunk_size);
87}
88
89template <typename T>
91CircularBuffer<T>::beginChunk(const std::size_t /* chunk_size */)
92{
93 return this->begin();
94}
95
96template <typename T>
98CircularBuffer<T>::beginChunk(const std::size_t /* chunk_size */) const
99{
100 return this->begin();
101}
102
103template <typename T>
104typename Buffer<T>::iterator
105CircularBuffer<T>::endChunk(const std::size_t chunk_size)
106{
107 if (chunk_size > this->size())
108 return this->end();
109 else
110 return this->begin() + chunk_size;
111}
112
113template <typename T>
115CircularBuffer<T>::endChunk(const std::size_t chunk_size) const
116{
117 if (chunk_size > this->size())
118 return this->end();
119 else
120 return this->begin() + chunk_size;
121}
122
123template <typename T>
124std::size_t
125CircularBuffer<T>::newEnd(const std::size_t new_end)
126{
127 auto actual_new_end = new_end;
128
129 if (new_end > this->_data.size())
130 {
131 const auto new_size = new_end - this->_begin_pos;
132
133 // See if we need to grow our capacity
134 if (this->_begin_pos == 0) // If we're already using the beginning - just resize
135 this->_data.resize(2 * new_size);
136 else
137 {
138 // Move everything to the beginning
139 auto to_it = this->_data.begin();
140 for (auto from_it = this->begin(); from_it < this->end(); ++from_it)
141 *to_it++ = std::move(*from_it);
142
143 this->_begin_pos = 0;
144 actual_new_end = new_size;
145
146 // If there still isn't room... add space
147 if (actual_new_end > this->_data.size())
148 this->_data.resize(2 * new_size);
149 }
150 }
151
152 return actual_new_end;
153}
154
155}
sideset clear()
Base class for a buffer.
Definition Buffer.h:29
std::vector< T >::iterator iterator
Definition Buffer.h:31
std::vector< T >::const_iterator const_iterator
Definition Buffer.h:32
std::size_t capacity() const
Get the capacity.
Definition Buffer.h:53
An optimized circular buffer.
virtual void eraseChunk(const std::size_t chunk_size) override
virtual std::size_t newEnd(const std::size_t new_end) override
Find out where the new end will be.
virtual Buffer< T >::iterator endChunk(const std::size_t chunk_size) override
Iterator for the last entry of a chunk size in the buffer If chunk_size is greater than the size of t...
virtual void erase(const std::size_t num) override
Remove the first num elements.
virtual Buffer< T >::iterator beginChunk(const std::size_t chunk_size) override
Iterator for the first entry with a given chunk size in the buffer If chunk_size is greater than the ...