util/CircularBuffer: use std::span internally

This commit is contained in:
Max Kellermann 2024-07-29 22:06:26 +02:00
parent 596d2d93dd
commit dbaa72cb40
6 changed files with 28 additions and 31 deletions

View File

@ -20,7 +20,6 @@ AsyncInputStream::AsyncInputStream(EventLoop &event_loop, std::string_view _url,
deferred_resume(event_loop, BIND_THIS_METHOD(DeferredResume)), deferred_resume(event_loop, BIND_THIS_METHOD(DeferredResume)),
deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)), deferred_seek(event_loop, BIND_THIS_METHOD(DeferredSeek)),
allocation(_buffer_size), allocation(_buffer_size),
buffer(&allocation.front(), allocation.size()),
resume_at(_resume_at) resume_at(_resume_at)
{ {
allocation.SetName("InputStream"); allocation.SetName("InputStream");

View File

@ -23,7 +23,7 @@ class AsyncInputStream : public InputStream {
HugeArray<std::byte> allocation; HugeArray<std::byte> allocation;
CircularBuffer<std::byte> buffer; CircularBuffer<std::byte> buffer{allocation};
const size_t resume_at; const size_t resume_at;
enum class SeekState : uint_least8_t { enum class SeekState : uint_least8_t {

View File

@ -16,8 +16,7 @@ ThreadInputStream::ThreadInputStream(const char *_plugin,
:InputStream(_uri, _mutex), :InputStream(_uri, _mutex),
plugin(_plugin), plugin(_plugin),
thread(BIND_THIS_METHOD(ThreadFunc)), thread(BIND_THIS_METHOD(ThreadFunc)),
allocation(_buffer_size), allocation(_buffer_size)
buffer(&allocation.front(), allocation.size())
{ {
allocation.SetName("InputStream"); allocation.SetName("InputStream");
allocation.ForkCow(false); allocation.ForkCow(false);

View File

@ -43,7 +43,7 @@ class ThreadInputStream : public InputStream {
HugeArray<std::byte> allocation; HugeArray<std::byte> allocation;
CircularBuffer<std::byte> buffer; CircularBuffer<std::byte> buffer{allocation};
/** /**
* Shall the stream be closed? * Shall the stream be closed?

View File

@ -37,19 +37,18 @@ protected:
*/ */
size_type tail = 0; size_type tail = 0;
const size_type capacity; const std::span<T> buffer;
const pointer data;
public: public:
constexpr CircularBuffer(pointer _data, size_type _capacity) noexcept explicit constexpr CircularBuffer(Range _buffer) noexcept
:capacity(_capacity), data(_data) {} :buffer(_buffer) {}
CircularBuffer(const CircularBuffer &other) = delete; CircularBuffer(const CircularBuffer &other) = delete;
CircularBuffer &operator=(const CircularBuffer &other) = delete; CircularBuffer &operator=(const CircularBuffer &other) = delete;
protected: protected:
constexpr size_type Next(size_type i) const noexcept { constexpr size_type Next(size_type i) const noexcept {
return i + 1 == capacity return i + 1 == buffer.size()
? 0 ? 0
: i + 1; : i + 1;
} }
@ -60,7 +59,7 @@ public:
} }
constexpr size_type GetCapacity() const noexcept { constexpr size_type GetCapacity() const noexcept {
return capacity; return buffer.size();
} }
constexpr bool empty() const noexcept { constexpr bool empty() const noexcept {
@ -77,7 +76,7 @@ public:
constexpr size_type GetSize() const noexcept { constexpr size_type GetSize() const noexcept {
return head <= tail return head <= tail
? tail - head ? tail - head
: capacity - head + tail; : buffer.size() - head + tail;
} }
/** /**
@ -87,7 +86,7 @@ public:
constexpr size_type GetSpace() const noexcept { constexpr size_type GetSpace() const noexcept {
/* space = capacity - size - 1 */ /* space = capacity - size - 1 */
return (head <= tail return (head <= tail
? capacity - tail + head ? buffer.size() - tail + head
: head - tail) : head - tail)
- 1; - 1;
} }
@ -97,17 +96,17 @@ public:
* When you are finished, call Append(). * When you are finished, call Append().
*/ */
constexpr Range Write() noexcept { constexpr Range Write() noexcept {
assert(head < capacity); assert(head < buffer.size());
assert(tail < capacity); assert(tail < buffer.size());
size_type end = tail < head size_type end = tail < head
? head - 1 ? head - 1
/* the "head==0" is there so we don't write /* the "head==0" is there so we don't write
the last cell, as this situation cannot be the last cell, as this situation cannot be
represented by head/tail */ represented by head/tail */
: capacity - (head == 0); : buffer.size() - (head == 0);
return Range(data + tail, end - tail); return buffer.subspan(tail, end - tail);
} }
/** /**
@ -115,15 +114,15 @@ public:
* to the buffer returned by Write(). * to the buffer returned by Write().
*/ */
constexpr void Append(size_type n) noexcept { constexpr void Append(size_type n) noexcept {
assert(head < capacity); assert(head < buffer.size());
assert(tail < capacity); assert(tail < buffer.size());
assert(n < capacity); assert(n < buffer.size());
assert(tail + n <= capacity); assert(tail + n <= buffer.size());
assert(head <= tail || tail + n < head); assert(head <= tail || tail + n < head);
tail += n; tail += n;
if (tail == capacity) { if (tail == buffer.size()) {
assert(head > 0); assert(head > 0);
tail = 0; tail = 0;
} }
@ -134,24 +133,24 @@ public:
* writable, to allow modifications while parsing. * writable, to allow modifications while parsing.
*/ */
constexpr Range Read() noexcept { constexpr Range Read() noexcept {
assert(head < capacity); assert(head < buffer.size());
assert(tail < capacity); assert(tail < buffer.size());
return Range(data + head, (tail < head ? capacity : tail) - head); return buffer.subspan(head, (tail < head ? buffer.size() : tail) - head);
} }
/** /**
* Marks a chunk as consumed. * Marks a chunk as consumed.
*/ */
constexpr void Consume(size_type n) noexcept { constexpr void Consume(size_type n) noexcept {
assert(head < capacity); assert(head < buffer.size());
assert(tail < capacity); assert(tail < buffer.size());
assert(n < capacity); assert(n < buffer.size());
assert(head + n <= capacity); assert(head + n <= buffer.size());
assert(tail < head || head + n <= tail); assert(tail < head || head + n <= tail);
head += n; head += n;
if (head == capacity) if (head == buffer.size())
head = 0; head = 0;
} }
}; };

View File

@ -10,7 +10,7 @@ TEST(CircularBuffer, Basic)
{ {
constexpr size_t N = 8; constexpr size_t N = 8;
int data[N]; int data[N];
CircularBuffer<int> buffer(data, N); CircularBuffer<int> buffer{data};
EXPECT_EQ(size_t(N), buffer.GetCapacity()); EXPECT_EQ(size_t(N), buffer.GetCapacity());