vortex_array/
mask_future.rs1use std::future::Future;
5use std::ops::Range;
6use std::sync::Arc;
7
8use futures::FutureExt;
9use futures::TryFutureExt;
10use futures::future::BoxFuture;
11use futures::future::Shared;
12use vortex_error::SharedVortexResult;
13use vortex_error::VortexError;
14use vortex_error::VortexResult;
15use vortex_error::vortex_panic;
16use vortex_mask::Mask;
17
18#[derive(Clone)]
20pub struct MaskFuture {
21 inner: Shared<BoxFuture<'static, SharedVortexResult<Mask>>>,
22 len: usize,
23}
24
25impl MaskFuture {
26 pub fn new<F>(len: usize, fut: F) -> Self
28 where
29 F: Future<Output = VortexResult<Mask>> + Send + 'static,
30 {
31 Self {
32 inner: fut
33 .inspect(move |r| {
34 if let Ok(mask) = r
35 && mask.len() != len {
36 vortex_panic!("MaskFuture created with future that returned mask of incorrect length (expected {}, got {})", len, mask.len());
37 }
38 })
39 .map_err(Arc::new)
40 .boxed()
41 .shared(),
42 len,
43 }
44 }
45
46 pub fn len(&self) -> usize {
48 self.len
49 }
50
51 pub fn is_empty(&self) -> bool {
53 self.len == 0
54 }
55
56 pub fn ready(mask: Mask) -> Self {
58 let fut = Self::new(mask.len(), async move { Ok(mask) });
59 let _ready = fut.inner.clone().now_or_never();
62 fut
63 }
64
65 pub fn peek(&self) -> Option<&Mask> {
71 self.inner.peek().and_then(|result| result.as_ref().ok())
72 }
73
74 pub fn new_true(row_count: usize) -> Self {
76 Self::ready(Mask::new_true(row_count))
77 }
78
79 pub fn slice(&self, range: Range<usize>) -> Self {
81 if range.start == 0 && range.end == self.len {
84 return self.clone();
85 }
86
87 if let Some(mask) = self.peek() {
89 return Self::ready(mask.slice(range));
90 }
91
92 let inner = self.inner.clone();
93 Self::new(range.len(), async move { Ok(inner.await?.slice(range)) })
94 }
95
96 pub fn inspect(
97 self,
98 f: impl FnOnce(&SharedVortexResult<Mask>) + 'static + Send + Sync,
99 ) -> Self {
100 let len = self.len;
101
102 Self {
103 inner: self.inner.inspect(f).boxed().shared(),
104 len,
105 }
106 }
107}
108
109impl Future for MaskFuture {
110 type Output = VortexResult<Mask>;
111
112 fn poll(
113 mut self: std::pin::Pin<&mut Self>,
114 cx: &mut std::task::Context<'_>,
115 ) -> std::task::Poll<Self::Output> {
116 self.inner.poll_unpin(cx).map_err(VortexError::from)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use vortex_buffer::BitBuffer;
123
124 use super::*;
125
126 #[test]
129 fn slice_resolves_to_sliced_mask() -> VortexResult<()> {
130 futures::executor::block_on(async {
131 let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true, true, false]));
132 let fut = MaskFuture::ready(mask.clone());
133
134 let full = fut.slice(0..mask.len());
135 assert_eq!(full.len(), mask.len());
136 assert_eq!(full.await?, mask);
137
138 let partial = fut.slice(0..mask.len() - 1);
139 assert_eq!(partial.len(), mask.len() - 1);
140 assert_eq!(partial.await?, Mask::from_iter([true, false, true, true]));
141 Ok(())
142 })
143 }
144
145 #[test]
146 fn ready_masks_and_their_slices_can_be_peeked() -> VortexResult<()> {
147 let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true, false]));
148 let fut = MaskFuture::ready(mask.clone());
149 assert_eq!(fut.peek(), Some(&mask));
150 assert_eq!(MaskFuture::new_true(3).peek(), Some(&Mask::new_true(3)));
151
152 let slice = fut.slice(1..3);
153 assert_eq!(slice.peek(), Some(&mask.slice(1..3)));
154 assert_eq!(slice.now_or_never().transpose()?, Some(mask.slice(1..3)));
156 Ok(())
157 }
158
159 #[test]
160 fn pending_masks_can_be_peeked_once_complete() -> VortexResult<()> {
161 let mask = Mask::from_buffer(BitBuffer::from_iter([true, false, true]));
162 let pending = MaskFuture::new(3, async move { Ok(mask) });
163 assert!(pending.peek().is_none());
164 assert!(pending.slice(0..2).peek().is_none());
165
166 let mask = futures::executor::block_on(pending.clone())?;
167 assert_eq!(pending.peek(), Some(&mask));
168 assert_eq!(pending.slice(0..2).peek(), Some(&mask.slice(0..2)));
169 Ok(())
170 }
171}