1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//! Buffer types for I/O operations.
//!
//! `IoBuf` and `IoBufMut` store readable/writable cursor state directly in the
//! public handle. Allocation ownership lives in a compact tagged owner
//! reference: runtime-owned heap buffers keep a header inside their own
//! allocation (in front of the data for low-alignment mutable buffers, at the
//! tail for high-alignment ones and adopted vecs), pooled buffers keep their
//! owner record in a per-slot side table owned by the size class,
//! caller-supplied `Vec<u8>` values converted to immutable buffers are adopted
//! into the native heap form when their spare capacity allows (mutable
//! conversions copy to preserve the caller's capacity), and caller-supplied
//! [`Bytes`] values are held zero-copy by a small external owner. This keeps
//! `bytes::Buf` and `bytes::BufMut` hot paths as simple pointer/length
//! arithmetic. `owner.rs` documents the owner model.
//!
//! Throughout this module, "native" means runtime-owned storage whose owner
//! supports zero-copy mutable recovery through [`IoBuf::try_into_mut`]: heap
//! allocations (front or tail header), pooled buffers, and adopted vecs, as
//! opposed to external `Bytes` and `'static` views.
//!
//! # Conversions
//!
//! Every `From` conversion into [`IoBuf`] or [`IoBufs`] is zero-copy: the
//! payload is never copied. Most conversions require at most one small owner
//! allocation. A `Vec<u8>` that cannot host an inline owner may require two
//! small metadata allocations: one for `bytes` shared ownership and one for
//! the external owner. Conversions into [`IoBufMut`] or [`IoBufsMut`] are
//! zero-copy where the source allocation can back a mutable handle and copy
//! otherwise. Each mutable conversion documents which one it is, and
//! conversions out of the handles document their cost on each impl.
//!
//! Because untracked heap buffers embed their owner header in the same
//! allocation, a power-of-two capacity request may land in the allocator's
//! next size bin. Pooled buffers do not pay this: their side-table record
//! keeps the data allocation exactly the class size.
//!
//! Public types:
//! - [`IoBuf`]: Immutable byte buffer
//! - [`IoBufMut`]: Mutable byte buffer
//! - [`IoBufs`]: Container for one or more immutable buffers
//! - [`IoBufsMut`]: Container for one or more mutable buffers
//! - [`BufferPool`]: Pool of reusable, aligned buffers
//! - [`Builder`]: Assembles [`IoBufs`] from inline writes and zero-copy pieces
//!
//! # Examples
//!
//! The core lifecycle: fill a fixed-capacity mutable buffer, freeze it into
//! cheaply cloneable immutable views, and recover the mutable handle (with
//! its spare capacity) once the views are gone:
//!
//! ```
//! use commonware_runtime::{Buf, BufMut, IoBuf, IoBufMut};
//!
//! let mut buf = IoBufMut::with_capacity(8);
//! buf.put_slice(b"abcdef");
//!
//! let frozen: IoBuf = buf.freeze();
//! let head = frozen.slice(..3);
//! assert_eq!(head, b"abc"[..]);
//!
//! // A live view shares the owner, so recovery declines.
//! let frozen = frozen.try_into_mut().unwrap_err();
//! drop(head);
//!
//! // Unique again: the mutable handle returns with its spare capacity.
//! let mut recovered = frozen.try_into_mut().unwrap();
//! assert_eq!(recovered.as_ref(), b"abcdef");
//! assert_eq!(recovered.capacity(), 8);
//! recovered.put_slice(b"gh");
//! ```
//!
//! [`Bytes`]: bytes::Bytes
pub use ;
pub use ;
use CachePadded;
pub use ;
use align_of;
/// Returns the system page size.
///
/// On Unix systems, queries the actual page size via `sysconf`.
/// On WebAssembly, defaults to 4KB.
/// Returns the cache line size for the current architecture.
pub const
/// Panics for cursor or write operations that run past the available region.
///
/// Outlined so the `Buf`/`BufMut` fast paths inline as a compare, a branch,
/// and a memcpy, mirroring the panic helpers in `bytes`.
!
/// Benchmark-only access to internal pool machinery.
///
/// Raw pooled buffers reference owner metadata stored by their freelist.
/// Taking one requires the caller to keep that freelist alive, and returning
/// one requires proof that it came from the target freelist:
///
/// ```compile_fail,E0133
/// use commonware_runtime::iobuf::bench::{Freelist, PooledBuffer};
///
/// fn return_buffer(freelist: &Freelist, buffer: PooledBuffer) {
/// freelist.put(buffer);
/// }
/// ```