vortex_array/array/
visitor.rs1use 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 fn children(&self) -> Vec<ArrayRef>;
14
15 fn nchildren(&self) -> usize;
17
18 fn children_names(&self) -> Vec<String>;
20
21 fn named_children(&self) -> Vec<(String, ArrayRef)>;
23
24 fn buffers(&self) -> Vec<ByteBuffer>;
26
27 fn nbuffers(&self) -> usize;
29
30 fn metadata(&self) -> Option<Vec<u8>>;
32
33 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result;
35}
36
37impl ArrayVisitor for Arc<dyn Array> {
38 fn children(&self) -> Vec<ArrayRef> {
39 self.as_ref().children()
40 }
41
42 fn nchildren(&self) -> usize {
43 self.as_ref().nchildren()
44 }
45
46 fn children_names(&self) -> Vec<String> {
47 self.as_ref().children_names()
48 }
49
50 fn named_children(&self) -> Vec<(String, ArrayRef)> {
51 self.as_ref().named_children()
52 }
53
54 fn buffers(&self) -> Vec<ByteBuffer> {
55 self.as_ref().buffers()
56 }
57
58 fn nbuffers(&self) -> usize {
59 self.as_ref().nbuffers()
60 }
61
62 fn metadata(&self) -> Option<Vec<u8>> {
63 self.as_ref().metadata()
64 }
65
66 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
67 self.as_ref().metadata_fmt(f)
68 }
69}
70
71pub trait ArrayVisitorExt: Array {
72 fn nbuffers_recursive(&self) -> usize {
74 self.children()
75 .iter()
76 .map(ArrayVisitorExt::nbuffers_recursive)
77 .sum::<usize>()
78 + self.nbuffers()
79 }
80
81 fn depth_first_traversal(&self) -> impl Iterator<Item = ArrayRef> {
83 struct ArrayChildrenIterator {
85 stack: Vec<ArrayRef>,
86 }
87
88 impl Iterator for ArrayChildrenIterator {
89 type Item = ArrayRef;
90
91 fn next(&mut self) -> Option<Self::Item> {
92 let next = self.stack.pop()?;
93 for child in next.children().into_iter().rev() {
94 self.stack.push(child);
95 }
96 Some(next)
97 }
98 }
99
100 ArrayChildrenIterator {
101 stack: vec![self.to_array()],
102 }
103 }
104}
105
106impl<A: Array + ?Sized> ArrayVisitorExt for A {}
107
108pub trait ArrayVisitorImpl<M: SerializeMetadata + DeserializeMetadata + Debug = EmptyMetadata> {
110 fn _visit_buffers(&self, _visitor: &mut dyn ArrayBufferVisitor) {}
111
112 fn _nbuffers(&self) -> usize {
113 struct NBuffers(usize);
114
115 impl ArrayBufferVisitor for NBuffers {
116 fn visit_buffer(&mut self, _buffer: &ByteBuffer) {
117 self.0 += 1;
118 }
119 }
120
121 let mut visitor = NBuffers(0);
122 self._visit_buffers(&mut visitor);
123 visitor.0
124 }
125
126 fn _visit_children(&self, _visitor: &mut dyn ArrayChildVisitor) {}
127
128 fn _nchildren(&self) -> usize {
129 struct NChildren(usize);
130
131 impl ArrayChildVisitor for NChildren {
132 fn visit_child(&mut self, _name: &str, _array: &dyn Array) {
133 self.0 += 1;
134 }
135 }
136
137 let mut visitor = NChildren(0);
138 self._visit_children(&mut visitor);
139 visitor.0
140 }
141
142 fn _metadata(&self) -> M;
143}
144
145pub trait ArrayBufferVisitor {
146 fn visit_buffer(&mut self, buffer: &ByteBuffer);
147}
148
149pub trait ArrayChildVisitor {
150 fn visit_child(&mut self, _name: &str, _array: &dyn Array);
152
153 fn visit_validity(&mut self, validity: &Validity, len: usize) {
155 if let Some(vlen) = validity.maybe_len() {
156 assert_eq!(vlen, len, "Validity length mismatch");
157 }
158
159 match validity {
160 Validity::NonNullable | Validity::AllValid => {}
161 Validity::AllInvalid => {
162 self.visit_child("validity", &ConstantArray::new(false, len))
169 }
170 Validity::Array(array) => {
171 self.visit_child("validity", array);
172 }
173 }
174 }
175
176 fn visit_patches(&mut self, patches: &Patches) {
178 self.visit_child("patch_indices", patches.indices());
179 self.visit_child("patch_values", patches.values());
180 }
181}
182
183impl<A: ArrayImpl> ArrayVisitor for A {
184 fn children(&self) -> Vec<ArrayRef> {
185 struct ChildrenCollector {
186 children: Vec<ArrayRef>,
187 }
188
189 impl ArrayChildVisitor for ChildrenCollector {
190 fn visit_child(&mut self, _name: &str, array: &dyn Array) {
191 self.children.push(array.to_array());
192 }
193 }
194
195 let mut collector = ChildrenCollector {
196 children: Vec::new(),
197 };
198 ArrayVisitorImpl::_visit_children(self, &mut collector);
199 collector.children
200 }
201
202 fn nchildren(&self) -> usize {
203 ArrayVisitorImpl::_nchildren(self)
204 }
205
206 fn children_names(&self) -> Vec<String> {
207 struct ChildNameCollector {
208 names: Vec<String>,
209 }
210
211 impl ArrayChildVisitor for ChildNameCollector {
212 fn visit_child(&mut self, name: &str, _array: &dyn Array) {
213 self.names.push(name.to_string());
214 }
215 }
216
217 let mut collector = ChildNameCollector { names: Vec::new() };
218 ArrayVisitorImpl::_visit_children(self, &mut collector);
219 collector.names
220 }
221
222 fn named_children(&self) -> Vec<(String, ArrayRef)> {
223 struct NamedChildrenCollector {
224 children: Vec<(String, ArrayRef)>,
225 }
226
227 impl ArrayChildVisitor for NamedChildrenCollector {
228 fn visit_child(&mut self, name: &str, array: &dyn Array) {
229 self.children.push((name.to_string(), array.to_array()));
230 }
231 }
232
233 let mut collector = NamedChildrenCollector {
234 children: Vec::new(),
235 };
236
237 ArrayVisitorImpl::_visit_children(self, &mut collector);
238 collector.children
239 }
240
241 fn buffers(&self) -> Vec<ByteBuffer> {
242 struct BufferCollector {
243 buffers: Vec<ByteBuffer>,
244 }
245
246 impl ArrayBufferVisitor for BufferCollector {
247 fn visit_buffer(&mut self, buffer: &ByteBuffer) {
248 self.buffers.push(buffer.clone());
249 }
250 }
251
252 let mut collector = BufferCollector {
253 buffers: Vec::new(),
254 };
255 ArrayVisitorImpl::_visit_buffers(self, &mut collector);
256 collector.buffers
257 }
258
259 fn nbuffers(&self) -> usize {
260 ArrayVisitorImpl::_nbuffers(self)
261 }
262
263 fn metadata(&self) -> Option<Vec<u8>> {
264 SerializeMetadata::serialize(&ArrayVisitorImpl::_metadata(self))
265 }
266
267 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
268 Debug::fmt(&ArrayVisitorImpl::_metadata(self), f)
269 }
270}