Skip to main content

o3/buffer/storage/regions/
mod.rs

1use std::{num::NonZero, ops, ptr};
2
3pub(in crate::buffer) use nonempty::NonEmpty;
4pub(in crate::buffer) use prefix::Prefix;
5pub(in crate::buffer) use tag::Header;
6pub use tag::Tag;
7pub(in crate::buffer) use value::{Complete, Init};
8
9use crate::{
10    buffer,
11    buffer::{
12        pool,
13        pool::owners,
14        resident,
15        storage::{alloc, provided, range, regions},
16    },
17    mem::rc,
18};
19
20/// # Safety
21/// The sources retain immutable bytes whose complete sum equals the capacity.
22/// Their copy operation initializes that complete admitted destination exactly once.
23pub(in crate::buffer) unsafe trait Initialize: Sized {
24    fn parts(&self) -> (NonZero<u32>, impl crate::buffer::raw::SliceExt);
25
26    #[inline(always)]
27    fn try_init<P: crate::buffer::raw::Policy>(
28        self,
29        seed: P,
30    ) -> Result<regions::Init<P>, alloc::Error<P::Failure>> {
31        use crate::buffer::raw::SliceExt as _;
32
33        let (capacity, sources) = self.parts();
34        let mut heap = crate::buffer::raw::Heap::try_new(seed, capacity)?;
35        // SAFETY: the retained sources exactly fill this fresh disjoint allocation.
36        unsafe { sources.copy_to(heap.as_mut_ptr().cast()) };
37        // SAFETY: copying every retained source initialized the complete allocation.
38        Ok(unsafe { regions::Init::new(heap) })
39    }
40}
41
42// SAFETY: admission pairs every retained slice with their exact nonzero byte sum.
43unsafe impl<const N: usize> Initialize for crate::buffer::raw::Slices<'_, N> {
44    fn parts(&self) -> (NonZero<u32>, impl crate::buffer::raw::SliceExt) {
45        (self.len(), self.slices())
46    }
47}
48
49mod nonempty;
50mod prefix;
51mod tag;
52mod value;
53
54pub(in crate::buffer) mod retained {
55    use super::{Extent, Shared, resident};
56    use crate::buffer::{self, raw, storage};
57
58    #[derive(Debug)]
59    enum Owner<'d> {
60        Unique(raw::Heap<resident::Budget<'d>>),
61        Shared(resident::State<'d>),
62    }
63
64    #[derive(Debug)]
65    #[repr(transparent)]
66    pub struct Retained<'d>(Shared<Owner<'d>>);
67
68    impl<'d> From<storage::Owned<resident::Budget<'d>>> for Retained<'d> {
69        #[inline]
70        fn from(value: storage::Owned<resident::Budget<'d>>) -> Self {
71            let bytes = Extent::from_bytes(value.as_slice());
72            let owner = match value.allocation {
73                Some(heap) => Owner::Unique(heap),
74                None => Owner::Shared(resident::State::Slice),
75            };
76            Self(Shared { owner, bytes })
77        }
78    }
79
80    impl<'d> From<resident::Shared<'d>> for Retained<'d> {
81        fn from(value: resident::Shared<'d>) -> Self {
82            let Shared { owner, bytes } = value.region;
83            Self(Shared {
84                owner: Owner::Shared(owner),
85                bytes,
86            })
87        }
88    }
89
90    impl<'d> Retained<'d> {
91        pub fn as_slice(&self) -> &[u8] {
92            self.0.as_slice()
93        }
94
95        pub fn into_shared(self) -> resident::Shared<'d> {
96            let Shared { owner, bytes } = self.0;
97            let owner = match owner {
98                Owner::Unique(heap) => resident::State::Resident(heap.into_shared()),
99                Owner::Shared(owner) => owner,
100            };
101            resident::Shared {
102                region: Shared { owner, bytes },
103            }
104        }
105    }
106
107    impl buffer::Residency for Retained<'_> {
108        #[inline]
109        fn resident(&self) -> usize {
110            match &self.0.owner {
111                Owner::Unique(heap) => heap.capacity().get() as usize,
112                Owner::Shared(owner) => owner.resident(),
113            }
114        }
115    }
116
117    const _: () = {
118        assert!(size_of::<Retained<'static>>() == size_of::<resident::Shared<'static>>());
119        assert!(size_of::<Option<Retained<'static>>>() == size_of::<Retained<'static>>());
120    };
121}
122
123/// Opaque byte coordinates, usable only under an exact backing-owner proof.
124/// Public raw contracts may borrow this representation; it exposes no safe views.
125#[derive(Debug)]
126#[repr(transparent)]
127pub struct Extent(ptr::NonNull<[u8]>);
128
129/// Immutable initialized bytes inseparably paired with their retaining owner.
130#[derive(Debug)]
131#[repr(C)]
132pub struct Shared<O = Option<regions::Tag>> {
133    owner: O,
134    bytes: Extent,
135}
136
137/// Completes consumption according to the actual backing's empty-owner policy.
138pub trait End: Sized {
139    const EMPTY: Option<Self>;
140}
141
142impl regions::Extent {
143    pub(in crate::buffer) const EMPTY: Self = Self(ptr::NonNull::slice_from_raw_parts(
144        ptr::NonNull::dangling(),
145        0,
146    ));
147
148    /// # Safety
149    /// The inclusive address range from `ptr` through `ptr + len` must not wrap.
150    /// The allocation need not remain live; coordinates alone expose no bytes.
151    pub(in crate::buffer) const unsafe fn new(ptr: ptr::NonNull<u8>, len: usize) -> Self {
152        Self(ptr::NonNull::slice_from_raw_parts(ptr, len))
153    }
154
155    pub(in crate::buffer) fn from_bytes(bytes: &[u8]) -> Self {
156        Self(ptr::NonNull::from(bytes))
157    }
158
159    pub(in crate::buffer) const fn len(&self) -> usize {
160        self.0.len()
161    }
162
163    /// # Safety
164    /// The range must be ordered and contained in this exact initialized extent,
165    /// proving its length cannot underflow.
166    pub(in crate::buffer) unsafe fn restrict(&self, range: ops::Range<usize>) -> Self {
167        let len = range.end - range.start;
168        let pointer = self.0.cast::<u8>().as_ptr().wrapping_add(range.start);
169        // SAFETY: the caller proves this subrange of the original nonwrapping extent.
170        unsafe { Self::new(ptr::NonNull::new_unchecked(pointer), len) }
171    }
172}
173
174const _: () = assert!(size_of::<regions::Extent>() == 2 * size_of::<usize>());
175
176const _: () = {
177    assert!(size_of::<regions::Shared<Option<regions::Tag>>>() == 3 * size_of::<usize>());
178    assert!(size_of::<Option<regions::Shared<Option<regions::Tag>>>>() == 3 * size_of::<usize>());
179    assert!(
180        size_of::<regions::Shared<owners::Edge<owners::Plain, pool::Borrowed<'static>>>>()
181            == 3 * size_of::<usize>()
182    );
183    assert!(
184        size_of::<Result<regions::Shared<Option<regions::Tag>>, rc::Error>>()
185            == size_of::<regions::Shared<Option<regions::Tag>>>()
186    );
187};
188
189const _: () = assert!(usize::BITS >= 64);
190
191impl<O> regions::Shared<O> {
192    pub(in crate::buffer) const fn empty(owner: O) -> Self {
193        Self {
194            owner,
195            bytes: regions::Extent::EMPTY,
196        }
197    }
198    /// # Safety
199    /// The extent must form one valid initialized immutable slice retained by
200    /// the transferred owner for every region borrow, including after owner moves.
201    pub(in crate::buffer) const unsafe fn from_extent(owner: O, extent: regions::Extent) -> Self {
202        Self {
203            owner,
204            bytes: extent,
205        }
206    }
207    pub(in crate::buffer) const fn owner(&self) -> &O {
208        &self.owner
209    }
210
211    pub fn as_slice(&self) -> &[u8] {
212        // SAFETY: this owner borrow retains the unchanged initialized extent.
213        unsafe { self.bytes.0.as_ref() }
214    }
215
216    /// # Safety
217    /// Every replacement must remain an initialized subrange of this exact
218    /// owner's backing; the owner and its lifetime must remain unchanged.
219    pub(in crate::buffer) unsafe fn extent_mut(&mut self) -> &mut regions::Extent {
220        &mut self.bytes
221    }
222    /// # Safety
223    /// The bounds must select a subrange of the unchanged current extent.
224    pub(in crate::buffer) unsafe fn restrict(&mut self, bounds: ops::Range<usize>) {
225        // SAFETY: the caller proves the range; the paired owner remains unchanged.
226        self.bytes = unsafe { self.bytes.restrict(bounds) };
227    }
228    pub fn try_restrict(&mut self, visible: ops::Range<usize>) -> Result<(), range::Error>
229    where
230        O: regions::End,
231    {
232        self.bytes = self
233            .as_slice()
234            .get(visible.clone())
235            .map(regions::Extent::from_bytes)
236            .ok_or_else(|| range::Error::new(visible, self.len()))?;
237        if self.is_empty()
238            && let Some(owner) = O::EMPTY
239        {
240            self.owner = owner;
241        }
242        Ok(())
243    }
244}
245
246impl<O: buffer::raw::Retain> regions::Shared<O> {
247    pub fn try_clone(&self) -> Result<Self, rc::Error> {
248        let extent = regions::Extent(self.bytes.0);
249        Ok(Self {
250            owner: self.owner.try_retain()?,
251            bytes: extent,
252        })
253    }
254    /// # Safety
255    /// The slice must be an initialized subrange of this exact region, preserved
256    /// by the source borrow until retaining its owner completes.
257    pub(in crate::buffer) unsafe fn try_view(&self, bytes: &[u8]) -> Result<Self, rc::Error> {
258        Ok(Self {
259            owner: self.owner.try_retain()?,
260            bytes: regions::Extent::from_bytes(bytes),
261        })
262    }
263}
264
265impl regions::Shared<Option<regions::Tag>> {
266    pub fn try_get(&self, range: impl ops::RangeBounds<usize>) -> Result<Option<Self>, rc::Error> {
267        let start = range.start_bound().cloned();
268        if let ops::Bound::Excluded(usize::MAX) = start {
269            return Ok(None);
270        }
271        let bytes = self.as_slice().get((start, range.end_bound().cloned()));
272        drop(range);
273        let Some(bytes) = bytes else {
274            return Ok(None);
275        };
276        if bytes.is_empty() {
277            return Ok(Some(Self::empty(None)));
278        }
279        // SAFETY: checked slicing keeps these bytes within this exact source.
280        unsafe { self.try_view(bytes) }.map(Some)
281    }
282}
283
284impl<O> ops::Deref for regions::Shared<O> {
285    type Target = [u8];
286    fn deref(&self) -> &Self::Target {
287        self.as_slice()
288    }
289}
290
291impl From<regions::Shared<crate::buffer::raw::Rc>> for regions::Shared<Option<regions::Tag>> {
292    fn from(region: regions::Shared<crate::buffer::raw::Rc>) -> Self {
293        Self {
294            owner: Some(regions::Tag::allocation(region.owner)),
295            bytes: region.bytes,
296        }
297    }
298}
299
300impl<L> From<regions::Shared<owners::Edge<owners::Plain<L>>>>
301    for regions::Shared<Option<regions::Tag>>
302{
303    fn from(region: regions::Shared<owners::Edge<owners::Plain<L>>>) -> Self {
304        Self {
305            owner: regions::Tag::pool(region.owner),
306            bytes: region.bytes,
307        }
308    }
309}
310
311impl<'d, L> From<regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>>
312    for regions::Shared<owners::Edge<owners::Plain<L>>>
313{
314    fn from(region: regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>) -> Self {
315        Self {
316            owner: region.owner.into_owned(),
317            bytes: region.bytes,
318        }
319    }
320}
321
322impl<'a: 'd, 'd> From<&'a [u8]> for resident::Shared<'d> {
323    fn from(bytes: &'a [u8]) -> Self {
324        Self {
325            region: regions::Shared {
326                owner: resident::State::Slice,
327                bytes: regions::Extent::from_bytes(bytes),
328            },
329        }
330    }
331}
332
333impl<'d> From<regions::Shared<Option<regions::Tag>>> for resident::Shared<'d> {
334    fn from(region: regions::Shared<Option<regions::Tag>>) -> Self {
335        Self {
336            region: regions::Shared {
337                owner: resident::State::Owned(region.owner),
338                bytes: region.bytes,
339            },
340        }
341    }
342}
343
344impl<'d> From<regions::Shared<crate::buffer::raw::Rc<resident::Budget<'d>>>>
345    for resident::Shared<'d>
346{
347    fn from(region: regions::Shared<crate::buffer::raw::Rc<resident::Budget<'d>>>) -> Self {
348        Self {
349            region: regions::Shared {
350                owner: resident::State::Resident(region.owner),
351                bytes: region.bytes,
352            },
353        }
354    }
355}
356
357impl<'d, L> From<regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>>
358    for resident::Shared<'d>
359{
360    fn from(region: regions::Shared<owners::Edge<owners::Plain<L>, pool::Borrowed<'d>>>) -> Self {
361        match regions::Tag::pool(region.owner) {
362            Some(owner) => Self {
363                region: regions::Shared {
364                    owner: resident::State::Borrowed(owner),
365                    bytes: region.bytes,
366                },
367            },
368            None => Self::new(),
369        }
370    }
371}
372
373impl<'d> From<regions::Shared<Option<provided::Account<'d>>>> for resident::Shared<'d> {
374    fn from(region: regions::Shared<Option<provided::Account<'d>>>) -> Self {
375        match region.owner {
376            Some(owner) => Self {
377                region: regions::Shared {
378                    owner: resident::State::Provided(owner),
379                    bytes: region.bytes,
380                },
381            },
382            None => Self::new(),
383        }
384    }
385}
386
387impl<'d> regions::Shared<resident::State<'d>> {
388    pub(in crate::buffer) fn try_own(
389        mut self,
390    ) -> Result<regions::Shared<Option<regions::Tag>>, Self> {
391        if let resident::State::Resident(owner) = self.owner {
392            self.owner = match owner.try_own() {
393                Ok(owner) => resident::State::Owned(Some(regions::Tag::allocation(owner))),
394                Err(owner) => resident::State::Resident(owner),
395            };
396        }
397        self.try_detach()
398    }
399
400    pub(in crate::buffer) fn try_detach(
401        self,
402    ) -> Result<regions::Shared<Option<regions::Tag>>, Self> {
403        let empty = self.is_empty();
404        match self.owner.try_own(empty) {
405            Ok(owner) => Ok(regions::Shared {
406                owner,
407                bytes: self.bytes,
408            }),
409            Err(owner) => Err(Self {
410                owner,
411                bytes: self.bytes,
412            }),
413        }
414    }
415}