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 buffers(&self) -> Vec<ByteBuffer>;
23
24 fn nbuffers(&self) -> usize;
26
27 fn metadata(&self) -> Option<Vec<u8>>;
29
30 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 fn nbuffers_recursive(&self) -> usize {
67 self.children()
68 .iter()
69 .map(ArrayVisitorExt::nbuffers_recursive)
70 .sum::<usize>()
71 + self.nbuffers()
72 }
73
74 fn depth_first_traversal(&self) -> impl Iterator<Item = ArrayRef> {
76 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
101pub 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 fn visit_child(&mut self, _name: &str, _array: &dyn Array);
148
149 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 self.visit_child("validity", &ConstantArray::new(false, len))
165 }
166 Validity::Array(array) => {
167 self.visit_child("validity", array);
168 }
169 }
170 }
171
172 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}