https://mooseframework.inl.gov
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 
14 namespace MooseUtils
15 {
16 
35 template <typename T>
36 class CircularBuffer : public Buffer<T>
37 {
38 public:
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 
52 protected:
53  virtual std::size_t newEnd(const std::size_t new_end) override;
54 };
55 
56 template <typename T>
58 {
59 }
60 
61 template <typename T>
62 CircularBuffer<T>::CircularBuffer(const std::size_t capacity) : Buffer<T>(capacity)
63 {
64 }
65 
66 template <typename T>
67 void
68 CircularBuffer<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 
79 template <typename T>
80 void
81 CircularBuffer<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 
89 template <typename T>
90 typename Buffer<T>::iterator
91 CircularBuffer<T>::beginChunk(const std::size_t /* chunk_size */)
92 {
93  return this->begin();
94 }
95 
96 template <typename T>
98 CircularBuffer<T>::beginChunk(const std::size_t /* chunk_size */) const
99 {
100  return this->begin();
101 }
102 
103 template <typename T>
104 typename Buffer<T>::iterator
105 CircularBuffer<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 
113 template <typename T>
115 CircularBuffer<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 
123 template <typename T>
124 std::size_t
125 CircularBuffer<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 }
std::vector< T >::const_iterator const_iterator
Definition: Buffer.h:32
virtual void eraseChunk(const std::size_t chunk_size) override
Base class for a buffer.
Definition: Buffer.h:28
std::vector< T >::iterator iterator
Definition: Buffer.h:31
std::size_t capacity() const
Get the capacity.
Definition: Buffer.h:53
An optimized circular buffer.
sideset clear()
virtual void erase(const std::size_t num) override
Remove the first num elements.
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 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 ...