20#include "pw_allocator/deallocator.h"
21#include "pw_allocator/internal/control_block.h"
22#include "pw_bytes/span.h"
23#include "pw_containers/dynamic_deque.h"
24#include "pw_preprocessor/compiler.h"
26namespace pw::multibuf::v2::internal {
30enum class Mutability {
49 using size_type = Deque::size_type;
50 using difference_type = Deque::difference_type;
53 static constexpr size_t kMaxSize = ~(1U << 15);
69 const Deque& deque, size_type entries_per_chunk) {
70 return deque.
size() / entries_per_chunk;
76 size_type entries_per_chunk) {
82 size_type chunk, size_type entries_per_chunk) {
88 size_type chunk, size_type entries_per_chunk) {
94 size_type chunk, size_type entries_per_chunk) {
100 size_type chunk, size_type entries_per_chunk, size_type layer) {
106 size_type chunk, size_type entries_per_chunk) {
107 return (chunk + 1) * entries_per_chunk - 1;
111 [[nodiscard]]
static constexpr std::byte*
GetData(
112 const Deque& deque, size_type chunk, size_type entries_per_chunk) {
113 return deque[
data_index(chunk, entries_per_chunk)].data;
120 size_type entries_per_chunk) {
121 return deque[
base_view_index(chunk, entries_per_chunk)].base_view.owned;
128 size_type entries_per_chunk) {
129 return deque[
base_view_index(chunk, entries_per_chunk)].base_view.shared;
135 size_type entries_per_chunk) {
143 const Deque& deque, size_type chunk, size_type entries_per_chunk) {
144 PW_ASSERT(
IsOwned(deque, chunk, entries_per_chunk));
149 [[nodiscard]]
static constexpr allocator::internal::ControlBlock&
152 size_type entries_per_chunk) {
153 PW_ASSERT(
IsShared(deque, chunk, entries_per_chunk));
161 size_type entries_per_chunk,
163 return layer == 1 ? true
164 : deque[
view_index(chunk, entries_per_chunk, layer)]
171 size_type entries_per_chunk) {
173 deque, chunk, entries_per_chunk,
num_layers(entries_per_chunk));
180 size_type entries_per_chunk,
185 : deque[
view_index(chunk, entries_per_chunk, layer)].view.offset;
190 const Deque& deque, size_type chunk, size_type entries_per_chunk) {
192 deque, chunk, entries_per_chunk,
num_layers(entries_per_chunk));
200 size_type entries_per_chunk,
202 return layer == 1 ?
GetOffset(deque, chunk, entries_per_chunk, layer)
203 : (
GetOffset(deque, chunk, entries_per_chunk, layer) -
204 GetOffset(deque, chunk, entries_per_chunk, layer - 1));
210 const Deque& deque, size_type chunk, size_type entries_per_chunk) {
212 deque, chunk, entries_per_chunk,
num_layers(entries_per_chunk));
219 size_type entries_per_chunk,
224 : deque[
view_index(chunk, entries_per_chunk, layer)].view.length;
229 const Deque& deque, size_type chunk, size_type entries_per_chunk) {
231 deque, chunk, entries_per_chunk,
num_layers(entries_per_chunk));
237 size_type entries_per_chunk,
239 std::byte*
data =
GetData(deque, chunk, entries_per_chunk);
240 size_type offset =
GetOffset(deque, chunk, entries_per_chunk, layer);
241 size_type length =
GetLength(deque, chunk, entries_per_chunk, layer);
248 size_type entries_per_chunk) {
250 deque, chunk, entries_per_chunk,
num_layers(entries_per_chunk));
321 static_assert(
sizeof(BaseView) <=
sizeof(
void*));
322 static_assert(
sizeof(View) <=
sizeof(
void*));
Abstract interface for releasing memory.
Definition: deallocator.h:29
Definition: dynamic_deque.h:60
constexpr size_type size() const noexcept
Returns the number of elements in the deque.
Definition: generic_deque.h:69
Describes the entire memory region.
Definition: entry.h:254
size_type owned
Definition: entry.h:260
size_type length
Amount of data from the buffer to present.
Definition: entry.h:263
size_type offset
Starting offset within the buffer of the data to present.
Definition: entry.h:256
size_type shared
Definition: entry.h:267
size_type length
Amount of data from the buffer to present.
Definition: entry.h:283
size_type offset
Starting offset within the buffer of the data to present.
Definition: entry.h:274
size_type sealed
Definition: entry.h:280
size_type boundary
Definition: entry.h:288
static constexpr size_type kBaseViewIndex
Per-chunk index entry that holds the base view of the data.
Definition: entry.h:62
static constexpr size_type kDataIndex
Per-chunk index entry that holds the data pointer.
Definition: entry.h:59
static constexpr size_type num_chunks(const Deque &deque, size_type entries_per_chunk)
Returns the number of chunks in a deque.
Definition: entry.h:68
static constexpr Deallocator & GetDeallocator(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns the deallocator for a chunk, which must be owned.
Definition: entry.h:142
static constexpr bool IsSealed(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns whether the chunk is part of a sealed layer.
Definition: entry.h:133
static constexpr size_type GetRelativeOffset(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Definition: entry.h:209
Deallocator * deallocator
Optional deallocator involved in freeing owned memory.
Definition: entry.h:307
static constexpr size_type kMemoryContextIndex
Per-chunk index entry that holds the deallocator or control block.
Definition: entry.h:56
allocator::internal::ControlBlock * control_block
Optional control block involved in freeing shared memory.
Definition: entry.h:310
std::byte * data
Pointer to memory.
Definition: entry.h:313
static constexpr size_type num_layers(size_type entries_per_chunk)
Definition: entry.h:75
static constexpr size_t kMaxSize
Offset and length must fit in 15 bits.
Definition: entry.h:53
static constexpr ByteSpan GetView(const Deque &deque, size_type chunk, size_type entries_per_chunk, size_type layer)
Returns a view of the visible data length of the chunk at the given layer.
Definition: entry.h:235
static constexpr size_type GetLength(const Deque &deque, size_type chunk, size_type entries_per_chunk, size_type layer)
Returns the length of the given layer of the chunk.
Definition: entry.h:216
static constexpr bool IsBoundary(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns whether the top layer of a chunk represents a fragment boundary.
Definition: entry.h:169
static constexpr bool IsShared(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Definition: entry.h:126
static constexpr size_type GetRelativeOffset(const Deque &deque, size_type chunk, size_type entries_per_chunk, size_type layer)
Definition: entry.h:197
static constexpr size_type GetLength(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns the length of the top layer of the chunk.
Definition: entry.h:228
static constexpr ByteSpan GetView(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns a view of the visible data length of the chunk at the top layer.
Definition: entry.h:246
static constexpr size_type memory_context_index(size_type chunk, size_type entries_per_chunk)
Returns the index to the data entry of a given chunk.
Definition: entry.h:81
static constexpr size_type GetOffset(const Deque &deque, size_type chunk, size_type entries_per_chunk, size_type layer)
Returns the offset of the given layer of the chunk.
Definition: entry.h:177
static constexpr size_type base_view_index(size_type chunk, size_type entries_per_chunk)
Returns the index to the base view entry of a given chunk.
Definition: entry.h:93
static constexpr size_type top_view_index(size_type chunk, size_type entries_per_chunk)
Returns the index to the top view entry of a given chunk.
Definition: entry.h:105
static constexpr bool IsBoundary(const Deque &deque, size_type chunk, size_type entries_per_chunk, size_type layer)
Returns whether the given layer of a chunk represents a fragment boundary.
Definition: entry.h:159
static constexpr size_type view_index(size_type chunk, size_type entries_per_chunk, size_type layer)
Returns the index to a view entry of a given chunk.
Definition: entry.h:99
static constexpr size_type kMinEntriesPerChunk
Minimum number of entries per chunk.
Definition: entry.h:65
static constexpr size_type GetOffset(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns the offset of the top layer of the chunk.
Definition: entry.h:189
static constexpr std::byte * GetData(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns the memory backing the chunk at the given index.
Definition: entry.h:111
static constexpr allocator::internal::ControlBlock & GetControlBlock(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Returns the control block for a chunk, which must be shared.
Definition: entry.h:150
static constexpr bool IsOwned(const Deque &deque, size_type chunk, size_type entries_per_chunk)
Definition: entry.h:118
static constexpr size_type data_index(size_type chunk, size_type entries_per_chunk)
Returns the index to the data entry of a given chunk.
Definition: entry.h:87