primitives/correlated_randomness/bundler/
mod.rs1use std::{
2 fmt::Debug,
3 ops::{Add, AddAssign, Sub, SubAssign},
4};
5
6use crate::correlated_randomness::{
7 bundler::errors::BundlerError,
8 stream::{CorrelatedStreamError, PrefetchHandle},
9};
10
11pub mod errors;
12
13pub type SizeOf<I> = <I as BundleIterator>::Size;
15
16pub type ErrorOf<I> = <I as BundleIterator>::Error;
18
19pub trait Bundler {
22 type Iterator: BundleIterator;
24
25 fn fetch(&mut self, size: &SizeOf<Self::Iterator>) -> Result<Self::Iterator, BundlerError>;
27
28 fn fetch_for<Consumer: BundleConsumer<Iterator = Self::Iterator>>(
30 &mut self,
31 consumer: &Consumer,
32 ) -> Result<Self::Iterator, BundlerError> {
33 let size = consumer.required_preprocessing();
34 self.fetch(&size)
35 }
36
37 fn prefetch(&self, size: &SizeOf<Self::Iterator>) -> PrefetchHandle<ErrorOf<Self::Iterator>>;
45
46 fn prefetch_for<Consumer: BundleConsumer<Iterator = Self::Iterator>>(
48 &self,
49 consumer: &Consumer,
50 ) -> PrefetchHandle<ErrorOf<Self::Iterator>> {
51 let size = consumer.required_preprocessing();
52 self.prefetch(&size)
53 }
54}
55
56impl<B: Bundler> Bundler for &mut B {
57 type Iterator = B::Iterator;
58
59 fn fetch(&mut self, size: &SizeOf<Self::Iterator>) -> Result<Self::Iterator, BundlerError> {
60 (**self).fetch(size)
61 }
62
63 fn prefetch(&self, size: &SizeOf<Self::Iterator>) -> PrefetchHandle<ErrorOf<Self::Iterator>> {
64 (**self).prefetch(size)
65 }
66}
67
68pub trait BundleConsumer {
70 type Iterator: BundleIterator;
73
74 fn required_preprocessing(&self) -> SizeOf<Self::Iterator>;
76
77 fn fetch_preprocessing_from<PB: Bundler<Iterator = Self::Iterator>>(
79 &self,
80 bundler: &mut PB,
81 ) -> Result<Self::Iterator, BundlerError> {
82 let size = self.required_preprocessing();
83 bundler.fetch(&size)
84 }
85
86 fn prefetch_preprocessing_from<PB: Bundler<Iterator = Self::Iterator>>(
88 &self,
89 bundler: &PB,
90 ) -> PrefetchHandle<ErrorOf<Self::Iterator>> {
91 let size = self.required_preprocessing();
92 bundler.prefetch(&size)
93 }
94}
95
96pub trait BundleIterator {
98 type Size: Debug + Clone + Default + Eq + Add + Sub + AddAssign + SubAssign;
100
101 type Error: Debug + Clone + From<CorrelatedStreamError> + Send + 'static;
103
104 fn len(&self) -> Self::Size;
106
107 fn is_empty(&self) -> bool {
109 self.len() == Self::Size::default()
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use std::cell::Cell;
116
117 use super::*;
118
119 struct Bundle(usize);
121
122 impl BundleIterator for Bundle {
123 type Size = usize;
124 type Error = CorrelatedStreamError;
125
126 fn len(&self) -> usize {
127 self.0
128 }
129 }
130
131 #[derive(Default)]
133 struct Recorder(Cell<Option<usize>>);
134
135 impl Bundler for Recorder {
136 type Iterator = Bundle;
137
138 fn fetch(&mut self, size: &usize) -> Result<Bundle, BundlerError> {
139 Ok(Bundle(*size))
140 }
141
142 fn prefetch(&self, size: &usize) -> PrefetchHandle<CorrelatedStreamError> {
143 self.0.set(Some(*size));
144 PrefetchHandle::ready(Ok(()))
145 }
146 }
147
148 struct Consumer(usize);
149
150 impl BundleConsumer for Consumer {
151 type Iterator = Bundle;
152
153 fn required_preprocessing(&self) -> usize {
154 self.0
155 }
156 }
157
158 #[tokio::test]
160 async fn consumer_driven_prefetch_forwards_the_required_size() {
161 let bundler = Recorder::default();
162 bundler.prefetch_for(&Consumer(11)).await.unwrap();
163 assert_eq!(bundler.0.get(), Some(11));
164
165 let bundler = Recorder::default();
166 Consumer(23)
167 .prefetch_preprocessing_from(&bundler)
168 .await
169 .unwrap();
170 assert_eq!(bundler.0.get(), Some(23));
171 }
172
173 #[tokio::test]
175 async fn mut_ref_forwards_prefetch() {
176 let mut bundler = Recorder::default();
177 let forwarded = &mut bundler;
178 forwarded.prefetch(&5).await.unwrap();
179 assert_eq!(bundler.0.get(), Some(5));
180 }
181}