MPD: util/CircularBuffer.hxx Source File

MPD 0.20.15

CircularBuffer.hxx
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2014 Max Kellermann <max.kellermann@gmail.com>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef CIRCULAR_BUFFER_HPP
31 #define CIRCULAR_BUFFER_HPP
32
33 #include "WritableBuffer.hxx"
34
35 #include <assert.h>
36 #include <stddef.h>
37
50 template<typename T>
51 class CircularBuffer {
52 public:
53 typedef WritableBuffer<T> Range;
54 typedef typename Range::pointer_type pointer_type;
55 typedef typename Range::size_type size_type;
56
57 protected:
61 size_type head;
62
66 size_type tail;
67
68 const size_type capacity;
69 const pointer_type data;
70
71 public:
72 constexpr CircularBuffer(pointer_type _data, size_type _capacity)
73 :head(0), tail(0), capacity(_capacity), data(_data) {}
74
75 CircularBuffer(const CircularBuffer &other) = delete;
76
77 protected:
78 constexpr size_type Next(size_type i) const {
79 return i + 1 == capacity
80 ? 0
81 : i + 1;
82 }
83
84 public:
85 void Clear() {
86 head = tail = 0;
87 }
88
89 constexpr size_type GetCapacity() const {
90 return capacity;
91 }
92
93 constexpr bool IsEmpty() const {
94 return head == tail;
95 }
96
97 constexpr bool IsFull() const {
98 return Next(tail) == head;
99 }
100
104 constexpr size_type GetSize() const {
105 return head <= tail
106 ? tail - head
107 : capacity - head + tail;
108 }
109
114 constexpr size_type GetSpace() const {
115 /* space = capacity - size - 1 */
116 return (head <= tail
117 ? capacity - tail + head
118 : head - tail)
119 - 1;
120 }
121
126 Range Write() {
127 assert(head < capacity);
128 assert(tail < capacity);
129
130 size_type end = tail < head
131 ? head - 1
132 /* the "head==0" is there so we don't write
133 the last cell, as this situation cannot be
134 represented by head/tail */
135 : capacity - (head == 0);
136
137 return Range(data + tail, end - tail);
138 }
139
144 void Append(size_type n) {
145 assert(head < capacity);
146 assert(tail < capacity);
147 assert(n < capacity);
148 assert(tail + n <= capacity);
149 assert(head <= tail || tail + n < head);
150
151 tail += n;
152
153 if (tail == capacity) {
154 assert(head > 0);
155 tail = 0;
156 }
157 }
158
163 Range Read() {
164 assert(head < capacity);
165 assert(tail < capacity);
166
167 return Range(data + head, (tail < head ? capacity : tail) - head);
168 }
169
173 void Consume(size_type n) {
174 assert(head < capacity);
175 assert(tail < capacity);
176 assert(n < capacity);
177 assert(head + n <= capacity);
178 assert(tail < head || head + n <= tail);
179
180 head += n;
181 if (head == capacity)
182 head = 0;
183 }
184 };
185
186 #endif
WritableBuffer.hxx
CircularBuffer::head
size_type head
The next index to be read.
Definition: CircularBuffer.hxx:61
CircularBuffer::data
const pointer_type data
Definition: CircularBuffer.hxx:69
CircularBuffer::Clear
void Clear()
Definition: CircularBuffer.hxx:85
CircularBuffer::pointer_type
Range::pointer_type pointer_type
Definition: CircularBuffer.hxx:54
WritableBuffer
A reference to a memory area that is writable.
Definition: Silence.hxx:27
CircularBuffer::Range
WritableBuffer< T > Range
Definition: CircularBuffer.hxx:53
CircularBuffer::IsFull
constexpr bool IsFull() const
Definition: CircularBuffer.hxx:97
WritableBuffer::pointer_type
T * pointer_type
Definition: WritableBuffer.hxx:85
CircularBuffer::Consume
void Consume(size_type n)
Marks a chunk as consumed.
Definition: CircularBuffer.hxx:173
CircularBuffer::GetSize
constexpr size_type GetSize() const
Returns the number of elements stored in this buffer.
Definition: CircularBuffer.hxx:104
CircularBuffer::GetSpace
constexpr size_type GetSpace() const
Returns the number of elements that can be added to this buffer.
Definition: CircularBuffer.hxx:114
CircularBuffer::Read
Range Read()
Return a buffer range which may be read.
Definition: CircularBuffer.hxx:163
CircularBuffer::Write
Range Write()
Prepares writing.
Definition: CircularBuffer.hxx:126
CircularBuffer::IsEmpty
constexpr bool IsEmpty() const
Definition: CircularBuffer.hxx:93
CircularBuffer
A circular buffer.
Definition: ThreadInputStream.hxx:32
CircularBuffer::Append
void Append(size_type n)
Expands the tail of the buffer, after data has been written to the buffer returned by Write()...
Definition: CircularBuffer.hxx:144
CircularBuffer::GetCapacity
constexpr size_type GetCapacity() const
Definition: CircularBuffer.hxx:89
CircularBuffer::tail
size_type tail
The next index to be written to.
Definition: CircularBuffer.hxx:66
CircularBuffer::size_type
Range::size_type size_type
Definition: CircularBuffer.hxx:55
CircularBuffer::Next
constexpr size_type Next(size_type i) const
Definition: CircularBuffer.hxx:78
CircularBuffer::capacity
const size_type capacity
Definition: CircularBuffer.hxx:68
WritableBuffer::size_type
size_t size_type
Definition: WritableBuffer.hxx:82
CircularBuffer::CircularBuffer
constexpr CircularBuffer(pointer_type _data, size_type _capacity)
Definition: CircularBuffer.hxx:72