VLCB
Loading...
Searching...
No Matches
CircularBuffer.h
Go to the documentation of this file.
1// Copyright (C) Sven Rosvall (sven@rosvall.ie)
2// This file is part of VLCB-Arduino project on https://github.com/SvenRosvall/VLCB-Arduino
3// Licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
4// The full licence can be found at: http://creativecommons.org/licenses/by-nc-sa/4.0
5
6#pragma once
7
8#include <stdint.h>
9
10namespace VLCB
11{
12
13template <typename E, int bufferCapacity = 4>
15{
16public:
17 explicit CircularBuffer();
19
20 bool available() const;
21 E *peek();
22 const E & pop();
23 void put(const E &entry);
24 void clear();
25
26 // Diagnostic metrics access
27 uint8_t bufUse() const;
28 unsigned int getNumberOfPuts() const { return numPuts; }
29 unsigned int getNumberOfGets() const { return numGets; }
30 unsigned int getOverflows() const { return numOverflows; }
31 unsigned int getHighWaterMark() const { return hwm; }
32
33private:
34
35 uint8_t capacity;
36 uint8_t head = 0;
37 uint8_t tail = 0;
38 bool full = false;
39
40 // Diagnostic metrics
41 uint8_t hwm = 0; // High water Mark
42 uint8_t numPuts = 0;
43 uint8_t numGets = 0;
44 uint8_t numOverflows = 0;
45
46 E buffer[bufferCapacity];
47};
48
49
50template <typename E, int bufferCapacity>
52 : capacity(bufferCapacity)
53{}
54
55template <typename E, int bufferCapacity>
59
61template <typename E, int bufferCapacity>
63{
64 return full || (head != tail);
65}
66
69template <typename E, int bufferCapacity>
71{
72 buffer[head] = entry;
73
74 if (full)
75 {
76 // if the buffer is full, this put will overwrite the oldest item
77 tail = (tail + 1) % capacity;
78 ++numOverflows;
79 }
80
81 head = (head + 1) % capacity;
82 full = head == tail;
83 uint8_t size = bufUse();
84 if (size > hwm)
85 {
86 // Tracks high water mark (hwm)
87 hwm = size;
88 }
89 ++numPuts; // Counts how many events put to buffer.
90 // DEBUG_SERIAL << ">COE Puts = " << numPuts << " Size = " << size <<endl;
91}
92
94template <typename E, int bufferCapacity>
96{
97 uint8_t oldTail = tail;
98 full = false;
99 tail = (tail + 1) % capacity;
100 ++numGets; // Counts how many events got from buffer.
101 // DEBUG_SERIAL << ">COE Gets = " << numGets << endl;
102 return buffer[oldTail];
103}
104
106template <typename E, int bufferCapacity>
108{
109 // should always call ::available first to avoid this
110 if (available())
111 {
112 return &buffer[tail];
113 }
114 else
115 {
116 return nullptr;
117 }
118}
119
121template <typename E, int bufferCapacity>
123{
124 head = 0;
125 tail = 0;
126 full = false;
127}
128
130template <typename E, int bufferCapacity>
132{
133 int8_t size = capacity;
134 if (!full)
135 {
136 size = head - tail;
137 if (size < 0)
138 {
139 size += capacity;
140 }
141 }
142 return size;
143}
144
145}
CircularBuffer()
Definition CircularBuffer.h:51
bool available() const
if buffer has one or more stored items
Definition CircularBuffer.h:62
void put(const E &entry)
Definition CircularBuffer.h:70
E * peek()
peek at the next item in the buffer without removing it
Definition CircularBuffer.h:107
const E & pop()
retrieve the next item from the buffer, requires that available() is checked first.
Definition CircularBuffer.h:95
unsigned int getNumberOfGets() const
Definition CircularBuffer.h:29
unsigned int getHighWaterMark() const
Definition CircularBuffer.h:31
unsigned int getOverflows() const
Definition CircularBuffer.h:30
unsigned int getNumberOfPuts() const
Definition CircularBuffer.h:28
~CircularBuffer()
Definition CircularBuffer.h:56
uint8_t bufUse() const
recalculate number of items in the buffer
Definition CircularBuffer.h:131
void clear()
clear all items
Definition CircularBuffer.h:122
Definition AbstractEventTeachingService.cpp:13