o3/buffer/storage/regions/
mod.rs1use 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
20pub(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 unsafe { sources.copy_to(heap.as_mut_ptr().cast()) };
37 Ok(unsafe { regions::Init::new(heap) })
39 }
40}
41
42unsafe 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#[derive(Debug)]
126#[repr(transparent)]
127pub struct Extent(ptr::NonNull<[u8]>);
128
129#[derive(Debug)]
131#[repr(C)]
132pub struct Shared<O = Option<regions::Tag>> {
133 owner: O,
134 bytes: Extent,
135}
136
137pub 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 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 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 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 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 unsafe { self.bytes.0.as_ref() }
214 }
215
216 pub(in crate::buffer) unsafe fn extent_mut(&mut self) -> &mut regions::Extent {
220 &mut self.bytes
221 }
222 pub(in crate::buffer) unsafe fn restrict(&mut self, bounds: ops::Range<usize>) {
225 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 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 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}