util/CircularBuffer: use std::span
This commit is contained in:
parent
b37c031fd1
commit
b50173ae8b
|
@ -117,9 +117,9 @@ AsyncInputStream::Seek(std::unique_lock<Mutex> &lock,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const size_t nbytes =
|
const size_t nbytes =
|
||||||
new_offset - offset < (offset_type)r.size
|
new_offset - offset < (offset_type)r.size()
|
||||||
? new_offset - offset
|
? new_offset - offset
|
||||||
: r.size;
|
: r.size();
|
||||||
|
|
||||||
buffer.Consume(nbytes);
|
buffer.Consume(nbytes);
|
||||||
offset += nbytes;
|
offset += nbytes;
|
||||||
|
@ -193,8 +193,8 @@ AsyncInputStream::Read(std::unique_lock<Mutex> &lock,
|
||||||
cond_handler.cond.wait(lock);
|
cond_handler.cond.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t nbytes = std::min(read_size, r.size);
|
const size_t nbytes = std::min(read_size, r.size());
|
||||||
memcpy(ptr, r.data, nbytes);
|
memcpy(ptr, r.data(), nbytes);
|
||||||
buffer.Consume(nbytes);
|
buffer.Consume(nbytes);
|
||||||
|
|
||||||
offset += (offset_type)nbytes;
|
offset += (offset_type)nbytes;
|
||||||
|
@ -222,17 +222,17 @@ AsyncInputStream::AppendToBuffer(const void *data, size_t append_size) noexcept
|
||||||
auto w = buffer.Write();
|
auto w = buffer.Write();
|
||||||
assert(!w.empty());
|
assert(!w.empty());
|
||||||
|
|
||||||
size_t nbytes = std::min(w.size, append_size);
|
size_t nbytes = std::min(w.size(), append_size);
|
||||||
memcpy(w.data, data, nbytes);
|
memcpy(w.data(), data, nbytes);
|
||||||
buffer.Append(nbytes);
|
buffer.Append(nbytes);
|
||||||
|
|
||||||
const size_t remaining = append_size - nbytes;
|
const size_t remaining = append_size - nbytes;
|
||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
w = buffer.Write();
|
w = buffer.Write();
|
||||||
assert(!w.empty());
|
assert(!w.empty());
|
||||||
assert(w.size >= remaining);
|
assert(w.size() >= remaining);
|
||||||
|
|
||||||
memcpy(w.data, (const uint8_t *)data + nbytes, remaining);
|
memcpy(w.data(), (const uint8_t *)data + nbytes, remaining);
|
||||||
buffer.Append(remaining);
|
buffer.Append(remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ ThreadInputStream::ThreadFunc() noexcept
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
nbytes = ThreadRead(w.data, w.size);
|
nbytes = ThreadRead(w.data(), w.size());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
postponed_exception = std::current_exception();
|
postponed_exception = std::current_exception();
|
||||||
InvokeOnAvailable();
|
InvokeOnAvailable();
|
||||||
|
@ -145,8 +145,8 @@ ThreadInputStream::Read(std::unique_lock<Mutex> &lock,
|
||||||
|
|
||||||
auto r = buffer.Read();
|
auto r = buffer.Read();
|
||||||
if (!r.empty()) {
|
if (!r.empty()) {
|
||||||
size_t nbytes = std::min(read_size, r.size);
|
size_t nbytes = std::min(read_size, r.size());
|
||||||
memcpy(ptr, r.data, nbytes);
|
memcpy(ptr, r.data(), nbytes);
|
||||||
buffer.Consume(nbytes);
|
buffer.Consume(nbytes);
|
||||||
wake_cond.notify_all();
|
wake_cond.notify_all();
|
||||||
offset += nbytes;
|
offset += nbytes;
|
||||||
|
|
|
@ -240,7 +240,7 @@ AlsaInputStream::DispatchSockets() noexcept
|
||||||
const std::scoped_lock<Mutex> protect(mutex);
|
const std::scoped_lock<Mutex> protect(mutex);
|
||||||
|
|
||||||
auto w = PrepareWriteBuffer();
|
auto w = PrepareWriteBuffer();
|
||||||
const snd_pcm_uframes_t w_frames = w.size / frame_size;
|
const snd_pcm_uframes_t w_frames = w.size() / frame_size;
|
||||||
if (w_frames == 0) {
|
if (w_frames == 0) {
|
||||||
/* buffer is full */
|
/* buffer is full */
|
||||||
Pause();
|
Pause();
|
||||||
|
@ -249,7 +249,7 @@ AlsaInputStream::DispatchSockets() noexcept
|
||||||
|
|
||||||
snd_pcm_sframes_t n_frames;
|
snd_pcm_sframes_t n_frames;
|
||||||
while ((n_frames = snd_pcm_readi(capture_handle,
|
while ((n_frames = snd_pcm_readi(capture_handle,
|
||||||
w.data, w_frames)) < 0) {
|
w.data(), w_frames)) < 0) {
|
||||||
if (n_frames == -EAGAIN)
|
if (n_frames == -EAGAIN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ UringInputStream::SubmitRead() noexcept
|
||||||
|
|
||||||
read_operation = std::make_unique<Uring::ReadOperation>();
|
read_operation = std::make_unique<Uring::ReadOperation>();
|
||||||
read_operation->Start(uring, fd, next_offset,
|
read_operation->Start(uring, fd, next_offset,
|
||||||
std::min(w.size, URING_MAX_READ),
|
std::min(w.size(), URING_MAX_READ),
|
||||||
*this);
|
*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +158,8 @@ UringInputStream::OnRead(std::unique_ptr<std::byte[]> data,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto w = PrepareWriteBuffer();
|
auto w = PrepareWriteBuffer();
|
||||||
assert(w.size >= nbytes);
|
assert(w.size() >= nbytes);
|
||||||
memcpy(w.data, data.get(), nbytes);
|
memcpy(w.data(), data.get(), nbytes);
|
||||||
CommitWriteBuffer(nbytes);
|
CommitWriteBuffer(nbytes);
|
||||||
next_offset += nbytes;
|
next_offset += nbytes;
|
||||||
SubmitRead();
|
SubmitRead();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Max Kellermann <max.kellermann@gmail.com>
|
* Copyright 2014-2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -27,13 +27,11 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CIRCULAR_BUFFER_HPP
|
#pragma once
|
||||||
#define CIRCULAR_BUFFER_HPP
|
|
||||||
|
|
||||||
#include "WritableBuffer.hxx"
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A circular buffer.
|
* A circular buffer.
|
||||||
|
@ -50,7 +48,7 @@
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class CircularBuffer {
|
class CircularBuffer {
|
||||||
public:
|
public:
|
||||||
typedef WritableBuffer<T> Range;
|
using Range = std::span<T>;
|
||||||
typedef typename Range::pointer pointer;
|
typedef typename Range::pointer pointer;
|
||||||
typedef typename Range::size_type size_type;
|
typedef typename Range::size_type size_type;
|
||||||
|
|
||||||
|
@ -182,5 +180,3 @@ public:
|
||||||
head = 0;
|
head = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_EQ(size_t(7), buffer.GetSpace());
|
EXPECT_EQ(size_t(7), buffer.GetSpace());
|
||||||
EXPECT_TRUE(buffer.Read().empty());
|
EXPECT_TRUE(buffer.Read().empty());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[0], buffer.Write().data);
|
EXPECT_EQ(&data[0], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(7), buffer.Write().size);
|
EXPECT_EQ(size_t(7), buffer.Write().size());
|
||||||
|
|
||||||
/* append one element */
|
/* append one element */
|
||||||
/* [O......X] */
|
/* [O......X] */
|
||||||
|
@ -35,11 +35,11 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(1), buffer.GetSize());
|
EXPECT_EQ(size_t(1), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(6), buffer.GetSpace());
|
EXPECT_EQ(size_t(6), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(1), buffer.Read().size);
|
EXPECT_EQ(size_t(1), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[0], buffer.Read().data);
|
EXPECT_EQ(&data[0], buffer.Read().data());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[1], buffer.Write().data);
|
EXPECT_EQ(&data[1], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(6), buffer.Write().size);
|
EXPECT_EQ(size_t(6), buffer.Write().size());
|
||||||
|
|
||||||
/* append 6 elements, buffer is now full */
|
/* append 6 elements, buffer is now full */
|
||||||
/* [OOOOOOOX] */
|
/* [OOOOOOOX] */
|
||||||
|
@ -49,8 +49,8 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(7), buffer.GetSize());
|
EXPECT_EQ(size_t(7), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(7), buffer.Read().size);
|
EXPECT_EQ(size_t(7), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[0], buffer.Read().data);
|
EXPECT_EQ(&data[0], buffer.Read().data());
|
||||||
EXPECT_TRUE(buffer.Write().empty());
|
EXPECT_TRUE(buffer.Write().empty());
|
||||||
|
|
||||||
/* consume [0]; can append one at [7] */
|
/* consume [0]; can append one at [7] */
|
||||||
|
@ -61,11 +61,11 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(6), buffer.GetSize());
|
EXPECT_EQ(size_t(6), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(1), buffer.GetSpace());
|
EXPECT_EQ(size_t(1), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(6), buffer.Read().size);
|
EXPECT_EQ(size_t(6), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[1], buffer.Read().data);
|
EXPECT_EQ(&data[1], buffer.Read().data());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[7], buffer.Write().data);
|
EXPECT_EQ(&data[7], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(1), buffer.Write().size);
|
EXPECT_EQ(size_t(1), buffer.Write().size());
|
||||||
|
|
||||||
/* append one element; [0] is still empty but cannot
|
/* append one element; [0] is still empty but cannot
|
||||||
be written to because head==1 */
|
be written to because head==1 */
|
||||||
|
@ -76,8 +76,8 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(7), buffer.GetSize());
|
EXPECT_EQ(size_t(7), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(7), buffer.Read().size);
|
EXPECT_EQ(size_t(7), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[1], buffer.Read().data);
|
EXPECT_EQ(&data[1], buffer.Read().data());
|
||||||
EXPECT_TRUE(buffer.Write().empty());
|
EXPECT_TRUE(buffer.Write().empty());
|
||||||
|
|
||||||
/* consume [1..3]; can append [0..2] */
|
/* consume [1..3]; can append [0..2] */
|
||||||
|
@ -88,11 +88,11 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(4), buffer.GetSize());
|
EXPECT_EQ(size_t(4), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(3), buffer.GetSpace());
|
EXPECT_EQ(size_t(3), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(4), buffer.Read().size);
|
EXPECT_EQ(size_t(4), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[4], buffer.Read().data);
|
EXPECT_EQ(&data[4], buffer.Read().data());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[0], buffer.Write().data);
|
EXPECT_EQ(&data[0], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(3), buffer.Write().size);
|
EXPECT_EQ(size_t(3), buffer.Write().size());
|
||||||
|
|
||||||
/* append [0..1] */
|
/* append [0..1] */
|
||||||
/* [OO.XOOOO] */
|
/* [OO.XOOOO] */
|
||||||
|
@ -102,11 +102,11 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(6), buffer.GetSize());
|
EXPECT_EQ(size_t(6), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(1), buffer.GetSpace());
|
EXPECT_EQ(size_t(1), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(4), buffer.Read().size);
|
EXPECT_EQ(size_t(4), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[4], buffer.Read().data);
|
EXPECT_EQ(&data[4], buffer.Read().data());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[2], buffer.Write().data);
|
EXPECT_EQ(&data[2], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(1), buffer.Write().size);
|
EXPECT_EQ(size_t(1), buffer.Write().size());
|
||||||
|
|
||||||
/* append [2] */
|
/* append [2] */
|
||||||
/* [OOOXOOOO] */
|
/* [OOOXOOOO] */
|
||||||
|
@ -116,8 +116,8 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(7), buffer.GetSize());
|
EXPECT_EQ(size_t(7), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
EXPECT_EQ(size_t(0), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(4), buffer.Read().size);
|
EXPECT_EQ(size_t(4), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[4], buffer.Read().data);
|
EXPECT_EQ(&data[4], buffer.Read().data());
|
||||||
EXPECT_TRUE(buffer.Write().empty());
|
EXPECT_TRUE(buffer.Write().empty());
|
||||||
|
|
||||||
/* consume [4..7] */
|
/* consume [4..7] */
|
||||||
|
@ -128,11 +128,11 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_FALSE(buffer.Read().empty());
|
EXPECT_FALSE(buffer.Read().empty());
|
||||||
EXPECT_EQ(size_t(3), buffer.GetSize());
|
EXPECT_EQ(size_t(3), buffer.GetSize());
|
||||||
EXPECT_EQ(size_t(4), buffer.GetSpace());
|
EXPECT_EQ(size_t(4), buffer.GetSpace());
|
||||||
EXPECT_EQ(size_t(3), buffer.Read().size);
|
EXPECT_EQ(size_t(3), buffer.Read().size());
|
||||||
EXPECT_EQ(&data[0], buffer.Read().data);
|
EXPECT_EQ(&data[0], buffer.Read().data());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[3], buffer.Write().data);
|
EXPECT_EQ(&data[3], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(4), buffer.Write().size);
|
EXPECT_EQ(size_t(4), buffer.Write().size());
|
||||||
|
|
||||||
/* consume [0..2]; after that, we can only write 5,
|
/* consume [0..2]; after that, we can only write 5,
|
||||||
because the CircularBuffer class doesn't have
|
because the CircularBuffer class doesn't have
|
||||||
|
@ -145,6 +145,6 @@ TEST(CircularBuffer, Basic)
|
||||||
EXPECT_EQ(size_t(7), buffer.GetSpace());
|
EXPECT_EQ(size_t(7), buffer.GetSpace());
|
||||||
EXPECT_TRUE(buffer.Read().empty());
|
EXPECT_TRUE(buffer.Read().empty());
|
||||||
EXPECT_FALSE(buffer.Write().empty());
|
EXPECT_FALSE(buffer.Write().empty());
|
||||||
EXPECT_EQ(&data[3], buffer.Write().data);
|
EXPECT_EQ(&data[3], buffer.Write().data());
|
||||||
EXPECT_EQ(size_t(5), buffer.Write().size);
|
EXPECT_EQ(size_t(5), buffer.Write().size());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue