1use crate::{DeliveryHandler, PageRequest};
6use delivery_blob::compression::{ChunkedArchiveError, DataBuffer};
7use fuchsia_sync::{Condvar, Mutex};
8use std::ops::{Deref, DerefMut, Range};
9use std::sync::Arc;
10use storage_ptr_slice::MutPtrByteSlice;
11use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
12
13#[derive(Clone, Copy, IntoBytes, FromBytes, KnownLayout, Immutable)]
14#[repr(C, align(64))]
15struct Block([u8; 64]);
16
17impl Default for Block {
18 fn default() -> Self {
19 Self([0u8; 64])
20 }
21}
22
23#[derive(Clone, Default)]
25pub struct AlignedBuffer {
26 blocks: Vec<Block>,
27 len: usize,
28}
29
30impl AlignedBuffer {
31 pub fn new(len: usize) -> Self {
32 let block_count = len.div_ceil(64);
33 Self { blocks: vec![Block::default(); block_count], len }
34 }
35
36 pub fn len(&self) -> usize {
37 self.len
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.len == 0
42 }
43
44 pub fn resize(&mut self, new_len: usize, val: u8) {
45 let block_count = new_len.div_ceil(64);
46 if block_count > self.blocks.len() {
47 self.blocks.resize(block_count, Block::default());
48 } else {
49 self.blocks.truncate(block_count);
50 }
51 if new_len > self.len {
52 self.blocks.as_mut_bytes()[self.len..new_len].fill(val);
53 }
54 self.len = new_len;
55 }
56
57 pub fn as_slice(&self) -> &[u8] {
58 &self.blocks.as_bytes()[..self.len]
59 }
60
61 pub fn as_mut_slice(&mut self) -> &mut [u8] {
62 &mut self.blocks.as_mut_bytes()[..self.len]
63 }
64
65 pub fn to_vec(&self) -> Vec<u8> {
66 self.as_slice().to_vec()
67 }
68}
69
70impl Deref for AlignedBuffer {
71 type Target = [u8];
72 fn deref(&self) -> &Self::Target {
73 self.as_slice()
74 }
75}
76
77impl DerefMut for AlignedBuffer {
78 fn deref_mut(&mut self) -> &mut Self::Target {
79 self.as_mut_slice()
80 }
81}
82
83#[derive(Default)]
84pub struct TestVecBufferInner {
85 pub commits: Vec<(u64, usize)>,
86 pub output: Vec<u8>,
87}
88
89#[derive(Clone)]
90pub struct TestVecBufferReceiver {
91 pub inner: Arc<Mutex<TestVecBufferInner>>,
92 on_commit: Arc<Condvar>,
93}
94
95impl Default for TestVecBufferReceiver {
96 fn default() -> Self {
97 Self {
98 inner: Arc::new(Mutex::new(TestVecBufferInner::default())),
99 on_commit: Arc::new(Condvar::new()),
100 }
101 }
102}
103
104impl TestVecBufferReceiver {
105 pub fn commits(&self) -> Vec<(u64, usize)> {
106 self.inner.lock().commits.clone()
107 }
108
109 pub fn wait_for_commits(&self, count: usize) -> Vec<(u64, usize)> {
110 let mut inner = self.inner.lock();
111 while inner.commits.len() < count {
112 self.on_commit.wait(&mut inner);
113 }
114 inner.commits.clone()
115 }
116
117 pub fn output(&self) -> Vec<u8> {
118 self.inner.lock().output.clone()
119 }
120}
121
122pub struct TestVecBuffer {
123 pub data: AlignedBuffer,
124 pub range: Range<u64>,
125 pub committed_len: usize,
126 pub offset: u64,
127 pub receiver: TestVecBufferReceiver,
128}
129
130impl TestVecBuffer {
131 pub fn new(size: usize) -> (Self, TestVecBufferReceiver) {
132 Self::new_with_offset(size, 0)
133 }
134
135 pub fn new_with_offset(size: usize, offset: u64) -> (Self, TestVecBufferReceiver) {
136 let receiver = TestVecBufferReceiver::default();
137 let range = offset..offset + size as u64;
138 let buf = Self {
139 data: AlignedBuffer::new(size),
140 range,
141 committed_len: 0,
142 offset,
143 receiver: receiver.clone(),
144 };
145 (buf, receiver)
146 }
147
148 pub fn new_with_range(range: Range<u64>) -> (Self, TestVecBufferReceiver) {
149 let size = (range.end - range.start) as usize;
150 let receiver = TestVecBufferReceiver::default();
151 let buf = Self {
152 data: AlignedBuffer::new(size),
153 offset: range.start,
154 range,
155 committed_len: 0,
156 receiver: receiver.clone(),
157 };
158 (buf, receiver)
159 }
160
161 pub fn new_unprepared() -> (Self, TestVecBufferReceiver) {
162 Self::new_unprepared_with_range(0..0)
163 }
164
165 pub fn new_unprepared_with_range(range: Range<u64>) -> (Self, TestVecBufferReceiver) {
166 let receiver = TestVecBufferReceiver::default();
167 let buf = Self {
168 data: AlignedBuffer::default(),
169 range,
170 committed_len: 0,
171 offset: 0,
172 receiver: receiver.clone(),
173 };
174 (buf, receiver)
175 }
176}
177
178impl DataBuffer for TestVecBuffer {
179 fn range(&self) -> Range<u64> {
180 self.range.clone()
181 }
182
183 fn mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
184 let remaining = &mut self.data[self.committed_len..];
185 MutPtrByteSlice::from(remaining)
186 }
187
188 fn commit(&mut self, size: usize) -> Result<(), ChunkedArchiveError> {
189 let mut inner = self.receiver.inner.lock();
190 inner.commits.push((self.offset, size));
191 inner.output = self.data.to_vec();
192 self.offset += size as u64;
193 self.committed_len += size;
194 self.receiver.on_commit.notify_all();
195 Ok(())
196 }
197}
198
199impl PageRequest for TestVecBuffer {
200 fn prepare(
201 &mut self,
202 read_range: Range<u64>,
203 _read_alignment: usize,
204 ) -> Result<(), ChunkedArchiveError> {
205 let size = (read_range.end - read_range.start) as usize;
206 if self.data.len() < size {
207 self.data.resize(size, 0);
208 }
209 self.range = read_range.clone();
210 self.offset = read_range.start;
211 Ok(())
212 }
213}
214
215pub struct TestDeliveryHandler<F>(pub F);
225
226impl<F, R: PageRequest> DeliveryHandler for TestDeliveryHandler<F>
227where
228 F: Fn(u64, Range<u64>) -> R + Send + Sync + 'static,
229{
230 type Request = R;
231
232 fn get_page_request(self: &Arc<Self>, key: u64, range: Range<u64>) -> Self::Request {
233 (self.0)(key, range)
234 }
235}