vortex_array/array/
visitor.rs1use std::fmt::Formatter;
5use std::ops::Deref;
6use std::sync::Arc;
7
8use vortex_buffer::ByteBuffer;
9use vortex_error::VortexResult;
10
11use crate::arrays::ConstantArray;
12use crate::patches::Patches;
13use crate::validity::Validity;
14use crate::{Array, ArrayRef};
15
16pub trait ArrayVisitor {
17 fn children(&self) -> Vec<ArrayRef>;
19
20 fn nchildren(&self) -> usize;
22
23 fn children_names(&self) -> Vec<String>;
25
26 fn named_children(&self) -> Vec<(String, ArrayRef)>;
28
29 fn buffers(&self) -> Vec<ByteBuffer>;
31
32 fn nbuffers(&self) -> usize;
34
35 fn metadata(&self) -> VortexResult<Option<Vec<u8>>>;
38
39 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result;
41}
42
43impl ArrayVisitor for Arc<dyn Array> {
44 fn children(&self) -> Vec<ArrayRef> {
45 self.as_ref().children()
46 }
47
48 fn nchildren(&self) -> usize {
49 self.as_ref().nchildren()
50 }
51
52 fn children_names(&self) -> Vec<String> {
53 self.as_ref().children_names()
54 }
55
56 fn named_children(&self) -> Vec<(String, ArrayRef)> {
57 self.as_ref().named_children()
58 }
59
60 fn buffers(&self) -> Vec<ByteBuffer> {
61 self.as_ref().buffers()
62 }
63
64 fn nbuffers(&self) -> usize {
65 self.as_ref().nbuffers()
66 }
67
68 fn metadata(&self) -> VortexResult<Option<Vec<u8>>> {
69 self.as_ref().metadata()
70 }
71
72 fn metadata_fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
73 self.as_ref().metadata_fmt(f)
74 }
75}
76
77pub trait ArrayVisitorExt: Array {
78 fn nbuffers_recursive(&self) -> usize {
80 self.children()
81 .iter()
82 .map(ArrayVisitorExt::nbuffers_recursive)
83 .sum::<usize>()
84 + self.nbuffers()
85 }
86
87 fn depth_first_traversal(&self) -> impl Iterator<Item = ArrayRef> {
89 struct ArrayChildrenIterator {
91 stack: Vec<ArrayRef>,
92 }
93
94 impl Iterator for ArrayChildrenIterator {
95 type Item = ArrayRef;
96
97 fn next(&mut self) -> Option<Self::Item> {
98 let next = self.stack.pop()?;
99 for child in next.children().into_iter().rev() {
100 self.stack.push(child);
101 }
102 Some(next)
103 }
104 }
105
106 ArrayChildrenIterator {
107 stack: vec![self.to_array()],
108 }
109 }
110}
111
112impl<A: Array + ?Sized> ArrayVisitorExt for A {}
113
114pub trait ArrayBufferVisitor {
115 fn visit_buffer(&mut self, buffer: &ByteBuffer);
116}
117
118pub trait ArrayChildVisitor {
119 fn visit_child(&mut self, _name: &str, _array: &dyn Array);
121
122 fn visit_validity(&mut self, validity: &Validity, len: usize) {
124 if let Some(vlen) = validity.maybe_len() {
125 assert_eq!(vlen, len, "Validity length mismatch");
126 }
127
128 match validity {
129 Validity::NonNullable | Validity::AllValid => {}
130 Validity::AllInvalid => {
131 self.visit_child("validity", ConstantArray::new(false, len).deref())
138 }
139 Validity::Array(array) => {
140 self.visit_child("validity", array);
141 }
142 }
143 }
144
145 fn visit_patches(&mut self, patches: &Patches) {
147 self.visit_child("patch_indices", patches.indices());
148 self.visit_child("patch_values", patches.values());
149 }
150}