vortex_array/array/
visitor.rs

1use std::fmt::{Debug, Formatter};
2use std::sync::Arc;
3
4use vortex_buffer::ByteBuffer;
5
6use crate::arrays::ConstantArray;
7use crate::patches::Patches;
8use crate::validity::Validity;
9use crate::{Array, ArrayImpl, ArrayRef, DeserializeMetadata, EmptyMetadata, SerializeMetadata};
10
11pub trait ArrayVisitor {
12    /// Returns the children of the array.
13    fn children(&self) -> Vec<ArrayRef>;
14
15    /// Returns the number of children of the array.
16    fn nchildren(&self) -> usize;
17
18    /// Returns the names of the children of the array.
19    fn children_names(&self) -> Vec<String>;
20
21    /// Returns the buffers of the array.
22    fn buffers(&self) -> Vec<ByteBuffer>;
23
24    /// Returns the number of buffers of the array.
25    fn nbuffers(&self) -> usize;
26
27    /// Returns the serialized metadata of the array.
28    fn metadata(&self) -> Option<Vec<u8>>;
29
30    /// Formats a human-readable metadata description.
31    fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result;
32}
33
34impl ArrayVisitor for Arc<dyn Array> {
35    fn children(&self) -> Vec<ArrayRef> {
36        self.as_ref().children()
37    }
38
39    fn nchildren(&self) -> usize {
40        self.as_ref().nchildren()
41    }
42
43    fn children_names(&self) -> Vec<String> {
44        self.as_ref().children_names()
45    }
46
47    fn buffers(&self) -> Vec<ByteBuffer> {
48        self.as_ref().buffers()
49    }
50
51    fn nbuffers(&self) -> usize {
52        self.as_ref().nbuffers()
53    }
54
55    fn metadata(&self) -> Option<Vec<u8>> {
56        self.as_ref().metadata()
57    }
58
59    fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60        self.as_ref().metadata_fmt(f)
61    }
62}
63
64pub trait ArrayVisitorExt: Array {
65    /// Count the number of buffers encoded by self and all child arrays.
66    fn nbuffers_recursive(&self) -> usize {
67        self.children()
68            .iter()
69            .map(ArrayVisitorExt::nbuffers_recursive)
70            .sum::<usize>()
71            + self.nbuffers()
72    }
73
74    /// Depth-first traversal of the array and its children.
75    fn depth_first_traversal(&self) -> impl Iterator<Item = ArrayRef> {
76        /// A depth-first pre-order iterator over an Array.
77        struct ArrayChildrenIterator {
78            stack: Vec<ArrayRef>,
79        }
80
81        impl Iterator for ArrayChildrenIterator {
82            type Item = ArrayRef;
83
84            fn next(&mut self) -> Option<Self::Item> {
85                let next = self.stack.pop()?;
86                for child in next.children().into_iter().rev() {
87                    self.stack.push(child);
88                }
89                Some(next)
90            }
91        }
92
93        ArrayChildrenIterator {
94            stack: vec![self.to_array()],
95        }
96    }
97}
98
99impl<A: Array + ?Sized> ArrayVisitorExt for A {}
100
101// TODO(ngates): rename to ArraySerdeImpl?
102pub trait ArrayVisitorImpl<
103    Metadata: SerializeMetadata + DeserializeMetadata + Debug = EmptyMetadata,
104>
105{
106    fn _buffers(&self, _visitor: &mut dyn ArrayBufferVisitor) {}
107
108    fn _nbuffers(&self) -> usize {
109        struct NBuffers(usize);
110
111        impl ArrayBufferVisitor for NBuffers {
112            fn visit_buffer(&mut self, _buffer: &ByteBuffer) {
113                self.0 += 1;
114            }
115        }
116
117        let mut visitor = NBuffers(0);
118        self._buffers(&mut visitor);
119        visitor.0
120    }
121
122    fn _children(&self, _visitor: &mut dyn ArrayChildVisitor) {}
123
124    fn _nchildren(&self) -> usize {
125        struct NChildren(usize);
126
127        impl ArrayChildVisitor for NChildren {
128            fn visit_child(&mut self, _name: &str, _array: &dyn Array) {
129                self.0 += 1;
130            }
131        }
132
133        let mut visitor = NChildren(0);
134        self._children(&mut visitor);
135        visitor.0
136    }
137
138    fn _metadata(&self) -> Metadata;
139}
140
141pub trait ArrayBufferVisitor {
142    fn visit_buffer(&mut self, buffer: &ByteBuffer);
143}
144
145pub trait ArrayChildVisitor {
146    /// Visit a child of this array.
147    fn visit_child(&mut self, _name: &str, _array: &dyn Array);
148
149    /// Utility for visiting Array validity.
150    fn visit_validity(&mut self, validity: &Validity, len: usize) {
151        if let Some(vlen) = validity.maybe_len() {
152            assert_eq!(vlen, len, "Validity length mismatch");
153        }
154
155        match validity {
156            Validity::NonNullable | Validity::AllValid => {}
157            Validity::AllInvalid => {
158                // To avoid storing metadata about validity, we store all invalid as a
159                // constant array of false values.
160                // This gives:
161                //  * is_nullable & has_validity => Validity::Array (or Validity::AllInvalid)
162                //  * is_nullable & !has_validity => Validity::AllValid
163                //  * !is_nullable => Validity::NonNullable
164                self.visit_child("validity", &ConstantArray::new(false, len))
165            }
166            Validity::Array(array) => {
167                self.visit_child("validity", array);
168            }
169        }
170    }
171
172    /// Utility for visiting Array patches.
173    fn visit_patches(&mut self, patches: &Patches) {
174        self.visit_child("patch_indices", patches.indices());
175        self.visit_child("patch_values", patches.values());
176    }
177}
178
179impl<A: ArrayImpl> ArrayVisitor for A {
180    fn children(&self) -> Vec<ArrayRef> {
181        struct ChildrenCollector {
182            children: Vec<ArrayRef>,
183        }
184
185        impl ArrayChildVisitor for ChildrenCollector {
186            fn visit_child(&mut self, _name: &str, array: &dyn Array) {
187                self.children.push(array.to_array());
188            }
189        }
190
191        let mut collector = ChildrenCollector {
192            children: Vec::new(),
193        };
194        ArrayVisitorImpl::_children(self, &mut collector);
195        collector.children
196    }
197
198    fn nchildren(&self) -> usize {
199        ArrayVisitorImpl::_nchildren(self)
200    }
201
202    fn children_names(&self) -> Vec<String> {
203        struct ChildNameCollector {
204            names: Vec<String>,
205        }
206
207        impl ArrayChildVisitor for ChildNameCollector {
208            fn visit_child(&mut self, name: &str, _array: &dyn Array) {
209                self.names.push(name.to_string());
210            }
211        }
212
213        let mut collector = ChildNameCollector { names: Vec::new() };
214        ArrayVisitorImpl::_children(self, &mut collector);
215        collector.names
216    }
217
218    fn buffers(&self) -> Vec<ByteBuffer> {
219        struct BufferCollector {
220            buffers: Vec<ByteBuffer>,
221        }
222
223        impl ArrayBufferVisitor for BufferCollector {
224            fn visit_buffer(&mut self, buffer: &ByteBuffer) {
225                self.buffers.push(buffer.clone());
226            }
227        }
228
229        let mut collector = BufferCollector {
230            buffers: Vec::new(),
231        };
232        ArrayVisitorImpl::_buffers(self, &mut collector);
233        collector.buffers
234    }
235
236    fn nbuffers(&self) -> usize {
237        ArrayVisitorImpl::_nbuffers(self)
238    }
239
240    fn metadata(&self) -> Option<Vec<u8>> {
241        SerializeMetadata::serialize(&ArrayVisitorImpl::_metadata(self))
242    }
243
244    fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
245        Debug::fmt(&ArrayVisitorImpl::_metadata(self), f)
246    }
247}