primitives/correlated_randomness/stream/buffered/
config.rs1use std::{sync::Arc, time::Duration};
6
7use blanket::blanket;
8use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
9
10use crate::correlated_randomness::stream::CorrelatedStreamError;
11
12#[derive(Debug, Clone)]
14pub struct BufferConfig {
15 capacity: usize,
17 max_request_size: usize,
19 refill_threshold: usize,
21}
22
23impl BufferConfig {
24 pub const UNBOUNDED: usize = usize::MAX;
27
28 pub fn eager(capacity: usize) -> Self {
32 assert!(capacity > 0, "capacity must be greater than 0");
33 Self {
34 capacity,
35 max_request_size: capacity,
36 refill_threshold: capacity,
37 }
38 }
39
40 pub fn eager_with(capacity: usize, max_request_size: usize) -> Self {
43 assert!(capacity > 0, "capacity must be greater than 0");
44 Self {
45 capacity,
46 max_request_size: max_request_size.min(capacity),
47 refill_threshold: capacity,
48 }
49 }
50
51 pub fn lazy(capacity: usize, refill_threshold: usize) -> Self {
56 assert!(capacity > 0, "capacity must be greater than 0");
57 Self {
58 capacity,
59 max_request_size: capacity,
60 refill_threshold: refill_threshold.min(capacity),
61 }
62 }
63
64 pub fn lazy_with(capacity: usize, refill_threshold: usize, max_request_size: usize) -> Self {
70 assert!(capacity > 0, "capacity must be greater than 0");
71 Self {
72 capacity,
73 max_request_size: max_request_size.min(capacity),
74 refill_threshold: refill_threshold.min(capacity),
75 }
76 }
77
78 #[inline]
80 pub fn capacity(&self) -> usize {
81 self.capacity
82 }
83
84 #[inline]
86 pub fn max_request_size(&self) -> usize {
87 self.max_request_size
88 }
89
90 #[inline]
92 pub fn refill_threshold(&self) -> usize {
93 self.refill_threshold
94 }
95
96 pub fn set_capacity(&mut self, capacity: usize) {
102 assert!(capacity > 0, "capacity must be greater than 0");
103 self.capacity = capacity;
104 self.max_request_size = self.max_request_size.min(capacity);
105 self.refill_threshold = self.refill_threshold.min(capacity);
106 }
107
108 pub fn set_max_request_size(&mut self, max_request_size: usize) {
110 self.max_request_size = max_request_size.min(self.capacity);
111 }
112
113 pub fn set_refill_threshold(&mut self, refill_threshold: usize) {
115 self.refill_threshold = refill_threshold.min(self.capacity);
116 }
117}
118
119pub const LOCK_TIMEOUT: Duration = Duration::from_millis(500);
127
128#[inline]
131pub fn try_read_config(
132 m: &RwLock<BufferConfig>,
133) -> Result<RwLockReadGuard<'_, BufferConfig>, CorrelatedStreamError> {
134 m.try_read_for(LOCK_TIMEOUT)
135 .ok_or(CorrelatedStreamError::LockTimeout {
136 timeout_ms: LOCK_TIMEOUT.as_millis() as u64,
137 })
138}
139
140#[inline]
143pub fn try_write_config(
144 m: &RwLock<BufferConfig>,
145) -> Result<RwLockWriteGuard<'_, BufferConfig>, CorrelatedStreamError> {
146 m.try_write_for(LOCK_TIMEOUT)
147 .ok_or(CorrelatedStreamError::LockTimeout {
148 timeout_ms: LOCK_TIMEOUT.as_millis() as u64,
149 })
150}
151
152pub type SharedBufferConfig = Arc<RwLock<BufferConfig>>;
154
155#[blanket(derive(Arc, Ref, Mut))]
162pub trait Buffer {
163 fn config(&self) -> &SharedBufferConfig;
165
166 #[inline]
167 fn capacity(&self) -> Result<usize, CorrelatedStreamError> {
168 Ok(try_read_config(self.config())?.capacity())
169 }
170 #[inline]
171 fn max_request_size(&self) -> Result<usize, CorrelatedStreamError> {
172 Ok(try_read_config(self.config())?.max_request_size())
173 }
174 #[inline]
175 fn refill_threshold(&self) -> Result<usize, CorrelatedStreamError> {
176 Ok(try_read_config(self.config())?.refill_threshold())
177 }
178
179 #[inline]
180 fn set_capacity(&self, capacity: usize) -> Result<(), CorrelatedStreamError> {
181 try_write_config(self.config())?.set_capacity(capacity);
182 Ok(())
183 }
184 #[inline]
185 fn set_max_request_size(&self, n: usize) -> Result<(), CorrelatedStreamError> {
186 try_write_config(self.config())?.set_max_request_size(n);
187 Ok(())
188 }
189 #[inline]
190 fn set_refill_threshold(&self, n: usize) -> Result<(), CorrelatedStreamError> {
191 try_write_config(self.config())?.set_refill_threshold(n);
192 Ok(())
193 }
194}
195
196impl Buffer for [SharedBufferConfig] {
200 fn config(&self) -> &SharedBufferConfig {
201 self.first().expect("Buffer config slice must be non-empty")
202 }
203 fn set_capacity(&self, capacity: usize) -> Result<(), CorrelatedStreamError> {
204 self.iter().try_for_each(|c| {
205 try_write_config(c)?.set_capacity(capacity);
206 Ok(())
207 })
208 }
209 fn set_max_request_size(&self, n: usize) -> Result<(), CorrelatedStreamError> {
210 self.iter().try_for_each(|c| {
211 try_write_config(c)?.set_max_request_size(n);
212 Ok(())
213 })
214 }
215 fn set_refill_threshold(&self, n: usize) -> Result<(), CorrelatedStreamError> {
216 self.iter().try_for_each(|c| {
217 try_write_config(c)?.set_refill_threshold(n);
218 Ok(())
219 })
220 }
221}