Skip to main content

o3/buffer/
mod.rs

1use std::{convert, num, ops};
2
3use storage::{provided, range};
4use write::consume;
5
6use crate::{buffer::pool::owners, mem::rc};
7
8pub mod raw;
9
10pub mod bytes;
11pub mod hold;
12pub mod pool;
13pub mod resident;
14pub mod segments;
15pub mod storage;
16pub mod write;
17
18/// A range whose bounds were validated against one immutably borrowed source.
19/// The source borrow prevents mutation while the view is inspected or retained.
20/// Inspection and narrowing do not allocate, copy, or retain an owner.
21#[must_use]
22#[repr(C)]
23pub struct View<'source, S: ?Sized> {
24    source: &'source S,
25    bytes: &'source [u8],
26}
27
28impl<S: ?Sized> Copy for View<'_, S> {}
29
30impl<S: ?Sized> Clone for View<'_, S> {
31    fn clone(&self) -> Self {
32        *self
33    }
34}
35
36impl<'source, S: ?Sized> View<'source, S> {
37    pub fn as_slice(&self) -> &'source [u8] {
38        self.bytes
39    }
40
41    pub fn is_empty(&self) -> bool {
42        self.bytes.is_empty()
43    }
44
45    pub fn len(&self) -> usize {
46        self.bytes.len()
47    }
48
49    pub fn select(&self, bytes: &[u8]) -> Option<View<'source, S>> {
50        let range: ops::Range<usize> = self.bytes.subslice_range(bytes)?.into();
51        // SAFETY: containment proved this exact range of the retained source;
52        // reconstructing its borrow preserves the source lifetime and provenance.
53        Some(Self {
54            source: self.source,
55            bytes: unsafe { self.bytes.get_unchecked(range) },
56        })
57    }
58
59    pub fn get(&self, range: ops::Range<usize>) -> Option<View<'source, S>> {
60        let bytes = self.bytes.get(range)?;
61        Some(View {
62            source: self.source,
63            bytes,
64        })
65    }
66
67    pub fn try_get(&self, range: ops::Range<usize>) -> Result<Self, range::Error> {
68        let bytes = self.bytes.try_get(range)?;
69        Ok(Self {
70            source: self.source,
71            bytes,
72        })
73    }
74
75    /// Borrows the complete initialized source without retaining or copying it.
76    pub fn new(source: &'source S) -> Self
77    where
78        S: AsRef<[u8]>,
79    {
80        Self {
81            source,
82            bytes: source.as_ref(),
83        }
84    }
85}
86
87impl<S: segments::Seal> View<'_, S> {
88    /// Retains this already-validated range without allocating or copying.
89    pub fn try_retain(self) -> Result<S, rc::Error> {
90        use storage::regions::NonEmpty;
91
92        let Some(view) = NonEmpty::new(&self) else {
93            return Ok(S::EMPTY);
94        };
95        S::try_share(view).map(segments::Item::into_inner)
96    }
97}
98
99impl View<'_, resident::Shared<'_>> {
100    /// Retains this validated range when its existing owner is independent.
101    /// A scoped owner returns `None` without retaining or copying its bytes.
102    pub fn try_own(self) -> Result<Option<storage::Shared>, rc::Error> {
103        if self.is_empty() {
104            return Ok(Some(storage::Shared::new()));
105        }
106        let owner = match self.source.region.owner() {
107            resident::State::Owned(owner) => Some(owner.try_clone()?),
108            resident::State::Static => None,
109            resident::State::Slice
110            | resident::State::Resident(_)
111            | resident::State::Accounted(_)
112            | resident::State::Provided(_) => return Ok(None),
113        };
114        // SAFETY: this view retains the exact source borrow and validated slice;
115        // the selected independent edge keeps that same immutable extent live.
116        Ok(Some(unsafe {
117            storage::Shared::assume(self.as_slice(), owner)
118        }))
119    }
120}
121
122const _: () = assert!(size_of::<View<'static, storage::Shared>>() == 3 * size_of::<usize>());
123
124impl<S: ?Sized> consume::Consume for View<'_, S> {
125    fn remaining(&self) -> usize {
126        self.bytes.len()
127    }
128    fn try_consume(&mut self, amount: usize) -> Result<(), consume::Error> {
129        raw::Selection::try_new(self, amount).map(raw::Selection::consume)
130    }
131
132    fn consume_max(&mut self, max: usize) -> usize {
133        raw::Store::advance_max(self, max)
134    }
135}
136
137impl<S: ?Sized> AsRef<[u8]> for View<'_, S> {
138    fn as_ref(&self) -> &[u8] {
139        self.bytes
140    }
141}
142
143impl<'input, S: ?Sized> Read<'input> for View<'input, S> {
144    fn as_slice(&self) -> &'input [u8] {
145        self.bytes
146    }
147
148    fn try_split<const N: usize>(mut self) -> Result<(&'input [u8; N], Self), consume::Error> {
149        let (head, tail) = Read::try_split(self.bytes)?;
150        self.bytes = tail;
151        Ok((head, self))
152    }
153}
154
155/// Payload backing capacity retained by this owner, excluding metadata and padding.
156/// Borrowed and static bytes retain zero bytes.
157pub trait Residency {
158    fn resident(&self) -> usize;
159}
160
161impl<L> Residency for pool::Span<owners::Plain<L>, pool::Owned, pool::Frozen> {
162    fn resident(&self) -> usize {
163        self.capacity().get() as usize
164    }
165}
166
167impl<L> Residency for pool::Cursor<L> {
168    fn resident(&self) -> usize {
169        self.len() + self.spare_len()
170    }
171}
172
173impl Residency for Vec<u8> {
174    fn resident(&self) -> usize {
175        self.capacity()
176    }
177}
178
179impl<const CAP: usize, L> Residency for storage::inline::Bytes<CAP, L> {
180    fn resident(&self) -> usize {
181        CAP
182    }
183}
184
185impl Residency for &[u8] {
186    /// A borrowed slice retains no complete backing allocation of its own.
187    fn resident(&self) -> usize {
188        0
189    }
190}
191
192pub const BLOCK_CAPACITY: u32 = 64 * 1024;
193
194fn is_within(range: &ops::Range<usize>, len: usize) -> bool {
195    range.start <= range.end && range.end <= len
196}
197
198/// One validated byte range retaining its original source borrow.
199pub trait Read<'input>: Sized {
200    fn as_slice(&self) -> &'input [u8];
201    fn try_split<const N: usize>(self) -> Result<(&'input [u8; N], Self), consume::Error>;
202}
203
204impl<'input> Read<'input> for convert::Infallible {
205    fn as_slice(&self) -> &'input [u8] {
206        match *self {}
207    }
208
209    fn try_split<const N: usize>(self) -> Result<(&'input [u8; N], Self), consume::Error> {
210        match self {}
211    }
212}
213
214impl<'input> Read<'input> for &'input [u8] {
215    fn as_slice(&self) -> &'input [u8] {
216        self
217    }
218
219    fn try_split<const N: usize>(self) -> Result<(&'input [u8; N], Self), consume::Error> {
220        self.split_first_chunk::<N>().ok_or_else(|| {
221            consume::Error::new(
222                num::NonZero::<usize>::MIN.saturating_add(N.saturating_sub(1)),
223                self.len(),
224            )
225        })
226    }
227}
228
229pub trait Source: Unpin {
230    type View<'input>: Read<'input>
231    where
232        Self: 'input;
233
234    fn remaining(&self) -> usize;
235
236    fn is_empty(&self) -> bool {
237        self.remaining() == 0
238    }
239}
240
241pub trait Cursor: Source + AsRef<[u8]> {
242    /// Validates a range once and retains its original source borrow.
243    fn try_get<'input>(
244        &'input self,
245        range: ops::Range<usize>,
246    ) -> Result<Self::View<'input>, range::Error>;
247}
248
249impl Source for [u8] {
250    type View<'input> = &'input [u8];
251
252    fn remaining(&self) -> usize {
253        self.len()
254    }
255}
256
257impl Cursor for [u8] {
258    #[inline]
259    fn try_get<'input>(
260        &'input self,
261        range: ops::Range<usize>,
262    ) -> Result<Self::View<'input>, range::Error> {
263        self.get(range.clone())
264            .ok_or_else(|| range::Error::new(range, self.len()))
265    }
266}
267
268pub trait Complete: Cursor {
269    fn view(&self) -> Self::View<'_>;
270}
271
272impl<O: Unpin> Source for storage::Shared<O> {
273    type View<'input>
274        = View<'input, Self>
275    where
276        Self: 'input;
277    fn remaining(&self) -> usize {
278        self.len()
279    }
280}
281impl<O: Unpin> Cursor for storage::Shared<O> {
282    fn try_get<'input>(
283        &'input self,
284        range: ops::Range<usize>,
285    ) -> Result<Self::View<'input>, range::Error> {
286        self.view().try_get(range)
287    }
288}
289impl<O: Unpin> Complete for storage::Shared<O> {
290    fn view(&self) -> Self::View<'_> {
291        View::new(self)
292    }
293}
294
295impl<'d> View<'_, storage::Shared<Option<provided::Account<'d>>>> {
296    /// Retains the proved extent using its existing registration, without admission.
297    pub fn try_retain(self) -> Result<storage::Shared<Option<provided::Account<'d>>>, rc::Error> {
298        if self.is_empty() {
299            return Ok(storage::Shared::<Option<provided::Account<'d>>>::new());
300        }
301        self.try_clone()
302    }
303}
304const _: () = {
305    assert!(
306        size_of::<storage::Shared<Option<provided::Account<'static>>>>() == 3 * size_of::<usize>()
307    );
308    assert!(
309        size_of::<Option<storage::Shared<Option<provided::Account<'static>>>>>()
310            == 3 * size_of::<usize>()
311    );
312};