devela/data/dst/queue/
private.rs
1use super::super::{decompose_pointer, make_fat_ptr, store_metadata};
8use super::{DstBuf, DstQueue};
9use crate::{MaybeUninit, Ptr};
10
11pub(super) struct PushInnerInfo<'a, I> {
12 pub(super) data: &'a mut [MaybeUninit<I>],
14
15 pub(super) meta: &'a mut [MaybeUninit<I>],
17
18 pub(super) reset_slot: &'a mut usize,
20 pub(super) reset_value: usize,
21}
22
23impl<DST: ?Sized, BUF: DstBuf> DstQueue<DST, BUF> {
24 pub(super) unsafe fn push_inner(
28 &mut self,
29 fat_ptr: &DST,
30 ) -> Result<PushInnerInfo<BUF::Inner>, ()> {
31 let bytes = size_of_val(fat_ptr);
32 let (_data_ptr, len, v) = decompose_pointer(fat_ptr);
33 unsafe { self.push_inner_raw(bytes, &v[..len]) }
35 }
36
37 pub(super) unsafe fn push_inner_raw(
39 &mut self,
40 bytes: usize,
41 metadata: &[usize],
42 ) -> Result<PushInnerInfo<BUF::Inner>, ()> {
43 let words = BUF::round_to_words(bytes) + Self::meta_words();
44
45 if self.space_words() < words {
47 if self.space_words() + self.read_pos >= words {
49 self.compact();
50 }
51 if self.space_words() < words && self.data.extend(self.write_pos + words).is_err() {
53 return Err(());
55 }
56 }
57 assert!(self.space_words() >= words);
58
59 let slot = &mut self.data.as_mut()[self.write_pos..][..words];
61 let prev_write_pos = self.write_pos;
62 self.write_pos += words;
63 let (meta, rv) = slot.split_at_mut(Self::meta_words());
64
65 store_metadata(meta, metadata);
67
68 Ok(PushInnerInfo {
70 meta,
71 data: rv,
72 reset_slot: &mut self.write_pos,
73 reset_value: prev_write_pos,
74 })
75 }
76
77 #[must_use]
78 pub(super) fn meta_words() -> usize {
79 BUF::round_to_words(size_of::<&DST>() - size_of::<usize>())
80 }
81
82 #[must_use]
83 fn space_words(&self) -> usize {
84 self.data.as_ref().len() - self.write_pos
85 }
86
87 #[must_use]
88 pub(super) fn front_raw(&self) -> *mut DST {
89 assert!(self.read_pos < self.write_pos);
90 unsafe { self.raw_at(self.read_pos) }
92 }
93
94 #[must_use]
95 pub(super) unsafe fn raw_at(&self, pos: usize) -> *mut DST {
97 assert!(pos >= self.read_pos);
98 assert!(pos < self.write_pos);
99 let meta = &self.data.as_ref()[pos..];
100 let mw = Self::meta_words();
101 let (meta, data) = meta.split_at(mw);
102 unsafe { make_fat_ptr(data.as_ptr() as *mut (), meta) }
104 }
105
106 #[must_use]
107 pub(super) fn front_raw_mut(&mut self) -> *mut DST {
108 assert!(self.read_pos < self.write_pos);
109 unsafe { self.raw_at_mut(self.read_pos) }
111 }
112
113 #[must_use]
114 pub(super) unsafe fn raw_at_mut(&mut self, pos: usize) -> *mut DST {
116 assert!(pos >= self.read_pos);
117 assert!(pos < self.write_pos);
118 let meta = &mut self.data.as_mut()[pos..];
119 let mw = Self::meta_words();
120 let (meta, data) = meta.split_at_mut(mw);
121 unsafe { make_fat_ptr(data.as_mut_ptr() as *mut (), meta) }
123 }
124
125 pub(super) fn pop_front_inner(&mut self) {
126 unsafe {
128 let ptr = &mut *self.front_raw_mut();
129 let len = size_of_val(ptr);
130 Ptr::drop_in_place(ptr);
131 let words = BUF::round_to_words(len);
132 self.read_pos += Self::meta_words() + words;
133 }
134 }
135}