1use crate::{DeliveryHandler, PageRequest};
6use delivery_blob::compression::{ChunkedArchiveError, DataBuffer};
7use fuchsia_sync::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(pub Arc<Mutex<TestVecBufferInner>>);
91
92impl TestVecBufferReceiver {
93 pub fn commits(&self) -> Vec<(u64, usize)> {
94 self.0.lock().commits.clone()
95 }
96
97 pub fn output(&self) -> Vec<u8> {
98 self.0.lock().output.clone()
99 }
100}
101
102pub struct TestVecBuffer {
103 pub data: AlignedBuffer,
104 pub range: Range<u64>,
105 pub committed_len: usize,
106 pub offset: u64,
107 pub receiver: TestVecBufferReceiver,
108}
109
110impl TestVecBuffer {
111 pub fn new(size: usize) -> (Self, TestVecBufferReceiver) {
112 Self::new_with_offset(size, 0)
113 }
114
115 pub fn new_with_offset(size: usize, offset: u64) -> (Self, TestVecBufferReceiver) {
116 let receiver = TestVecBufferReceiver(Arc::new(Mutex::new(TestVecBufferInner::default())));
117 let range = offset..offset + size as u64;
118 let buf = Self {
119 data: AlignedBuffer::new(size),
120 range,
121 committed_len: 0,
122 offset,
123 receiver: receiver.clone(),
124 };
125 (buf, receiver)
126 }
127
128 pub fn new_with_range(range: Range<u64>) -> (Self, TestVecBufferReceiver) {
129 let size = (range.end - range.start) as usize;
130 let receiver = TestVecBufferReceiver(Arc::new(Mutex::new(TestVecBufferInner::default())));
131 let buf = Self {
132 data: AlignedBuffer::new(size),
133 offset: range.start,
134 range,
135 committed_len: 0,
136 receiver: receiver.clone(),
137 };
138 (buf, receiver)
139 }
140
141 pub fn new_unprepared() -> (Self, TestVecBufferReceiver) {
142 Self::new_unprepared_with_range(0..0)
143 }
144
145 pub fn new_unprepared_with_range(range: Range<u64>) -> (Self, TestVecBufferReceiver) {
146 let receiver = TestVecBufferReceiver(Arc::new(Mutex::new(TestVecBufferInner::default())));
147 let buf = Self {
148 data: AlignedBuffer::default(),
149 range,
150 committed_len: 0,
151 offset: 0,
152 receiver: receiver.clone(),
153 };
154 (buf, receiver)
155 }
156}
157
158impl DataBuffer for TestVecBuffer {
159 fn range(&self) -> Range<u64> {
160 self.range.clone()
161 }
162
163 fn mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
164 let remaining = &mut self.data[self.committed_len..];
165 MutPtrByteSlice::from(remaining)
166 }
167
168 fn commit(&mut self, size: usize) -> Result<(), ChunkedArchiveError> {
169 let mut inner = self.receiver.0.lock();
170 inner.commits.push((self.offset, size));
171 inner.output = self.data.to_vec();
172 self.offset += size as u64;
173 self.committed_len += size;
174 Ok(())
175 }
176}
177
178impl PageRequest for TestVecBuffer {
179 fn prepare(&mut self, read_range: Range<u64>) -> Result<(), ChunkedArchiveError> {
180 let size = (read_range.end - read_range.start) as usize;
181 if self.data.len() < size {
182 self.data.resize(size, 0);
183 }
184 self.range = read_range.clone();
185 self.offset = read_range.start;
186 Ok(())
187 }
188}
189
190pub struct TestDeliveryHandler<F>(pub F);
200
201impl<F, R: PageRequest> DeliveryHandler for TestDeliveryHandler<F>
202where
203 F: Fn(u64, Range<u64>) -> R + Send + Sync + 'static,
204{
205 type Request = R;
206
207 fn get_page_request(self: &Arc<Self>, key: u64, range: Range<u64>) -> Self::Request {
208 (self.0)(key, range)
209 }
210}