in parquet/src/arrow/arrow_writer/levels.rs [327:387]
fn write_struct(&mut self, array: &StructArray, range: Range<usize>) {
let (children, ctx) = match self {
Self::Struct(children, ctx) => (children, ctx),
_ => unreachable!(),
};
let write_null = |children: &mut [LevelInfoBuilder], range: Range<usize>| {
for child in children {
child.visit_leaves(|info| {
let len = range.end - range.start;
let def_levels = info.def_levels.as_mut().unwrap();
def_levels.extend(std::iter::repeat(ctx.def_level - 1).take(len));
if let Some(rep_levels) = info.rep_levels.as_mut() {
rep_levels.extend(std::iter::repeat(ctx.rep_level).take(len));
}
})
}
};
let write_non_null = |children: &mut [LevelInfoBuilder], range: Range<usize>| {
for (child_array, child) in array.columns().iter().zip(children) {
child.write(child_array, range.clone())
}
};
match array.nulls() {
Some(validity) => {
let mut last_non_null_idx = None;
let mut last_null_idx = None;
// TODO: Faster bitmask iteration (#1757)
for i in range.clone() {
match validity.is_valid(i) {
true => {
if let Some(last_idx) = last_null_idx.take() {
write_null(children, last_idx..i)
}
last_non_null_idx.get_or_insert(i);
}
false => {
if let Some(last_idx) = last_non_null_idx.take() {
write_non_null(children, last_idx..i)
}
last_null_idx.get_or_insert(i);
}
}
}
if let Some(last_idx) = last_null_idx.take() {
write_null(children, last_idx..range.end)
}
if let Some(last_idx) = last_non_null_idx.take() {
write_non_null(children, last_idx..range.end)
}
}
None => write_non_null(children, range),
}
}