Skip to main content

lance_encoding/
repdef.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright The Lance Authors
3
4//! Utilities for rep-def levels
5//!
6//! Repetition and definition levels are a way to encode multipile validity / offsets arrays
7//! into a single buffer.  They are a form of "zipping" buffers together that takes advantage
8//! of the fact that, if the outermost array is invalid, then the validity of the inner items
9//! is irrelevant.
10//!
11//! Note: the concept of repetition & definition levels comes from the Dremel paper and has
12//! been implemented in Apache Parquet.  However, the implementation here is not necessarily
13//! compatible with Parquet.  For example, we use 0 to represent the "inner-most" item and
14//! Parquet uses 0 to represent the "outer-most" item.
15//!
16//! # Repetition Levels
17//!
18//! With repetition levels we convert a sparse array of offsets into a dense array of levels.
19//! These levels are marked non-zero whenever a new list begins.  In other words, given the
20//! list array with 3 rows [{<0,1>, <>, <2>}, {<3>}, {}], [], [{<4>}] we would have three
21//! offsets arrays:
22//!
23//! Outer-most ([]): [0, 3, 3, 4]
24//! Middle     ({}): [0, 3, 4, 4, 5]
25//! Inner      (<>): [0, 2, 2, 3, 4, 5]
26//! Values         : [0, 1, 2, 3, 4]
27//!
28//! We can convert these into repetition levels as follows:
29//!
30//! | Values | Repetition |
31//! | ------ | ---------- |
32//! |      0 |          3 | // Start of outer-most list
33//! |      1 |          0 | // Continues inner-most list (no new lists)
34//! |      - |          1 | // Start of new inner-most list (empty list)
35//! |      2 |          1 | // Start of new inner-most list
36//! |      3 |          2 | // Start of new middle list
37//! |      - |          2 | // Start of new inner-most list (empty list)
38//! |      - |          3 | // Start of new outer-most list (empty list)
39//! |      4 |          0 | // Start of new outer-most list
40//!
41//! Note: We actually have MORE repetition levels than values.  This is because the repetition
42//! levels need to be able to represent empty lists.
43//!
44//! # Definition Levels
45//!
46//! Definition levels are simpler.  We can think of them as zipping together various validity bitmaps
47//! (from different levels of nesting) into a single buffer.  For example, we could zip the arrays
48//! [1, 1, 0, 0] and [1, 0, 1, 0] into [11, 10, 01, 00].  However, 00 and 01 are redundant.  If the
49//! outer level is null then the validity of the inner levels is irrelevant.  To save space we instead
50//! encode a "level" which is the "depth" of the null.  Let's look at a more complete example:
51//!
52//! Array: [{"middle": {"inner": 1]}}, NULL, {"middle": NULL}, {"middle": {"inner": NULL}}]
53//!
54//! In Arrow we would have the following validity arrays:
55//! Outer validity : 1, 0, 1, 1
56//! Middle validity: 1, ?, 0, 1
57//! Inner validity : 1, ?, ?, 0
58//! Values         : 1, ?, ?, ?
59//!
60//! The ? values are undefined in the Arrow format.  We can convert these into definition levels as follows:
61//!
62//! | Values | Definition |
63//! | ------ | ---------- |
64//! |      1 |          0 | // Valid at all levels
65//! |      - |          3 | // Null at outer level
66//! |      - |          2 | // Null at middle level
67//! |      - |          1 | // Null at inner level
68//!
69//! # Compression
70//!
71//! Note that we only need 2 bits of definition levels to represent 3 levels of nesting.  Definition
72//! levels are always more compact than the input validity arrays.  However, compressed levels are not
73//! necessarily more compact than the compressed validity arrays.
74//!
75//! Repetition levels are more complex.  If there are very large lists then a sparse array of offsets
76//! (which has one element per list) might be more compact than a dense array of repetition levels
77//! (which has one element per list value, possibly even more if there are empty lists).
78//!
79//! However, both repetition levels and definition levels are typically very compressible with RLE.
80//!
81//! However, in Lance we don't always take advantage of that compression because we want to be able
82//! to zip rep-def levels together with our values.  This gives us fewer IOPS when accessing row values.
83//!
84//! # Utilities in this Module
85//!
86//! - `RepDefBuilder` - Extracts validity and offset information from Arrow arrays.  We use this as we
87//!   shred the incoming data into primitive leaf arrays.  We don't immediately convert into rep-def because
88//!   we need to share and cheaply clone the builder when we have structs (each struct child shares some parent
89//!   validity / offset information)  The `serialize` method is called once all data has been received to create
90//!   the final rep-def levels.
91//!
92//! - `SerializerContext` - This is an internal utility that helps with serializing rep-def levels.
93//!
94//! - `CompositeRepDefUnraveler` - This structure is used to reverse the process.  It starts with a set of
95//!   rep-def levels and then uses the `unravel_validity` and `unravel_offsets` methods to produce validity
96//!   buffers and offset buffers.  It is "composite" because we may be combining sets of rep-def buffers from
97//!   multiple locations (e.g. multiple blocks in a mini-block encoded file).
98//!
99//! - `RepDefSlicer` - This is a utility that helps with slicing rep-def buffers.  These buffers are "kind of"
100//!   transparent (maps 1:1 with the values in the array) but not exactly because of the special (empty/null) lists.
101//!   The slicer helps with this issue and is used when slicing a rep-def buffer into mini-blocks.
102//!
103//! - `build_control_word_iterator` - This takes in rep-def levels and returns an iterator that returns byte-padded
104//!   "control words" which are used when creating full-zip encoded data.
105//!
106//! - `ControlWordParser` - This parser can parse the control words returned by `build_control_word_iterator` and is
107//!   used when decoding full-zip encoded data.
108
109use std::{
110    iter::{Copied, Zip},
111    ops::Range,
112    sync::Arc,
113};
114
115use arrow_array::OffsetSizeTrait;
116use arrow_buffer::{
117    ArrowNativeType, BooleanBuffer, BooleanBufferBuilder, NullBuffer, OffsetBuffer, ScalarBuffer,
118};
119use lance_core::{Error, Result, utils::bit::log_2_ceil};
120
121use crate::{
122    buffer::LanceBuffer,
123    encodings::logical::primitive::sparse::{SparseStructuralPlan, SparseStructuralUnraveler},
124};
125
126pub type LevelBuffer = Vec<u16>;
127
128/// A top-level-row range whose dense rep/def stream fits one mini-block page.
129#[derive(Debug, Clone, PartialEq, Eq)]
130pub(crate) struct MiniBlockRepDefSplit {
131    /// Top-level row offset, relative to the original unsplit page.
132    pub(crate) row_start: u64,
133    /// Number of top-level rows in this split.
134    pub(crate) num_rows: u64,
135    /// Rep/def level range, relative to the original unsplit page.
136    pub(crate) level_range: Range<usize>,
137    /// Visible value offset, relative to the original unsplit page.
138    pub(crate) value_start: u64,
139    /// Number of visible values in this split.
140    pub(crate) num_values: u64,
141}
142
143/// Dense mini-block rep/def budget result for one accumulated page.
144#[derive(Debug, Clone, PartialEq, Eq)]
145pub(crate) enum MiniBlockRepDefBudget {
146    /// The dense rep/def stream fits one mini-block structural page.
147    WithinBudget,
148    /// The dense rep/def stream fits after splitting on top-level row boundaries.
149    RequiresPageSplit(Vec<MiniBlockRepDefSplit>),
150    /// A single top-level row has this many rep/def levels and exceeds the budget.
151    SingleRowOverBudget(u64),
152}
153
154// As we build def levels we add this to special values to indicate that they
155// are special so that we can skip over them when processing lower levels.
156//
157// We assume 16 bits is good enough for rep-def levels.  This _would_ give
158// us 65536 levels of struct nesting and list nesting.  However, we cut that
159// in half for SPECIAL_THRESHOLD because we use the top bit to indicate if an
160// item is a special value (null list / empty list) during construction.
161//
162// We subtract this off at the end of construction to get the actual definition
163// levels.
164const SPECIAL_THRESHOLD: u16 = u16::MAX / 2;
165
166/// Represents information that we extract from a list array as we are
167/// encoding
168#[derive(Clone, Debug)]
169struct OffsetDesc {
170    offsets: Arc<[i64]>,
171    validity: Option<BooleanBuffer>,
172    has_empty_lists: bool,
173    num_values: usize,
174    num_specials: usize,
175}
176
177/// Represents validity information that we extract from non-list arrays (that
178/// have nulls) as we are encoding
179#[derive(Clone, Debug)]
180struct ValidityDesc {
181    validity: Option<BooleanBuffer>,
182    num_values: usize,
183}
184
185/// Represents validity information that we extract from FSL arrays.  This is
186/// just validity (no offsets) but we also record the dimension of the FSL array
187/// as that will impact the next layer
188#[derive(Clone, Debug)]
189struct FslDesc {
190    validity: Option<BooleanBuffer>,
191    dimension: usize,
192    num_values: usize,
193}
194
195// As we build up rep/def from arrow arrays we record a
196// series of RawRepDef objects.  Each one corresponds to layer
197// in the array structure
198#[derive(Clone, Debug)]
199enum RawRepDef {
200    Offsets(OffsetDesc),
201    Validity(ValidityDesc),
202    Fsl(FslDesc),
203}
204
205/// A normalized Arrow structural layer shared by dense and sparse serializers.
206#[derive(Clone, Copy, Debug)]
207pub(crate) enum NormalizedStructuralLayer<'a> {
208    List {
209        offsets: &'a [i64],
210        validity: Option<&'a BooleanBuffer>,
211        num_slots: usize,
212    },
213    Validity {
214        validity: Option<&'a BooleanBuffer>,
215        num_slots: usize,
216    },
217    FixedSizeList {
218        validity: Option<&'a BooleanBuffer>,
219        dimension: usize,
220        num_slots: usize,
221    },
222}
223
224/// Structural layers concatenated across input batches exactly once.
225///
226/// Dense rep/def serialization and sparse metadata planning both consume this
227/// representation so the Arrow nesting is not independently reconstructed.
228#[derive(Debug)]
229pub(crate) struct NormalizedStructuralPlan {
230    layers: Vec<RawRepDef>,
231    dense_all_valid: bool,
232}
233
234impl NormalizedStructuralPlan {
235    pub(crate) fn layers(&self) -> impl ExactSizeIterator<Item = NormalizedStructuralLayer<'_>> {
236        self.layers.iter().map(|layer| match layer {
237            RawRepDef::Offsets(OffsetDesc {
238                offsets,
239                validity,
240                num_values,
241                ..
242            }) => NormalizedStructuralLayer::List {
243                offsets,
244                validity: validity.as_ref(),
245                num_slots: *num_values,
246            },
247            RawRepDef::Validity(ValidityDesc {
248                validity,
249                num_values,
250            }) => NormalizedStructuralLayer::Validity {
251                validity: validity.as_ref(),
252                num_slots: *num_values,
253            },
254            RawRepDef::Fsl(FslDesc {
255                validity,
256                dimension,
257                num_values,
258            }) => NormalizedStructuralLayer::FixedSizeList {
259                validity: validity.as_ref(),
260                dimension: *dimension,
261                num_slots: *num_values,
262            },
263        })
264    }
265
266    fn to_serializer(&self) -> (SerializerContext, Option<u64>) {
267        if self.dense_all_valid {
268            let def_meaning = self
269                .layers
270                .iter()
271                .map(|_| DefinitionInterpretation::AllValidItem)
272                .collect::<Vec<_>>();
273            return (
274                SerializerContext {
275                    def_meaning,
276                    rep_levels: LevelBuffer::default(),
277                    spare_rep: LevelBuffer::default(),
278                    def_levels: LevelBuffer::default(),
279                    spare_def: LevelBuffer::default(),
280                    current_rep: 0,
281                    current_def: 0,
282                    current_len: 0,
283                    current_num_specials: 0,
284                    has_fsl: false,
285                },
286                None,
287            );
288        }
289
290        let total_len = self.layers.last().map_or(0, RawRepDef::num_values)
291            + self
292                .layers
293                .iter()
294                .map(RawRepDef::num_specials)
295                .sum::<usize>();
296        let max_rep = self.layers.iter().map(RawRepDef::max_rep).sum::<u16>();
297        let max_def = self.layers.iter().map(RawRepDef::max_def).sum::<u16>();
298        let bits_per_rep = if max_rep > 0 {
299            u64::from(u16::BITS - max_rep.leading_zeros())
300        } else {
301            0
302        };
303        let bits_per_def = if max_def > 0 {
304            u64::from(u16::BITS - max_def.leading_zeros())
305        } else {
306            0
307        };
308        let bits_per_level =
309            (bits_per_rep + bits_per_def > 0).then_some(bits_per_rep + bits_per_def);
310
311        let num_layers = self.layers.len();
312        let mut context = SerializerContext::new(total_len, num_layers, max_rep, max_def);
313        for layer in &self.layers {
314            match layer {
315                RawRepDef::Validity(def) => context.record_validity(def),
316                RawRepDef::Offsets(rep) => context.record_offsets(rep),
317                RawRepDef::Fsl(fsl) => context.record_fsl(fsl),
318            }
319        }
320        (context, bits_per_level)
321    }
322
323    pub(crate) fn serialize(&self) -> SerializedRepDefs {
324        self.to_serializer().0.build()
325    }
326
327    pub(crate) fn serialize_with_miniblock_repdef_budget(
328        &self,
329        max_levels_for_bits: impl FnOnce(u64) -> u64,
330        num_rows: u64,
331        num_values: u64,
332    ) -> Result<(SerializedRepDefs, MiniBlockRepDefBudget)> {
333        let (context, bits_per_level) = self.to_serializer();
334        context.build_with_miniblock_repdef_budget(
335            bits_per_level.map(max_levels_for_bits),
336            num_rows,
337            num_values,
338        )
339    }
340}
341
342impl RawRepDef {
343    // Are there any nulls in this layer
344    fn has_nulls(&self) -> bool {
345        match self {
346            Self::Offsets(OffsetDesc { validity, .. }) => validity.is_some(),
347            Self::Validity(ValidityDesc { validity, .. }) => validity.is_some(),
348            Self::Fsl(FslDesc { validity, .. }) => validity.is_some(),
349        }
350    }
351
352    // How many values are in this layer
353    fn num_values(&self) -> usize {
354        match self {
355            Self::Offsets(OffsetDesc { num_values, .. }) => *num_values,
356            Self::Validity(ValidityDesc { num_values, .. }) => *num_values,
357            Self::Fsl(FslDesc { num_values, .. }) => *num_values,
358        }
359    }
360
361    /// How many empty/null lists are in this layer
362    fn num_specials(&self) -> usize {
363        match self {
364            Self::Offsets(OffsetDesc { num_specials, .. }) => *num_specials,
365            _ => 0,
366        }
367    }
368
369    /// How many definition levels do we need for this layer
370    fn max_def(&self) -> u16 {
371        match self {
372            Self::Offsets(OffsetDesc {
373                has_empty_lists,
374                validity,
375                ..
376            }) => {
377                let mut max_def = 0;
378                if *has_empty_lists {
379                    max_def += 1;
380                }
381                if validity.is_some() {
382                    max_def += 1;
383                }
384                max_def
385            }
386            Self::Validity(ValidityDesc { validity: None, .. }) => 0,
387            Self::Validity(ValidityDesc { .. }) => 1,
388            Self::Fsl(FslDesc { validity: None, .. }) => 0,
389            Self::Fsl(FslDesc { .. }) => 1,
390        }
391    }
392
393    /// How many repetition levels do we need for this layer
394    fn max_rep(&self) -> u16 {
395        match self {
396            Self::Offsets(_) => 1,
397            _ => 0,
398        }
399    }
400}
401
402/// Represents repetition and definition levels that have been
403/// serialized into a pair of (optional) level buffers
404#[derive(Debug)]
405pub struct SerializedRepDefs {
406    /// The repetition levels, one per item
407    ///
408    /// If None, there are no lists
409    pub repetition_levels: Option<Arc<[u16]>>,
410    /// The definition levels, one per item
411    ///
412    /// If None, there are no nulls
413    pub definition_levels: Option<Arc<[u16]>>,
414    /// The meaning of each definition level
415    pub def_meaning: Vec<DefinitionInterpretation>,
416    /// The maximum level that is "visible" from the lowest level
417    ///
418    /// This is the last level before we encounter a list level of some kind.  Once we've
419    /// hit a list level then nulls in any level beyond do not map to actual items.
420    ///
421    /// This is None if there are no lists
422    pub max_visible_level: Option<u16>,
423    has_fsl: bool,
424}
425
426impl SerializedRepDefs {
427    fn max_visible_level(def_meaning: &[DefinitionInterpretation]) -> Option<u16> {
428        let first_list = def_meaning.iter().position(|level| level.is_list());
429        first_list.map(|first_list| {
430            def_meaning
431                .iter()
432                .map(|level| level.num_def_levels())
433                .take(first_list)
434                .sum::<u16>()
435        })
436    }
437
438    pub fn new(
439        repetition_levels: Option<LevelBuffer>,
440        definition_levels: Option<LevelBuffer>,
441        def_meaning: Vec<DefinitionInterpretation>,
442    ) -> Self {
443        Self::new_with_fixed_size_list_levels(
444            repetition_levels,
445            definition_levels,
446            def_meaning,
447            false,
448        )
449    }
450
451    pub(crate) fn new_with_fixed_size_list_levels(
452        repetition_levels: Option<LevelBuffer>,
453        definition_levels: Option<LevelBuffer>,
454        def_meaning: Vec<DefinitionInterpretation>,
455        has_fsl: bool,
456    ) -> Self {
457        let max_visible_level = Self::max_visible_level(&def_meaning);
458        Self {
459            repetition_levels: repetition_levels.map(Arc::from),
460            definition_levels: definition_levels.map(Arc::from),
461            def_meaning,
462            max_visible_level,
463            has_fsl,
464        }
465    }
466
467    /// Creates an empty SerializedRepDefs (no repetition, all valid)
468    pub fn empty(def_meaning: Vec<DefinitionInterpretation>) -> Self {
469        Self {
470            repetition_levels: None,
471            definition_levels: None,
472            def_meaning,
473            max_visible_level: None,
474            has_fsl: false,
475        }
476    }
477
478    pub fn rep_slicer(&self) -> Option<RepDefSlicer<'_>> {
479        self.repetition_levels
480            .as_ref()
481            .map(|rep| RepDefSlicer::new(self, rep.clone()))
482    }
483
484    pub fn def_slicer(&self) -> Option<RepDefSlicer<'_>> {
485        self.definition_levels
486            .as_ref()
487            .map(|def| RepDefSlicer::new(self, def.clone()))
488    }
489
490    pub(crate) fn has_fixed_size_list_levels(&self) -> bool {
491        self.has_fsl
492    }
493}
494
495/// Slices a level buffer into pieces
496///
497/// This is needed to handle the fact that a level buffer may have more
498/// levels than values due to special (empty/null) lists.
499///
500/// As a result, a call to `slice_next(10)` may return 10 levels or it may
501/// return more than 10 levels if any special values are encountered.
502#[derive(Debug)]
503pub struct RepDefSlicer<'a> {
504    repdef: &'a SerializedRepDefs,
505    to_slice: LanceBuffer,
506    current: usize,
507}
508
509// TODO: All of this logic will need some changing when we compress rep/def levels.
510impl<'a> RepDefSlicer<'a> {
511    fn new(repdef: &'a SerializedRepDefs, levels: Arc<[u16]>) -> Self {
512        Self {
513            repdef,
514            to_slice: LanceBuffer::reinterpret_slice(levels),
515            current: 0,
516        }
517    }
518
519    pub fn num_levels(&self) -> usize {
520        self.to_slice.len() / 2
521    }
522
523    pub fn num_levels_remaining(&self) -> usize {
524        self.num_levels() - self.current
525    }
526
527    pub fn all_levels(&self) -> &LanceBuffer {
528        &self.to_slice
529    }
530
531    /// Returns the rest of the levels not yet sliced
532    ///
533    /// This must be called instead of `slice_next` on the final iteration.
534    /// This is because anytime we slice there may be empty/null lists on the
535    /// boundary that are "free" and the current behavior in `slice_next` is to
536    /// leave them for the next call.
537    ///
538    /// `slice_rest` will slice all remaining levels and return them.
539    pub fn slice_rest(&mut self) -> LanceBuffer {
540        let start = self.current;
541        let remaining = self.num_levels_remaining();
542        self.current = self.num_levels();
543        self.to_slice.slice_with_length(start * 2, remaining * 2)
544    }
545
546    /// Returns enough levels to satisfy the next `num_values` values
547    pub fn slice_next(&mut self, num_values: usize) -> LanceBuffer {
548        let start = self.current;
549        let Some(max_visible_level) = self.repdef.max_visible_level else {
550            // No lists, should be 1:1 mapping from levels to values
551            self.current = start + num_values;
552            return self.to_slice.slice_with_length(start * 2, num_values * 2);
553        };
554        if let Some(def) = self.repdef.definition_levels.as_ref() {
555            // There are lists and there are def levels.  That means there may be
556            // more rep/def levels than values.  We need to scan the def levels to figure
557            // out which items are "invisible" and skip over them
558            let mut def_itr = def[start..].iter();
559            let mut num_taken = 0;
560            let mut num_passed = 0;
561            while num_taken < num_values {
562                let def_level = *def_itr.next().unwrap();
563                if def_level <= max_visible_level {
564                    num_taken += 1;
565                }
566                num_passed += 1;
567            }
568            self.current = start + num_passed;
569            self.to_slice.slice_with_length(start * 2, num_passed * 2)
570        } else {
571            // No def levels, should be 1:1 mapping from levels to values
572            self.current = start + num_values;
573            self.to_slice.slice_with_length(start * 2, num_values * 2)
574        }
575    }
576}
577
578/// This tells us how an array handles definition.  Given a stack of
579/// these and a nested array and a set of definition levels we can calculate
580/// how we should interpret the definition levels.
581///
582/// For example, if the interpretation is [AllValidItem, NullableItem] then
583/// a 0 means "valid item" and a 1 means "null struct".  If the interpretation
584/// is [NullableItem, NullableItem] then a 0 means "valid item" and a 1 means
585/// "null item" and a 2 means "null struct".
586///
587/// Lists are tricky because we might use up to two definition levels for a
588/// single layer of list nesting because we need one value to indicate "empty list"
589/// and another value to indicate "null list".
590#[derive(Debug, Copy, Clone, PartialEq, Eq)]
591pub enum DefinitionInterpretation {
592    AllValidItem,
593    AllValidList,
594    NullableItem,
595    NullableList,
596    EmptyableList,
597    NullableAndEmptyableList,
598}
599
600impl DefinitionInterpretation {
601    /// How many definition levels do we need for this layer
602    pub fn num_def_levels(&self) -> u16 {
603        match self {
604            Self::AllValidItem => 0,
605            Self::AllValidList => 0,
606            Self::NullableItem => 1,
607            Self::NullableList => 1,
608            Self::EmptyableList => 1,
609            Self::NullableAndEmptyableList => 2,
610        }
611    }
612
613    /// Does this layer have nulls?
614    pub fn is_all_valid(&self) -> bool {
615        matches!(
616            self,
617            Self::AllValidItem | Self::AllValidList | Self::EmptyableList
618        )
619    }
620
621    /// Does this layer represent a list?
622    pub fn is_list(&self) -> bool {
623        matches!(
624            self,
625            Self::AllValidList
626                | Self::NullableList
627                | Self::EmptyableList
628                | Self::NullableAndEmptyableList
629        )
630    }
631}
632
633/// The RepDefBuilder is used to collect offsets & validity buffers
634/// from arrow structures.  Once we have those we use the SerializerContext
635/// to build the actual repetition and definition levels.
636///
637/// We know ahead of time how many rep/def levels we will need (number of items
638/// in inner-most array + the number of empty/null lists in any parent arrays).
639///
640/// As a result we try and avoid any re-allocations by pre-allocating the buffers
641/// up front.  We allocate two copies of each buffer which allows us to avoid unsafe
642/// code caused by reading and writing to the same buffer (also, it's unavoidable
643/// because there are times we need to write 'faster' than we read)
644#[derive(Debug)]
645struct SerializerContext {
646    // This is built from outer-to-inner and then reversed at the end
647    def_meaning: Vec<DefinitionInterpretation>,
648    rep_levels: LevelBuffer,
649    spare_rep: LevelBuffer,
650    def_levels: LevelBuffer,
651    spare_def: LevelBuffer,
652    current_rep: u16,
653    current_def: u16,
654    current_len: usize,
655    current_num_specials: usize,
656    has_fsl: bool,
657}
658
659impl SerializerContext {
660    fn new(len: usize, num_layers: usize, max_rep: u16, max_def: u16) -> Self {
661        let def_meaning = Vec::with_capacity(num_layers);
662        Self {
663            rep_levels: if max_rep > 0 {
664                vec![0; len]
665            } else {
666                LevelBuffer::default()
667            },
668            spare_rep: if max_rep > 0 {
669                vec![0; len]
670            } else {
671                LevelBuffer::default()
672            },
673            def_levels: if max_def > 0 {
674                vec![0; len]
675            } else {
676                LevelBuffer::default()
677            },
678            spare_def: if max_def > 0 {
679                vec![0; len]
680            } else {
681                LevelBuffer::default()
682            },
683            def_meaning,
684            current_rep: max_rep,
685            current_def: max_def,
686            current_len: 0,
687            current_num_specials: 0,
688            has_fsl: false,
689        }
690    }
691
692    fn checkout_def(&mut self, meaning: DefinitionInterpretation) -> u16 {
693        let def = self.current_def;
694        self.current_def -= meaning.num_def_levels();
695        self.def_meaning.push(meaning);
696        def
697    }
698
699    fn record_offsets(&mut self, offset_desc: &OffsetDesc) {
700        let rep_level = self.current_rep;
701        let (null_list_level, empty_list_level) =
702            match (offset_desc.validity.is_some(), offset_desc.has_empty_lists) {
703                (true, true) => {
704                    let level =
705                        self.checkout_def(DefinitionInterpretation::NullableAndEmptyableList);
706                    (level - 1, level)
707                }
708                (true, false) => (self.checkout_def(DefinitionInterpretation::NullableList), 0),
709                (false, true) => (
710                    0,
711                    self.checkout_def(DefinitionInterpretation::EmptyableList),
712                ),
713                (false, false) => {
714                    self.checkout_def(DefinitionInterpretation::AllValidList);
715                    (0, 0)
716                }
717            };
718        self.current_rep -= 1;
719
720        if let Some(validity) = &offset_desc.validity {
721            self.do_record_validity(validity, null_list_level);
722        }
723
724        // We write into the spare buffers and read from the active buffers
725        // and then swap at the end.  This way we don't write over what we
726        // are reading.
727
728        let mut new_len = 0;
729        let expected_len = offset_desc.num_values + self.current_num_specials;
730        if expected_len == 0 {
731            // Offsets [0] mean no list values, so no levels.
732            self.current_len = 0;
733            return;
734        }
735        assert!(self.rep_levels.len() >= expected_len - 1);
736        if self.def_levels.is_empty() {
737            let mut write_itr = self.spare_rep.iter_mut();
738            let mut read_iter = self.rep_levels.iter().copied();
739            for w in offset_desc.offsets.windows(2) {
740                let len = w[1] - w[0];
741                // len can't be 0 because then we'd have def levels
742                assert!(len > 0);
743                let rep = read_iter.next().unwrap();
744                let list_level = if rep == 0 { rep_level } else { rep };
745                *write_itr.next().unwrap() = list_level;
746
747                for _ in 1..len {
748                    *write_itr.next().unwrap() = 0;
749                }
750                new_len += len as usize;
751            }
752            std::mem::swap(&mut self.rep_levels, &mut self.spare_rep);
753        } else {
754            assert!(self.def_levels.len() >= expected_len - 1);
755            let mut def_write_itr = self.spare_def.iter_mut();
756            let mut rep_write_itr = self.spare_rep.iter_mut();
757            let mut rep_read_itr = self.rep_levels.iter().copied();
758            let mut def_read_itr = self.def_levels.iter().copied();
759            let specials_to_pass = self.current_num_specials;
760            let mut specials_passed = 0;
761
762            for w in offset_desc.offsets.windows(2) {
763                let mut def = def_read_itr.next().unwrap();
764                // Copy over any higher-level special values in place
765                while def > SPECIAL_THRESHOLD {
766                    *def_write_itr.next().unwrap() = def;
767                    *rep_write_itr.next().unwrap() = rep_read_itr.next().unwrap();
768                    def = def_read_itr.next().unwrap();
769                    new_len += 1;
770                    specials_passed += 1;
771                }
772
773                let len = w[1] - w[0];
774                let rep = rep_read_itr.next().unwrap();
775
776                // If the rep_level is 0 then we are the first list level
777                // otherwise we are starting a higher level list so keep
778                // existing rep level
779                let list_level = if rep == 0 { rep_level } else { rep };
780
781                if def == 0 && len > 0 {
782                    // New valid list, write a rep level and then add new 0/0 items
783                    *def_write_itr.next().unwrap() = 0;
784                    *rep_write_itr.next().unwrap() = list_level;
785
786                    for _ in 1..len {
787                        *def_write_itr.next().unwrap() = 0;
788                        *rep_write_itr.next().unwrap() = 0;
789                    }
790
791                    new_len += len as usize;
792                } else if def == 0 {
793                    // Empty list, insert new special
794                    *def_write_itr.next().unwrap() = empty_list_level + SPECIAL_THRESHOLD;
795                    *rep_write_itr.next().unwrap() = list_level;
796                    new_len += 1;
797                } else {
798                    // Either the list is null or one of its struct parents
799                    // is null.  Promote it to a special value.
800                    *def_write_itr.next().unwrap() = def + SPECIAL_THRESHOLD;
801                    *rep_write_itr.next().unwrap() = list_level;
802                    new_len += 1;
803                }
804            }
805
806            // If we have any special values at the end, we need to copy them over
807            while specials_passed < specials_to_pass {
808                *def_write_itr.next().unwrap() = def_read_itr.next().unwrap();
809                *rep_write_itr.next().unwrap() = rep_read_itr.next().unwrap();
810                new_len += 1;
811                specials_passed += 1;
812            }
813            std::mem::swap(&mut self.def_levels, &mut self.spare_def);
814            std::mem::swap(&mut self.rep_levels, &mut self.spare_rep);
815        }
816
817        self.current_len = new_len;
818        self.current_num_specials += offset_desc.num_specials;
819    }
820
821    fn do_record_validity(&mut self, validity: &BooleanBuffer, null_level: u16) {
822        assert!(self.def_levels.len() >= validity.len() + self.current_num_specials);
823        debug_assert!(
824            self.current_len == 0 || self.current_len == validity.len() + self.current_num_specials
825        );
826        self.current_len = validity.len();
827
828        let mut def_read_itr = self.def_levels.iter().copied();
829        let mut def_write_itr = self.spare_def.iter_mut();
830
831        let specials_to_pass = self.current_num_specials;
832        let mut specials_passed = 0;
833
834        for incoming_validity in validity.iter() {
835            let mut def = def_read_itr.next().unwrap();
836            while def > SPECIAL_THRESHOLD {
837                *def_write_itr.next().unwrap() = def;
838                def = def_read_itr.next().unwrap();
839                specials_passed += 1;
840            }
841            if def == 0 && !incoming_validity {
842                *def_write_itr.next().unwrap() = null_level;
843            } else {
844                *def_write_itr.next().unwrap() = def;
845            }
846        }
847
848        while specials_passed < specials_to_pass {
849            *def_write_itr.next().unwrap() = def_read_itr.next().unwrap();
850            specials_passed += 1;
851        }
852
853        std::mem::swap(&mut self.def_levels, &mut self.spare_def);
854    }
855
856    fn multiply_levels(&mut self, multiplier: usize) {
857        let old_len = self.current_len;
858        // All non-special values will be broadcasted by the multiplier.  Special values are copied as-is.
859        self.current_len =
860            (self.current_len - self.current_num_specials) * multiplier + self.current_num_specials;
861
862        if self.rep_levels.is_empty() && self.def_levels.is_empty() {
863            // All valid with no rep/def levels, nothing to do
864            return;
865        } else if self.rep_levels.is_empty() {
866            assert!(self.def_levels.len() >= self.current_len);
867            // No rep levels, just multiply the def levels
868            let mut def_read_itr = self.def_levels.iter().copied();
869            let mut def_write_itr = self.spare_def.iter_mut();
870            for _ in 0..old_len {
871                let mut def = def_read_itr.next().unwrap();
872                while def > SPECIAL_THRESHOLD {
873                    *def_write_itr.next().unwrap() = def;
874                    def = def_read_itr.next().unwrap();
875                }
876                for _ in 0..multiplier {
877                    *def_write_itr.next().unwrap() = def;
878                }
879            }
880        } else if self.def_levels.is_empty() {
881            assert!(self.rep_levels.len() >= self.current_len);
882            // No def levels, just multiply the rep levels
883            let mut rep_read_itr = self.rep_levels.iter().copied();
884            let mut rep_write_itr = self.spare_rep.iter_mut();
885            for _ in 0..old_len {
886                let rep = rep_read_itr.next().unwrap();
887                for _ in 0..multiplier {
888                    *rep_write_itr.next().unwrap() = rep;
889                }
890            }
891        } else {
892            assert!(self.rep_levels.len() >= self.current_len);
893            assert!(self.def_levels.len() >= self.current_len);
894            let mut rep_read_itr = self.rep_levels.iter().copied();
895            let mut def_read_itr = self.def_levels.iter().copied();
896            let mut rep_write_itr = self.spare_rep.iter_mut();
897            let mut def_write_itr = self.spare_def.iter_mut();
898            for _ in 0..old_len {
899                let mut def = def_read_itr.next().unwrap();
900                while def > SPECIAL_THRESHOLD {
901                    *def_write_itr.next().unwrap() = def;
902                    *rep_write_itr.next().unwrap() = rep_read_itr.next().unwrap();
903                    def = def_read_itr.next().unwrap();
904                }
905                let rep = rep_read_itr.next().unwrap();
906                for _ in 0..multiplier {
907                    *def_write_itr.next().unwrap() = def;
908                    *rep_write_itr.next().unwrap() = rep;
909                }
910            }
911        }
912        std::mem::swap(&mut self.def_levels, &mut self.spare_def);
913        std::mem::swap(&mut self.rep_levels, &mut self.spare_rep);
914    }
915
916    fn record_validity_buf(&mut self, validity: &Option<BooleanBuffer>) {
917        if let Some(validity) = validity {
918            let def_level = self.checkout_def(DefinitionInterpretation::NullableItem);
919            self.do_record_validity(validity, def_level);
920        } else {
921            self.checkout_def(DefinitionInterpretation::AllValidItem);
922        }
923    }
924
925    fn record_validity(&mut self, validity_desc: &ValidityDesc) {
926        self.record_validity_buf(&validity_desc.validity)
927    }
928
929    fn record_fsl(&mut self, fsl_desc: &FslDesc) {
930        self.has_fsl = true;
931        self.record_validity_buf(&fsl_desc.validity);
932        self.multiply_levels(fsl_desc.dimension);
933    }
934
935    fn normalize_specials(&mut self) {
936        for def in self.def_levels.iter_mut() {
937            if *def > SPECIAL_THRESHOLD {
938                *def -= SPECIAL_THRESHOLD;
939            }
940        }
941    }
942
943    fn normalize_specials_and_plan_splits(
944        &mut self,
945        def_meaning: &[DefinitionInterpretation],
946        max_levels_per_page: Option<u64>,
947        num_rows: u64,
948        num_values: u64,
949    ) -> Result<MiniBlockRepDefBudget> {
950        // Extremely sparse lists can have many rep/def levels for very few
951        // visible leaf values.  If this ratio becomes too skewed then a
952        // mini-block rep/def chunk can exceed its packed metadata budget even
953        // though the value buffers are small.  We detect that case while
954        // normalizing special def levels and split on top-level row boundaries
955        // so each emitted dense mini-block page stays within the budget.
956        if self.def_levels.is_empty() {
957            return Ok(MiniBlockRepDefBudget::WithinBudget);
958        }
959
960        if self.rep_levels.is_empty() {
961            self.normalize_specials();
962            return Ok(MiniBlockRepDefBudget::WithinBudget);
963        }
964
965        if self.rep_levels.len() != self.def_levels.len() {
966            return Err(Error::internal(format!(
967                "Cannot plan structural page splits with mismatched rep/def lengths: rep={}, def={}",
968                self.rep_levels.len(),
969                self.def_levels.len()
970            )));
971        }
972
973        let Some(max_levels_per_page) = max_levels_per_page else {
974            self.normalize_specials();
975            return Ok(MiniBlockRepDefBudget::WithinBudget);
976        };
977
978        if num_values == 0 {
979            self.normalize_specials();
980            return Ok(MiniBlockRepDefBudget::WithinBudget);
981        }
982
983        let max_schema_rep = def_meaning.iter().filter(|level| level.is_list()).count() as u16;
984        let max_visible_level = SerializedRepDefs::max_visible_level(def_meaning);
985        let should_plan = !self.has_fsl && max_schema_rep > 0 && max_visible_level.is_some();
986
987        if !should_plan {
988            self.normalize_specials();
989            return Ok(MiniBlockRepDefBudget::WithinBudget);
990        }
991
992        let max_visible_level = max_visible_level.unwrap();
993        let mut splits = Vec::new();
994        let mut counted_rows = 0u64;
995        let mut counted_values = 0u64;
996        let mut saw_structural_overhead = false;
997        let mut single_row_over_budget_levels = None;
998
999        let mut current_row_level_start = None;
1000        let mut current_row_num_values = 0u64;
1001
1002        let mut current_page_row_start = 0u64;
1003        let mut current_page_num_rows = 0u64;
1004        let mut current_page_level_start = 0usize;
1005        let mut current_page_level_end = 0usize;
1006        let mut current_page_value_start = 0u64;
1007        let mut current_page_num_values = 0u64;
1008        let mut current_page_num_levels = 0u64;
1009        let mut current_page_has_structural_overhead = false;
1010
1011        let mut finish_row =
1012            |row_level_start: usize, row_level_end: usize, row_num_values: u64| -> Result<()> {
1013                let row_num_levels = (row_level_end - row_level_start) as u64;
1014                let row_has_structural_overhead = row_num_levels > row_num_values;
1015                saw_structural_overhead |= row_has_structural_overhead;
1016
1017                if row_has_structural_overhead && row_num_levels > max_levels_per_page {
1018                    single_row_over_budget_levels = Some(row_num_levels);
1019                }
1020
1021                if current_page_num_rows > 0
1022                    && (current_page_has_structural_overhead || row_has_structural_overhead)
1023                    && current_page_num_levels + row_num_levels > max_levels_per_page
1024                {
1025                    splits.push(MiniBlockRepDefSplit {
1026                        row_start: current_page_row_start,
1027                        num_rows: current_page_num_rows,
1028                        level_range: current_page_level_start..current_page_level_end,
1029                        value_start: current_page_value_start,
1030                        num_values: current_page_num_values,
1031                    });
1032                    current_page_row_start = counted_rows;
1033                    current_page_num_rows = 0;
1034                    current_page_level_start = row_level_start;
1035                    current_page_value_start = counted_values;
1036                    current_page_num_values = 0;
1037                    current_page_num_levels = 0;
1038                    current_page_has_structural_overhead = false;
1039                }
1040
1041                if current_page_num_rows == 0 {
1042                    current_page_level_start = row_level_start;
1043                }
1044                current_page_num_rows += 1;
1045                current_page_level_end = row_level_end;
1046                current_page_num_values += row_num_values;
1047                current_page_num_levels += row_num_levels;
1048                current_page_has_structural_overhead |= row_has_structural_overhead;
1049                counted_rows += 1;
1050                counted_values += row_num_values;
1051                Ok(())
1052            };
1053
1054        for (idx, (rep_level, def_level)) in self
1055            .rep_levels
1056            .iter()
1057            .copied()
1058            .zip(self.def_levels.iter_mut())
1059            .enumerate()
1060        {
1061            if *def_level > SPECIAL_THRESHOLD {
1062                *def_level -= SPECIAL_THRESHOLD;
1063            }
1064
1065            if rep_level == max_schema_rep {
1066                if let Some(level_start) = current_row_level_start {
1067                    finish_row(level_start, idx, current_row_num_values)?;
1068                    current_row_num_values = 0;
1069                } else if idx != 0 {
1070                    return Err(Error::internal(format!(
1071                        "Cannot plan structural page splits: first top-level row starts at level {}, expected 0",
1072                        idx
1073                    )));
1074                }
1075                current_row_level_start = Some(idx);
1076            }
1077
1078            if current_row_level_start.is_none() {
1079                return Err(Error::internal(
1080                    "Cannot plan structural page splits: found levels before the first top-level row start",
1081                ));
1082            }
1083            if *def_level <= max_visible_level {
1084                current_row_num_values += 1;
1085            }
1086        }
1087
1088        let Some(level_start) = current_row_level_start else {
1089            return Err(Error::internal(
1090                "Cannot plan structural page splits: found no top-level row starts",
1091            ));
1092        };
1093        finish_row(level_start, self.rep_levels.len(), current_row_num_values)?;
1094
1095        if counted_rows != num_rows {
1096            return Err(Error::internal(format!(
1097                "Cannot plan structural page splits: expected {} top-level row starts, found {}",
1098                num_rows, counted_rows
1099            )));
1100        }
1101        if counted_values != num_values {
1102            return Err(Error::internal(format!(
1103                "Cannot plan structural page splits: counted {} visible values, expected {}",
1104                counted_values, num_values
1105            )));
1106        }
1107        if !saw_structural_overhead {
1108            return Ok(MiniBlockRepDefBudget::WithinBudget);
1109        }
1110        if let Some(row_num_levels) = single_row_over_budget_levels {
1111            return Ok(MiniBlockRepDefBudget::SingleRowOverBudget(row_num_levels));
1112        }
1113
1114        if current_page_num_rows > 0 {
1115            splits.push(MiniBlockRepDefSplit {
1116                row_start: current_page_row_start,
1117                num_rows: current_page_num_rows,
1118                level_range: current_page_level_start..current_page_level_end,
1119                value_start: current_page_value_start,
1120                num_values: current_page_num_values,
1121            });
1122        }
1123
1124        if splits.len() > 1 {
1125            Ok(MiniBlockRepDefBudget::RequiresPageSplit(splits))
1126        } else {
1127            Ok(MiniBlockRepDefBudget::WithinBudget)
1128        }
1129    }
1130
1131    fn build(mut self) -> SerializedRepDefs {
1132        if self.current_len == 0 {
1133            return SerializedRepDefs::new_with_fixed_size_list_levels(
1134                None,
1135                None,
1136                self.def_meaning,
1137                self.has_fsl,
1138            );
1139        }
1140
1141        self.normalize_specials();
1142
1143        let definition_levels = if self.def_levels.is_empty() {
1144            None
1145        } else {
1146            Some(self.def_levels)
1147        };
1148        let repetition_levels = if self.rep_levels.is_empty() {
1149            None
1150        } else {
1151            Some(self.rep_levels)
1152        };
1153
1154        // Need to reverse the def meaning since we build rep / def levels in reverse
1155        let def_meaning = self.def_meaning.into_iter().rev().collect::<Vec<_>>();
1156
1157        SerializedRepDefs::new_with_fixed_size_list_levels(
1158            repetition_levels,
1159            definition_levels,
1160            def_meaning,
1161            self.has_fsl,
1162        )
1163    }
1164
1165    fn build_with_miniblock_repdef_budget(
1166        mut self,
1167        max_levels_per_page: Option<u64>,
1168        num_rows: u64,
1169        num_values: u64,
1170    ) -> Result<(SerializedRepDefs, MiniBlockRepDefBudget)> {
1171        if self.current_len == 0 {
1172            return Ok((
1173                SerializedRepDefs::new_with_fixed_size_list_levels(
1174                    None,
1175                    None,
1176                    self.def_meaning,
1177                    self.has_fsl,
1178                ),
1179                MiniBlockRepDefBudget::WithinBudget,
1180            ));
1181        }
1182
1183        // Need to reverse the def meaning since we build rep / def levels in reverse
1184        let def_meaning = std::mem::take(&mut self.def_meaning)
1185            .into_iter()
1186            .rev()
1187            .collect::<Vec<_>>();
1188        let budget = self.normalize_specials_and_plan_splits(
1189            &def_meaning,
1190            max_levels_per_page,
1191            num_rows,
1192            num_values,
1193        )?;
1194
1195        let definition_levels = if self.def_levels.is_empty() {
1196            None
1197        } else {
1198            Some(self.def_levels)
1199        };
1200        let repetition_levels = if self.rep_levels.is_empty() {
1201            None
1202        } else {
1203            Some(self.rep_levels)
1204        };
1205
1206        Ok((
1207            SerializedRepDefs::new_with_fixed_size_list_levels(
1208                repetition_levels,
1209                definition_levels,
1210                def_meaning,
1211                self.has_fsl,
1212            ),
1213            budget,
1214        ))
1215    }
1216}
1217
1218/// A structure used to collect validity buffers and offsets from arrow
1219/// arrays and eventually create repetition and definition levels
1220///
1221/// As we are encoding the structural encoders are given this struct and
1222/// will record the arrow information into it.  Once we hit a leaf node we
1223/// serialize the data into rep/def levels and write these into the page.
1224#[derive(Clone, Default, Debug)]
1225pub struct RepDefBuilder {
1226    // The rep/def info we have collected so far
1227    repdefs: Vec<RawRepDef>,
1228    // The current length, can get larger as we traverse lists (e.g. an
1229    // array might have 5 lists which results in 50 items)
1230    //
1231    // Starts uninitialized until we see the first rep/def item
1232    len: Option<usize>,
1233}
1234
1235impl RepDefBuilder {
1236    fn check_validity_len(&mut self, incoming_len: usize) {
1237        if let Some(len) = self.len {
1238            assert_eq!(incoming_len, len);
1239        } else {
1240            // First validity buffer we've seen
1241            self.len = Some(incoming_len);
1242        }
1243    }
1244
1245    fn num_layers(&self) -> usize {
1246        self.repdefs.len()
1247    }
1248
1249    /// The builder is "empty" if there is no repetition and no nulls.  In this case we don't need
1250    /// to store anything to disk (except the description)
1251    pub fn is_empty(&self) -> bool {
1252        self.repdefs
1253            .iter()
1254            .all(|r| matches!(r, RawRepDef::Validity(ValidityDesc { validity: None, .. })))
1255    }
1256
1257    /// Returns true if there is only a single layer of definition
1258    pub fn is_simple_validity(&self) -> bool {
1259        self.repdefs.len() == 1 && matches!(self.repdefs[0], RawRepDef::Validity(_))
1260    }
1261
1262    /// Registers a nullable validity bitmap
1263    pub fn add_validity_bitmap(&mut self, validity: NullBuffer) {
1264        self.check_validity_len(validity.len());
1265        if validity.null_count() == 0 {
1266            self.add_no_null(validity.len());
1267            return;
1268        }
1269        self.repdefs.push(RawRepDef::Validity(ValidityDesc {
1270            num_values: validity.len(),
1271            validity: Some(validity.into_inner()),
1272        }));
1273    }
1274
1275    /// Registers an all-valid validity layer
1276    pub fn add_no_null(&mut self, len: usize) {
1277        self.check_validity_len(len);
1278        self.repdefs.push(RawRepDef::Validity(ValidityDesc {
1279            validity: None,
1280            num_values: len,
1281        }));
1282    }
1283
1284    pub fn add_fsl(&mut self, validity: Option<NullBuffer>, dimension: usize, num_values: usize) {
1285        if let Some(len) = self.len {
1286            assert_eq!(num_values, len);
1287        }
1288        self.len = Some(num_values * dimension);
1289        debug_assert!(validity.is_none() || validity.as_ref().unwrap().len() == num_values);
1290        self.repdefs.push(RawRepDef::Fsl(FslDesc {
1291            num_values,
1292            validity: validity.map(|v| v.into_inner()),
1293            dimension,
1294        }))
1295    }
1296
1297    fn check_offset_len(&mut self, offsets: &[i64]) {
1298        if let Some(len) = self.len {
1299            assert!(offsets.len() == len + 1);
1300        }
1301        self.len = Some(offsets[offsets.len() - 1] as usize);
1302    }
1303
1304    fn do_add_offsets(
1305        &mut self,
1306        lengths: impl Iterator<Item = i64>,
1307        validity: Option<NullBuffer>,
1308        capacity: usize,
1309    ) -> bool {
1310        let mut num_specials = 0;
1311        let mut has_empty_lists = false;
1312        let mut has_garbage_values = false;
1313        let mut last_off: i64 = 0;
1314
1315        let mut normalized_offsets = Vec::with_capacity(capacity);
1316        normalized_offsets.push(0);
1317
1318        if let Some(ref validity) = validity {
1319            for (len, is_valid) in lengths.zip(validity.iter()) {
1320                match (is_valid, len == 0) {
1321                    (false, is_empty) => {
1322                        num_specials += 1;
1323                        has_garbage_values |= !is_empty;
1324                    }
1325                    (true, true) => {
1326                        num_specials += 1;
1327                        has_empty_lists = true;
1328                    }
1329                    _ => {
1330                        last_off += len;
1331                    }
1332                }
1333                normalized_offsets.push(last_off);
1334            }
1335        } else {
1336            for len in lengths {
1337                if len == 0 {
1338                    num_specials += 1;
1339                    has_empty_lists = true;
1340                }
1341                last_off += len;
1342                normalized_offsets.push(last_off);
1343            }
1344        }
1345
1346        self.check_offset_len(&normalized_offsets);
1347        self.repdefs.push(RawRepDef::Offsets(OffsetDesc {
1348            num_values: normalized_offsets.len() - 1,
1349            offsets: normalized_offsets.into(),
1350            validity: validity.map(|v| v.into_inner()),
1351            has_empty_lists,
1352            num_specials: num_specials as usize,
1353        }));
1354
1355        has_garbage_values
1356    }
1357
1358    /// Adds a layer of offsets
1359    ///
1360    /// Offsets are casted to a common type (i64) and also normalized.  Null lists are
1361    /// always represented by a zero-length (identical) pair of offsets and so the caller
1362    /// should filter out any garbage items before encoding them.  To assist with this the
1363    /// method will return true if any non-empty null lists were found.
1364    pub fn add_offsets<O: OffsetSizeTrait>(
1365        &mut self,
1366        offsets: OffsetBuffer<O>,
1367        validity: Option<NullBuffer>,
1368    ) -> bool {
1369        let inner = offsets.into_inner();
1370        let buffer_len = inner.len();
1371
1372        if O::IS_LARGE {
1373            let i64_buff = ScalarBuffer::<i64>::new(inner.into_inner(), 0, buffer_len);
1374            let lengths = i64_buff.windows(2).map(|off| off[1] - off[0]);
1375            self.do_add_offsets(lengths, validity, buffer_len)
1376        } else {
1377            let i32_buff = ScalarBuffer::<i32>::new(inner.into_inner(), 0, buffer_len);
1378            let lengths = i32_buff.windows(2).map(|off| (off[1] - off[0]) as i64);
1379            self.do_add_offsets(lengths, validity, buffer_len)
1380        }
1381    }
1382
1383    // When we are encoding data it arrives in batches.  For each batch we create a RepDefBuilder and collect the
1384    // various validity buffers and offset buffers from that batch.  Once we have enough batches to write a page we
1385    // need to take this collection of RepDefBuilders and concatenate them and then serialize them into rep/def levels.
1386    //
1387    // TODO: In the future, we may concatenate and serialize at the same time?
1388    //
1389    // This method takes care of the concatenation part.  First we collect all of layer 0 from each builder, then we
1390    // call this method.  Then we collect all of layer 1 from each builder and call this method.  And so on.
1391    //
1392    // That means this method should get a collection of `RawRepDef` where each item is the same kind (all validity or
1393    // all offsets) though the nullability / lengths may be different in each layer.
1394    fn concat_layers<'a>(
1395        layers: impl Iterator<Item = &'a RawRepDef>,
1396        num_layers: usize,
1397    ) -> RawRepDef {
1398        enum LayerKind {
1399            Validity,
1400            Fsl,
1401            Offsets,
1402        }
1403
1404        // We make two passes through the layers.  The first determines if we need to pay the cost of allocating
1405        // buffers.  The second pass actually adds the values.
1406        let mut collected = Vec::with_capacity(num_layers);
1407        let mut has_nulls = false;
1408        let mut layer_kind = LayerKind::Validity;
1409        let mut total_num_specials = 0;
1410        let mut all_dimension = 0;
1411        let mut all_has_empty_lists = false;
1412        let mut all_num_values = 0;
1413        for layer in layers {
1414            has_nulls |= layer.has_nulls();
1415            match layer {
1416                RawRepDef::Validity(_) => {
1417                    layer_kind = LayerKind::Validity;
1418                }
1419                RawRepDef::Offsets(OffsetDesc {
1420                    num_specials,
1421                    has_empty_lists,
1422                    ..
1423                }) => {
1424                    all_has_empty_lists |= *has_empty_lists;
1425                    layer_kind = LayerKind::Offsets;
1426                    total_num_specials += num_specials;
1427                }
1428                RawRepDef::Fsl(FslDesc { dimension, .. }) => {
1429                    layer_kind = LayerKind::Fsl;
1430                    all_dimension = *dimension;
1431                }
1432            }
1433            collected.push(layer);
1434            all_num_values += layer.num_values();
1435        }
1436
1437        // Shortcut if there are no nulls
1438        if !has_nulls {
1439            match layer_kind {
1440                LayerKind::Validity => {
1441                    return RawRepDef::Validity(ValidityDesc {
1442                        validity: None,
1443                        num_values: all_num_values,
1444                    });
1445                }
1446                LayerKind::Fsl => {
1447                    return RawRepDef::Fsl(FslDesc {
1448                        validity: None,
1449                        num_values: all_num_values,
1450                        dimension: all_dimension,
1451                    });
1452                }
1453                LayerKind::Offsets => {}
1454            }
1455        }
1456
1457        // Only allocate if needed
1458        let mut validity_builder = if has_nulls {
1459            BooleanBufferBuilder::new(all_num_values)
1460        } else {
1461            BooleanBufferBuilder::new(0)
1462        };
1463        let mut all_offsets = if matches!(layer_kind, LayerKind::Offsets) {
1464            let mut all_offsets = Vec::with_capacity(all_num_values);
1465            all_offsets.push(0);
1466            all_offsets
1467        } else {
1468            Vec::new()
1469        };
1470
1471        for layer in collected {
1472            match layer {
1473                RawRepDef::Validity(ValidityDesc {
1474                    validity: Some(validity),
1475                    ..
1476                }) => {
1477                    validity_builder.append_buffer(validity);
1478                }
1479                RawRepDef::Validity(ValidityDesc {
1480                    validity: None,
1481                    num_values,
1482                }) => {
1483                    validity_builder.append_n(*num_values, true);
1484                }
1485                RawRepDef::Fsl(FslDesc {
1486                    validity,
1487                    num_values,
1488                    ..
1489                }) => {
1490                    if let Some(validity) = validity {
1491                        validity_builder.append_buffer(validity);
1492                    } else {
1493                        validity_builder.append_n(*num_values, true);
1494                    }
1495                }
1496                RawRepDef::Offsets(OffsetDesc {
1497                    offsets,
1498                    validity: Some(validity),
1499                    has_empty_lists,
1500                    ..
1501                }) => {
1502                    all_has_empty_lists |= has_empty_lists;
1503                    validity_builder.append_buffer(validity);
1504                    let last = *all_offsets.last().unwrap();
1505                    all_offsets.extend(offsets.iter().skip(1).map(|off| *off + last));
1506                }
1507                RawRepDef::Offsets(OffsetDesc {
1508                    offsets,
1509                    validity: None,
1510                    has_empty_lists,
1511                    num_values,
1512                    ..
1513                }) => {
1514                    all_has_empty_lists |= has_empty_lists;
1515                    if has_nulls {
1516                        validity_builder.append_n(*num_values, true);
1517                    }
1518                    let last = *all_offsets.last().unwrap();
1519                    all_offsets.extend(offsets.iter().skip(1).map(|off| *off + last));
1520                }
1521            }
1522        }
1523        let validity = if has_nulls {
1524            Some(validity_builder.finish())
1525        } else {
1526            None
1527        };
1528        match layer_kind {
1529            LayerKind::Fsl => RawRepDef::Fsl(FslDesc {
1530                validity,
1531                num_values: all_num_values,
1532                dimension: all_dimension,
1533            }),
1534            LayerKind::Validity => RawRepDef::Validity(ValidityDesc {
1535                validity,
1536                num_values: all_num_values,
1537            }),
1538            LayerKind::Offsets => RawRepDef::Offsets(OffsetDesc {
1539                offsets: all_offsets.into(),
1540                validity,
1541                has_empty_lists: all_has_empty_lists,
1542                num_values: all_num_values,
1543                num_specials: total_num_specials,
1544            }),
1545        }
1546    }
1547
1548    /// Converts the validity / offsets buffers that have been gathered so far
1549    /// into repetition and definition levels
1550    pub fn serialize(builders: Vec<Self>) -> SerializedRepDefs {
1551        Self::normalize(builders).serialize()
1552    }
1553
1554    pub(crate) fn normalize(builders: Vec<Self>) -> NormalizedStructuralPlan {
1555        assert!(!builders.is_empty());
1556        let num_layers = builders[0].num_layers();
1557        debug_assert!(
1558            builders
1559                .iter()
1560                .all(|builder| builder.num_layers() == num_layers)
1561        );
1562        let layers = (0..num_layers)
1563            .map(|layer_index| {
1564                Self::concat_layers(
1565                    builders.iter().map(|b| &b.repdefs[layer_index]),
1566                    builders.len(),
1567                )
1568            })
1569            .collect::<Vec<_>>();
1570        NormalizedStructuralPlan {
1571            layers,
1572            dense_all_valid: builders.iter().all(Self::is_empty),
1573        }
1574    }
1575}
1576
1577/// Starts with serialized repetition and definition levels and unravels
1578/// them into validity buffers and offsets buffers
1579///
1580/// This is used during decoding to create the necessary arrow structures
1581#[derive(Debug)]
1582pub struct RepDefUnraveler {
1583    sparse: Option<SparseStructuralUnraveler>,
1584    rep_levels: Option<LevelBuffer>,
1585    def_levels: Option<LevelBuffer>,
1586    // Maps from definition level to the rep level at which that definition level is visible
1587    levels_to_rep: Vec<u16>,
1588    def_meaning: Arc<[DefinitionInterpretation]>,
1589    // Current definition level to compare to.
1590    current_def_cmp: u16,
1591    // Current rep level, determines which specials we can see
1592    current_rep_cmp: u16,
1593    // Current layer index, 0 means inner-most layer and it counts up from there.  Used to index
1594    // into special_defs
1595    current_layer: usize,
1596    // Number of items in the inner-most layer (needed if the definition levels are not present)
1597    num_items: u64,
1598}
1599
1600impl RepDefUnraveler {
1601    /// Creates a new unraveler from serialized repetition and definition information
1602    pub fn new(
1603        rep_levels: Option<LevelBuffer>,
1604        def_levels: Option<LevelBuffer>,
1605        def_meaning: Arc<[DefinitionInterpretation]>,
1606        num_items: u64,
1607    ) -> Self {
1608        let mut levels_to_rep = Vec::with_capacity(def_meaning.len());
1609        let mut rep_counter = 0;
1610        // Level=0 is always visible and means valid item
1611        levels_to_rep.push(0);
1612        for meaning in def_meaning.as_ref() {
1613            match meaning {
1614                DefinitionInterpretation::AllValidItem | DefinitionInterpretation::AllValidList => {
1615                    // There is no corresponding level, so nothing to put in levels_to_rep
1616                }
1617                DefinitionInterpretation::NullableItem => {
1618                    // Some null structs are not visible at inner rep levels in cases like LIST<STRUCT<LIST<...>>>
1619                    levels_to_rep.push(rep_counter);
1620                }
1621                DefinitionInterpretation::NullableList => {
1622                    rep_counter += 1;
1623                    levels_to_rep.push(rep_counter);
1624                }
1625                DefinitionInterpretation::EmptyableList => {
1626                    rep_counter += 1;
1627                    levels_to_rep.push(rep_counter);
1628                }
1629                DefinitionInterpretation::NullableAndEmptyableList => {
1630                    rep_counter += 1;
1631                    levels_to_rep.push(rep_counter);
1632                    levels_to_rep.push(rep_counter);
1633                }
1634            }
1635        }
1636        Self {
1637            sparse: None,
1638            rep_levels,
1639            def_levels,
1640            current_def_cmp: 0,
1641            current_rep_cmp: 0,
1642            levels_to_rep,
1643            current_layer: 0,
1644            def_meaning,
1645            num_items,
1646        }
1647    }
1648
1649    pub(crate) fn new_sparse(plan: SparseStructuralPlan) -> Self {
1650        Self {
1651            sparse: Some(SparseStructuralUnraveler::new(plan)),
1652            rep_levels: None,
1653            def_levels: None,
1654            levels_to_rep: Vec::new(),
1655            def_meaning: Arc::new([]),
1656            current_def_cmp: 0,
1657            current_rep_cmp: 0,
1658            current_layer: 0,
1659            num_items: 0,
1660        }
1661    }
1662
1663    fn ensure_exhausted(&self) -> Result<()> {
1664        if let Some(sparse) = &self.sparse {
1665            sparse.ensure_exhausted()?;
1666        }
1667        Ok(())
1668    }
1669
1670    fn is_sparse(&self) -> bool {
1671        self.sparse.is_some()
1672    }
1673
1674    pub fn is_all_valid(&self) -> bool {
1675        if let Some(sparse) = &self.sparse {
1676            return sparse.is_all_valid();
1677        }
1678        self.def_levels.is_none() || self.def_meaning[self.current_layer].is_all_valid()
1679    }
1680
1681    /// If the current level is a repetition layer then this returns the number of lists
1682    /// at this level.
1683    ///
1684    /// This is not valid to call when the current level is a struct/primitive layer because
1685    /// in some cases there may be no rep or def information to know this.
1686    pub fn max_lists(&self) -> Result<usize> {
1687        if let Some(sparse) = &self.sparse {
1688            return sparse.max_lists();
1689        }
1690        debug_assert!(
1691            self.def_meaning[self.current_layer] != DefinitionInterpretation::NullableItem
1692        );
1693        Ok(self
1694            .rep_levels
1695            .as_ref()
1696            // Worst case every rep item is max_rep and a new list
1697            .map(|levels| levels.len())
1698            .unwrap_or(0))
1699    }
1700
1701    /// Unravels a layer of offsets from the unraveler into the given offset width
1702    ///
1703    /// When decoding a list the caller should first unravel the offsets and then
1704    /// unravel the validity (this is the opposite order used during encoding)
1705    pub fn unravel_offsets<T: ArrowNativeType>(
1706        &mut self,
1707        offsets: &mut Vec<T>,
1708        validity: Option<&mut BooleanBufferBuilder>,
1709    ) -> Result<()> {
1710        if let Some(sparse) = self.sparse.as_mut() {
1711            return sparse.unravel_offsets(offsets, validity);
1712        }
1713        let rep_levels = self
1714            .rep_levels
1715            .as_mut()
1716            .expect("Expected repetition level but data didn't contain repetition");
1717        let valid_level = self.current_def_cmp;
1718        let (null_level, empty_level) = match self.def_meaning[self.current_layer] {
1719            DefinitionInterpretation::NullableList => {
1720                self.current_def_cmp += 1;
1721                (valid_level + 1, 0)
1722            }
1723            DefinitionInterpretation::EmptyableList => {
1724                self.current_def_cmp += 1;
1725                (0, valid_level + 1)
1726            }
1727            DefinitionInterpretation::NullableAndEmptyableList => {
1728                self.current_def_cmp += 2;
1729                (valid_level + 1, valid_level + 2)
1730            }
1731            DefinitionInterpretation::AllValidList => (0, 0),
1732            _ => unreachable!(),
1733        };
1734        self.current_layer += 1;
1735
1736        // This is the highest def level that is still visible.  Once we hit a list then
1737        // we stop looking because any null / empty list (or list masked by a higher level
1738        // null) will not be visible
1739        let mut max_level = null_level.max(empty_level).max(valid_level);
1740        // Anything higher than this (but less than max_level) is a null struct masking our
1741        // list.  We will materialize this is a null list.
1742        let upper_null = max_level;
1743        for level in self.def_meaning[self.current_layer..].iter() {
1744            match level {
1745                DefinitionInterpretation::NullableItem => {
1746                    max_level += 1;
1747                }
1748                DefinitionInterpretation::AllValidItem => {}
1749                _ => {
1750                    break;
1751                }
1752            }
1753        }
1754
1755        let mut curlen: usize = offsets.last().map(|o| o.as_usize()).unwrap_or(0);
1756
1757        // If offsets is empty this is a no-op.  If offsets is not empty that means we already
1758        // added a set of offsets.  For example, we might have added [0, 3, 5] (2 lists).  Now
1759        // say we want to add [0, 1, 4] (2 lists).  We should get [0, 3, 5, 6, 9] (4 lists).  If
1760        // we don't pop here we get [0, 3, 5, 5, 6, 9] which is wrong.
1761        //
1762        // Or, to think about it another way, if every unraveler adds the starting 0 and the trailing
1763        // length then we have N + unravelers.len() values instead of N + 1.
1764        offsets.pop();
1765
1766        let to_offset = |val: usize| {
1767            T::from_usize(val)
1768            .ok_or_else(|| Error::invalid_input("A single batch had more than i32::MAX values and so a large container type is required"))
1769        };
1770        self.current_rep_cmp += 1;
1771        if let Some(def_levels) = &mut self.def_levels {
1772            assert!(rep_levels.len() == def_levels.len());
1773            // It's possible validity is None even if we have def levels.  For example, we might have
1774            // empty lists (which require def levels) but no nulls.
1775            let mut push_validity: Box<dyn FnMut(bool)> = if let Some(validity) = validity {
1776                Box::new(|is_valid| validity.append(is_valid))
1777            } else {
1778                Box::new(|_| {})
1779            };
1780            // This is a strange access pattern.  We are iterating over the rep/def levels and
1781            // at the same time writing the rep/def levels.  This means we need both a mutable
1782            // and immutable reference to the rep/def levels.
1783            let mut read_idx = 0;
1784            let mut write_idx = 0;
1785            while read_idx < rep_levels.len() {
1786                // SAFETY: We assert that rep_levels and def_levels have the same
1787                // len and read_idx and write_idx can never go past the end.
1788                unsafe {
1789                    let rep_val = *rep_levels.get_unchecked(read_idx);
1790                    if rep_val != 0 {
1791                        let def_val = *def_levels.get_unchecked(read_idx);
1792                        // Copy over
1793                        *rep_levels.get_unchecked_mut(write_idx) = rep_val - 1;
1794                        *def_levels.get_unchecked_mut(write_idx) = def_val;
1795                        write_idx += 1;
1796
1797                        if def_val == 0 {
1798                            // This is a valid list
1799                            offsets.push(to_offset(curlen)?);
1800                            curlen += 1;
1801                            push_validity(true);
1802                        } else if def_val > max_level {
1803                            // This is not visible at this rep level, do not add to offsets, but keep in repdef
1804                        } else if def_val == null_level || def_val > upper_null {
1805                            // This is a null list (or a list masked by a null struct)
1806                            offsets.push(to_offset(curlen)?);
1807                            push_validity(false);
1808                        } else if def_val == empty_level {
1809                            // This is an empty list
1810                            offsets.push(to_offset(curlen)?);
1811                            push_validity(true);
1812                        } else {
1813                            // New valid list starting with null item
1814                            offsets.push(to_offset(curlen)?);
1815                            curlen += 1;
1816                            push_validity(true);
1817                        }
1818                    } else {
1819                        curlen += 1;
1820                    }
1821                    read_idx += 1;
1822                }
1823            }
1824            offsets.push(to_offset(curlen)?);
1825            rep_levels.truncate(write_idx);
1826            def_levels.truncate(write_idx);
1827            Ok(())
1828        } else {
1829            // SAFETY: See above loop
1830            let mut read_idx = 0;
1831            let mut write_idx = 0;
1832            let old_offsets_len = offsets.len();
1833            while read_idx < rep_levels.len() {
1834                // SAFETY: read_idx / write_idx cannot go past rep_levels.len()
1835                unsafe {
1836                    let rep_val = *rep_levels.get_unchecked(read_idx);
1837                    if rep_val != 0 {
1838                        // Finish the current list
1839                        offsets.push(to_offset(curlen)?);
1840                        *rep_levels.get_unchecked_mut(write_idx) = rep_val - 1;
1841                        write_idx += 1;
1842                    }
1843                    curlen += 1;
1844                    read_idx += 1;
1845                }
1846            }
1847            let num_new_lists = offsets.len() - old_offsets_len;
1848            offsets.push(to_offset(curlen)?);
1849            // Truncate to the number of lists THIS unraveler produced (write_idx),
1850            // not `offsets.len() - 1` — the latter includes offsets contributed by
1851            // earlier unravelers in a multi-page read, which would leave too many
1852            // rep levels for the next (outer) layer and over-count its lists.
1853            rep_levels.truncate(write_idx);
1854            if let Some(validity) = validity {
1855                // Even though we don't have validity it is possible another unraveler did and so we need
1856                // to push all valids
1857                validity.append_n(num_new_lists, true);
1858            }
1859            Ok(())
1860        }
1861    }
1862
1863    pub fn skip_validity(&mut self) -> Result<()> {
1864        if let Some(sparse) = self.sparse.as_mut() {
1865            return sparse.skip_validity();
1866        }
1867        debug_assert!(self.is_all_valid());
1868        self.current_layer += 1;
1869        Ok(())
1870    }
1871
1872    /// Unravels a layer of validity from the definition levels
1873    pub fn unravel_validity(&mut self, validity: &mut BooleanBufferBuilder) -> Result<()> {
1874        if let Some(sparse) = self.sparse.as_mut() {
1875            return sparse.unravel_validity(validity);
1876        }
1877        let meaning = self.def_meaning[self.current_layer];
1878        if meaning == DefinitionInterpretation::AllValidItem || self.def_levels.is_none() {
1879            self.current_layer += 1;
1880            validity.append_n(self.num_items as usize, true);
1881            return Ok(());
1882        }
1883
1884        self.current_layer += 1;
1885        let def_levels = &self.def_levels.as_ref().unwrap();
1886
1887        let current_def_cmp = self.current_def_cmp;
1888        self.current_def_cmp += 1;
1889
1890        for is_valid in def_levels.iter().filter_map(|&level| {
1891            if self.levels_to_rep[level as usize] <= self.current_rep_cmp {
1892                Some(level <= current_def_cmp)
1893            } else {
1894                None
1895            }
1896        }) {
1897            validity.append(is_valid);
1898        }
1899        Ok(())
1900    }
1901
1902    pub fn decimate(&mut self, dimension: usize) -> Result<()> {
1903        if let Some(sparse) = self.sparse.as_mut() {
1904            return sparse.decimate(dimension);
1905        }
1906        if self.rep_levels.is_some() {
1907            // If we need to support this then I think we need to walk through the rep def levels to find
1908            // the spots at which we keep.  E.g. if we have:
1909            //  rep: 1 0 0 1 0 1 0 0 0 1 0 0
1910            //  def: 1 1 1 0 1 0 1 1 0 1 1 0
1911            //  dimension: 2
1912            //
1913            // The output should be:
1914            //  rep: 1 0 0 1 0 0 0
1915            //  def: 1 1 1 0 1 1 0
1916            //
1917            // Maybe there's some special logic for empty/null lists?  I'll save the headache for future me.
1918            todo!("Not yet supported FSL<...List<...>>");
1919        }
1920        let Some(def_levels) = self.def_levels.as_mut() else {
1921            return Ok(());
1922        };
1923        let mut read_idx = 0;
1924        let mut write_idx = 0;
1925        while read_idx < def_levels.len() {
1926            unsafe {
1927                *def_levels.get_unchecked_mut(write_idx) = *def_levels.get_unchecked(read_idx);
1928            }
1929            write_idx += 1;
1930            read_idx += dimension;
1931        }
1932        def_levels.truncate(write_idx);
1933        Ok(())
1934    }
1935}
1936
1937/// As we decode we may extract rep/def information from multiple pages (or multiple
1938/// chunks within a page).
1939///
1940/// For each chunk we create an unraveler.  Each unraveler can have a completely different
1941/// interpretation (e.g. one page might contain null items but no null structs and the next
1942/// page might have null structs but no null items).
1943///
1944/// Concatenating these unravelers would be tricky and expensive so instead we have a
1945/// composite unraveler which unravels across multiple unravelers.
1946///
1947/// Note: this class should be used even if there is only one page / unraveler.  This is
1948/// because the `RepDefUnraveler`'s API is more complex (it's meant to be called by this
1949/// class)
1950#[derive(Debug)]
1951pub struct CompositeRepDefUnraveler {
1952    unravelers: Vec<RepDefUnraveler>,
1953    comparisons: Vec<Self>,
1954}
1955
1956impl CompositeRepDefUnraveler {
1957    pub fn new(unravelers: Vec<RepDefUnraveler>) -> Self {
1958        Self {
1959            unravelers,
1960            comparisons: Vec::new(),
1961        }
1962    }
1963
1964    pub(crate) fn add_compatibility_check(&mut self, other: Self) {
1965        self.comparisons.push(other);
1966    }
1967
1968    pub(crate) fn has_sparse(&self) -> bool {
1969        self.unravelers.iter().any(RepDefUnraveler::is_sparse)
1970            || self.comparisons.iter().any(Self::has_sparse)
1971    }
1972
1973    pub(crate) fn ensure_exhausted(&self) -> Result<()> {
1974        for unraveler in &self.unravelers {
1975            unraveler.ensure_exhausted()?;
1976        }
1977        for comparison in &self.comparisons {
1978            comparison.ensure_exhausted()?;
1979        }
1980        Ok(())
1981    }
1982
1983    fn null_buffers_equal(
1984        left: &Option<NullBuffer>,
1985        right: &Option<NullBuffer>,
1986        expected_len: usize,
1987    ) -> bool {
1988        match (left, right) {
1989            (None, None) => true,
1990            (Some(left), Some(right)) => {
1991                left.len() == expected_len
1992                    && right.len() == expected_len
1993                    && left.iter().eq(right.iter())
1994            }
1995            (None, Some(right)) => right.len() == expected_len && right.null_count() == 0,
1996            (Some(left), None) => left.len() == expected_len && left.null_count() == 0,
1997        }
1998    }
1999
2000    fn decimate(&mut self, dimension: usize) -> Result<()> {
2001        for unraveler in &mut self.unravelers {
2002            unraveler.decimate(dimension)?;
2003        }
2004        for comparison in &mut self.comparisons {
2005            comparison.decimate(dimension)?;
2006        }
2007        Ok(())
2008    }
2009
2010    /// Unravels a layer of validity
2011    ///
2012    /// Returns None if there are no null items in this layer
2013    pub fn unravel_validity(&mut self, num_values: usize) -> Result<Option<NullBuffer>> {
2014        let is_all_valid = self
2015            .unravelers
2016            .iter()
2017            .all(|unraveler| unraveler.is_all_valid());
2018
2019        let validity = if is_all_valid {
2020            for unraveler in self.unravelers.iter_mut() {
2021                unraveler.skip_validity()?;
2022            }
2023            None
2024        } else {
2025            let mut validity = BooleanBufferBuilder::new(num_values);
2026            for unraveler in self.unravelers.iter_mut() {
2027                unraveler.unravel_validity(&mut validity)?;
2028            }
2029            Some(NullBuffer::new(validity.finish()))
2030        };
2031        for comparison in &mut self.comparisons {
2032            let other = comparison.unravel_validity(num_values)?;
2033            if !Self::null_buffers_equal(&validity, &other, num_values) {
2034                return Err(Error::invalid_input_source(
2035                    format!(
2036                        "Structural sibling fields have incompatible validity metadata for {num_values} values"
2037                    )
2038                    .into(),
2039                ));
2040            }
2041        }
2042        Ok(validity)
2043    }
2044
2045    pub fn unravel_fsl_validity(
2046        &mut self,
2047        num_values: usize,
2048        dimension: usize,
2049    ) -> Result<Option<NullBuffer>> {
2050        self.decimate(dimension)?;
2051        self.unravel_validity(num_values)
2052    }
2053
2054    /// Unravels a layer of offsets (and the validity for that layer)
2055    pub fn unravel_offsets<T: ArrowNativeType>(
2056        &mut self,
2057    ) -> Result<(OffsetBuffer<T>, Option<NullBuffer>)> {
2058        let mut is_all_valid = true;
2059        let mut max_num_lists: usize = 0;
2060        for unraveler in self.unravelers.iter() {
2061            is_all_valid &= unraveler.is_all_valid();
2062            max_num_lists = max_num_lists
2063                .checked_add(unraveler.max_lists()?)
2064                .ok_or_else(|| {
2065                    Error::invalid_input_source(
2066                        "Combined repetition/definition list count exceeds usize::MAX".into(),
2067                    )
2068                })?;
2069        }
2070
2071        let mut validity = if is_all_valid {
2072            None
2073        } else {
2074            // Note: This is probably an over-estimate and potentially even an under-estimate.  We only know
2075            // right now how many items we have and not how many rows.  (TODO: Shouldn't we know the # of rows?)
2076            Some(BooleanBufferBuilder::new(max_num_lists))
2077        };
2078
2079        let mut offsets = Vec::with_capacity(max_num_lists + 1);
2080
2081        for unraveler in self.unravelers.iter_mut() {
2082            unraveler.unravel_offsets(&mut offsets, validity.as_mut())?;
2083        }
2084
2085        let offsets = OffsetBuffer::new(ScalarBuffer::from(offsets));
2086        let validity = validity.map(|mut v| NullBuffer::new(v.finish()));
2087        for comparison in &mut self.comparisons {
2088            let (other_offsets, other_validity) = comparison.unravel_offsets::<T>()?;
2089            if offsets.as_ref() != other_offsets.as_ref()
2090                || !Self::null_buffers_equal(
2091                    &validity,
2092                    &other_validity,
2093                    offsets.len().saturating_sub(1),
2094                )
2095            {
2096                return Err(Error::invalid_input_source(
2097                    format!(
2098                        "Structural sibling fields have incompatible list metadata for {} slots",
2099                        offsets.len().saturating_sub(1)
2100                    )
2101                    .into(),
2102                ));
2103            }
2104        }
2105
2106        Ok((offsets, validity))
2107    }
2108}
2109
2110/// A [`ControlWordIterator`] when there are both repetition and definition levels
2111///
2112/// The iterator will put the repetition level in the upper bits and the definition
2113/// level in the lower bits.  The number of bits used for each level is determined
2114/// by the width of the repetition and definition levels.
2115#[derive(Debug)]
2116pub struct BinaryControlWordIterator<I: Iterator<Item = (u16, u16)>, W> {
2117    repdef: I,
2118    def_width: usize,
2119    max_rep: u16,
2120    max_visible_def: u16,
2121    rep_mask: u16,
2122    def_mask: u16,
2123    bits_rep: u8,
2124    bits_def: u8,
2125    phantom: std::marker::PhantomData<W>,
2126}
2127
2128impl<I: Iterator<Item = (u16, u16)>> BinaryControlWordIterator<I, u8> {
2129    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2130        let next = self.repdef.next()?;
2131        let control_word: u8 =
2132            (((next.0 & self.rep_mask) as u8) << self.def_width) + ((next.1 & self.def_mask) as u8);
2133        buf.push(control_word);
2134        let is_new_row = next.0 == self.max_rep;
2135        let is_visible = next.1 <= self.max_visible_def;
2136        let is_valid_item = next.1 == 0;
2137        Some(ControlWordDesc {
2138            is_new_row,
2139            is_visible,
2140            is_valid_item,
2141        })
2142    }
2143}
2144
2145impl<I: Iterator<Item = (u16, u16)>> BinaryControlWordIterator<I, u16> {
2146    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2147        let next = self.repdef.next()?;
2148        let control_word: u16 =
2149            ((next.0 & self.rep_mask) << self.def_width) + (next.1 & self.def_mask);
2150        let control_word = control_word.to_le_bytes();
2151        buf.push(control_word[0]);
2152        buf.push(control_word[1]);
2153        let is_new_row = next.0 == self.max_rep;
2154        let is_visible = next.1 <= self.max_visible_def;
2155        let is_valid_item = next.1 == 0;
2156        Some(ControlWordDesc {
2157            is_new_row,
2158            is_visible,
2159            is_valid_item,
2160        })
2161    }
2162}
2163
2164impl<I: Iterator<Item = (u16, u16)>> BinaryControlWordIterator<I, u32> {
2165    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2166        let next = self.repdef.next()?;
2167        let control_word: u32 = (((next.0 & self.rep_mask) as u32) << self.def_width)
2168            + ((next.1 & self.def_mask) as u32);
2169        let control_word = control_word.to_le_bytes();
2170        buf.push(control_word[0]);
2171        buf.push(control_word[1]);
2172        buf.push(control_word[2]);
2173        buf.push(control_word[3]);
2174        let is_new_row = next.0 == self.max_rep;
2175        let is_visible = next.1 <= self.max_visible_def;
2176        let is_valid_item = next.1 == 0;
2177        Some(ControlWordDesc {
2178            is_new_row,
2179            is_visible,
2180            is_valid_item,
2181        })
2182    }
2183}
2184
2185/// A [`ControlWordIterator`] when there are only definition levels or only repetition levels
2186#[derive(Debug)]
2187pub struct UnaryControlWordIterator<I: Iterator<Item = u16>, W> {
2188    repdef: I,
2189    level_mask: u16,
2190    bits_rep: u8,
2191    bits_def: u8,
2192    max_rep: u16,
2193    phantom: std::marker::PhantomData<W>,
2194}
2195
2196impl<I: Iterator<Item = u16>> UnaryControlWordIterator<I, u8> {
2197    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2198        let next = self.repdef.next()?;
2199        buf.push((next & self.level_mask) as u8);
2200        let is_new_row = self.max_rep == 0 || next == self.max_rep;
2201        let is_valid_item = next == 0 || self.bits_def == 0;
2202        Some(ControlWordDesc {
2203            is_new_row,
2204            // Either there is no rep, in which case there are no invisible items
2205            // or there is no def, in which case there are no invisible items
2206            is_visible: true,
2207            is_valid_item,
2208        })
2209    }
2210}
2211
2212impl<I: Iterator<Item = u16>> UnaryControlWordIterator<I, u16> {
2213    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2214        let next = self.repdef.next().unwrap() & self.level_mask;
2215        let control_word = next.to_le_bytes();
2216        buf.push(control_word[0]);
2217        buf.push(control_word[1]);
2218        let is_new_row = self.max_rep == 0 || next == self.max_rep;
2219        let is_valid_item = next == 0 || self.bits_def == 0;
2220        Some(ControlWordDesc {
2221            is_new_row,
2222            is_visible: true,
2223            is_valid_item,
2224        })
2225    }
2226}
2227
2228impl<I: Iterator<Item = u16>> UnaryControlWordIterator<I, u32> {
2229    fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2230        let next = self.repdef.next()?;
2231        let next = (next & self.level_mask) as u32;
2232        let control_word = next.to_le_bytes();
2233        buf.push(control_word[0]);
2234        buf.push(control_word[1]);
2235        buf.push(control_word[2]);
2236        buf.push(control_word[3]);
2237        let is_new_row = self.max_rep == 0 || next as u16 == self.max_rep;
2238        let is_valid_item = next == 0 || self.bits_def == 0;
2239        Some(ControlWordDesc {
2240            is_new_row,
2241            is_visible: true,
2242            is_valid_item,
2243        })
2244    }
2245}
2246
2247/// A [`ControlWordIterator`] when there are no repetition or definition levels
2248#[derive(Debug)]
2249pub struct NilaryControlWordIterator {
2250    len: usize,
2251    idx: usize,
2252}
2253
2254impl NilaryControlWordIterator {
2255    fn append_next(&mut self) -> Option<ControlWordDesc> {
2256        if self.idx == self.len {
2257            None
2258        } else {
2259            self.idx += 1;
2260            Some(ControlWordDesc {
2261                is_new_row: true,
2262                is_visible: true,
2263                is_valid_item: true,
2264            })
2265        }
2266    }
2267}
2268
2269/// Helper function to get a bit mask of the given width
2270fn get_mask(width: u16) -> u16 {
2271    (1 << width) - 1
2272}
2273
2274// We're really going out of our way to avoid boxing here but this will be called on a per-value basis
2275// so it is in the critical path.
2276type SpecificBinaryControlWordIterator<'a, T> = BinaryControlWordIterator<
2277    Zip<Copied<std::slice::Iter<'a, u16>>, Copied<std::slice::Iter<'a, u16>>>,
2278    T,
2279>;
2280
2281/// An iterator that generates control words from repetition and definition levels
2282///
2283/// "Control word" is just a fancy term for a single u8/u16/u32 that contains both
2284/// the repetition and definition in it.
2285///
2286/// In the large majority of case we only need a single byte to represent both the
2287/// repetition and definition levels.  However, if there is deep nesting then we may
2288/// need two bytes.  In the worst case we need 4 bytes though this suggests hundreds of
2289/// levels of nesting which seems unlikely to encounter in practice.
2290#[derive(Debug)]
2291pub enum ControlWordIterator<'a> {
2292    Binary8(SpecificBinaryControlWordIterator<'a, u8>),
2293    Binary16(SpecificBinaryControlWordIterator<'a, u16>),
2294    Binary32(SpecificBinaryControlWordIterator<'a, u32>),
2295    Unary8(UnaryControlWordIterator<Copied<std::slice::Iter<'a, u16>>, u8>),
2296    Unary16(UnaryControlWordIterator<Copied<std::slice::Iter<'a, u16>>, u16>),
2297    Unary32(UnaryControlWordIterator<Copied<std::slice::Iter<'a, u16>>, u32>),
2298    Nilary(NilaryControlWordIterator),
2299}
2300
2301/// Describes the properties of a control word
2302#[derive(Debug)]
2303pub struct ControlWordDesc {
2304    pub is_new_row: bool,
2305    pub is_visible: bool,
2306    pub is_valid_item: bool,
2307}
2308
2309impl ControlWordIterator<'_> {
2310    /// Appends the next control word to the buffer
2311    ///
2312    /// Returns true if this is the start of a new item (i.e. the repetition level is maxed out)
2313    pub fn append_next(&mut self, buf: &mut Vec<u8>) -> Option<ControlWordDesc> {
2314        match self {
2315            Self::Binary8(iter) => iter.append_next(buf),
2316            Self::Binary16(iter) => iter.append_next(buf),
2317            Self::Binary32(iter) => iter.append_next(buf),
2318            Self::Unary8(iter) => iter.append_next(buf),
2319            Self::Unary16(iter) => iter.append_next(buf),
2320            Self::Unary32(iter) => iter.append_next(buf),
2321            Self::Nilary(iter) => iter.append_next(),
2322        }
2323    }
2324
2325    /// Return true if the control word iterator has repetition levels
2326    pub fn has_repetition(&self) -> bool {
2327        match self {
2328            Self::Binary8(_) | Self::Binary16(_) | Self::Binary32(_) => true,
2329            Self::Unary8(iter) => iter.bits_rep > 0,
2330            Self::Unary16(iter) => iter.bits_rep > 0,
2331            Self::Unary32(iter) => iter.bits_rep > 0,
2332            Self::Nilary(_) => false,
2333        }
2334    }
2335
2336    /// Returns the number of bytes per control word
2337    pub fn bytes_per_word(&self) -> usize {
2338        match self {
2339            Self::Binary8(_) => 1,
2340            Self::Binary16(_) => 2,
2341            Self::Binary32(_) => 4,
2342            Self::Unary8(_) => 1,
2343            Self::Unary16(_) => 2,
2344            Self::Unary32(_) => 4,
2345            Self::Nilary(_) => 0,
2346        }
2347    }
2348
2349    /// Returns the number of bits used for the repetition level
2350    pub fn bits_rep(&self) -> u8 {
2351        match self {
2352            Self::Binary8(iter) => iter.bits_rep,
2353            Self::Binary16(iter) => iter.bits_rep,
2354            Self::Binary32(iter) => iter.bits_rep,
2355            Self::Unary8(iter) => iter.bits_rep,
2356            Self::Unary16(iter) => iter.bits_rep,
2357            Self::Unary32(iter) => iter.bits_rep,
2358            Self::Nilary(_) => 0,
2359        }
2360    }
2361
2362    /// Returns the number of bits used for the definition level
2363    pub fn bits_def(&self) -> u8 {
2364        match self {
2365            Self::Binary8(iter) => iter.bits_def,
2366            Self::Binary16(iter) => iter.bits_def,
2367            Self::Binary32(iter) => iter.bits_def,
2368            Self::Unary8(iter) => iter.bits_def,
2369            Self::Unary16(iter) => iter.bits_def,
2370            Self::Unary32(iter) => iter.bits_def,
2371            Self::Nilary(_) => 0,
2372        }
2373    }
2374}
2375
2376/// Builds a [`ControlWordIterator`] from repetition and definition levels
2377/// by first calculating the width needed and then creating the iterator
2378/// with the appropriate width
2379pub fn build_control_word_iterator<'a>(
2380    rep: Option<&'a [u16]>,
2381    max_rep: u16,
2382    def: Option<&'a [u16]>,
2383    max_def: u16,
2384    max_visible_def: u16,
2385    len: usize,
2386) -> ControlWordIterator<'a> {
2387    let rep_width = if max_rep == 0 {
2388        0
2389    } else {
2390        log_2_ceil(max_rep as u32) as u16
2391    };
2392    let rep_mask = if max_rep == 0 { 0 } else { get_mask(rep_width) };
2393    let def_width = if max_def == 0 {
2394        0
2395    } else {
2396        log_2_ceil(max_def as u32) as u16
2397    };
2398    let def_mask = if max_def == 0 { 0 } else { get_mask(def_width) };
2399    let total_width = rep_width + def_width;
2400    match (rep, def) {
2401        (Some(rep), Some(def)) => {
2402            let iter = rep.iter().copied().zip(def.iter().copied());
2403            let def_width = def_width as usize;
2404            if total_width <= 8 {
2405                ControlWordIterator::Binary8(BinaryControlWordIterator {
2406                    repdef: iter,
2407                    rep_mask,
2408                    def_mask,
2409                    def_width,
2410                    max_rep,
2411                    max_visible_def,
2412                    bits_rep: rep_width as u8,
2413                    bits_def: def_width as u8,
2414                    phantom: std::marker::PhantomData,
2415                })
2416            } else if total_width <= 16 {
2417                ControlWordIterator::Binary16(BinaryControlWordIterator {
2418                    repdef: iter,
2419                    rep_mask,
2420                    def_mask,
2421                    def_width,
2422                    max_rep,
2423                    max_visible_def,
2424                    bits_rep: rep_width as u8,
2425                    bits_def: def_width as u8,
2426                    phantom: std::marker::PhantomData,
2427                })
2428            } else {
2429                ControlWordIterator::Binary32(BinaryControlWordIterator {
2430                    repdef: iter,
2431                    rep_mask,
2432                    def_mask,
2433                    def_width,
2434                    max_rep,
2435                    max_visible_def,
2436                    bits_rep: rep_width as u8,
2437                    bits_def: def_width as u8,
2438                    phantom: std::marker::PhantomData,
2439                })
2440            }
2441        }
2442        (Some(lev), None) => {
2443            let iter = lev.iter().copied();
2444            if total_width <= 8 {
2445                ControlWordIterator::Unary8(UnaryControlWordIterator {
2446                    repdef: iter,
2447                    level_mask: rep_mask,
2448                    bits_rep: total_width as u8,
2449                    bits_def: 0,
2450                    max_rep,
2451                    phantom: std::marker::PhantomData,
2452                })
2453            } else if total_width <= 16 {
2454                ControlWordIterator::Unary16(UnaryControlWordIterator {
2455                    repdef: iter,
2456                    level_mask: rep_mask,
2457                    bits_rep: total_width as u8,
2458                    bits_def: 0,
2459                    max_rep,
2460                    phantom: std::marker::PhantomData,
2461                })
2462            } else {
2463                ControlWordIterator::Unary32(UnaryControlWordIterator {
2464                    repdef: iter,
2465                    level_mask: rep_mask,
2466                    bits_rep: total_width as u8,
2467                    bits_def: 0,
2468                    max_rep,
2469                    phantom: std::marker::PhantomData,
2470                })
2471            }
2472        }
2473        (None, Some(lev)) => {
2474            let iter = lev.iter().copied();
2475            if total_width <= 8 {
2476                ControlWordIterator::Unary8(UnaryControlWordIterator {
2477                    repdef: iter,
2478                    level_mask: def_mask,
2479                    bits_rep: 0,
2480                    bits_def: total_width as u8,
2481                    max_rep: 0,
2482                    phantom: std::marker::PhantomData,
2483                })
2484            } else if total_width <= 16 {
2485                ControlWordIterator::Unary16(UnaryControlWordIterator {
2486                    repdef: iter,
2487                    level_mask: def_mask,
2488                    bits_rep: 0,
2489                    bits_def: total_width as u8,
2490                    max_rep: 0,
2491                    phantom: std::marker::PhantomData,
2492                })
2493            } else {
2494                ControlWordIterator::Unary32(UnaryControlWordIterator {
2495                    repdef: iter,
2496                    level_mask: def_mask,
2497                    bits_rep: 0,
2498                    bits_def: total_width as u8,
2499                    max_rep: 0,
2500                    phantom: std::marker::PhantomData,
2501                })
2502            }
2503        }
2504        (None, None) => ControlWordIterator::Nilary(NilaryControlWordIterator { len, idx: 0 }),
2505    }
2506}
2507
2508/// A parser to unwrap control words into repetition and definition levels
2509///
2510/// This is the inverse of the [`ControlWordIterator`].
2511#[derive(Copy, Clone, Debug)]
2512pub enum ControlWordParser {
2513    // First item is the bits to shift, second is the mask to apply (the mask can be
2514    // calculated from the bits to shift but we don't want to calculate it each time)
2515    BOTH8(u8, u32),
2516    BOTH16(u8, u32),
2517    BOTH32(u8, u32),
2518    REP8,
2519    REP16,
2520    REP32,
2521    DEF8,
2522    DEF16,
2523    DEF32,
2524    NIL,
2525}
2526
2527impl ControlWordParser {
2528    fn parse_both<const WORD_SIZE: u8>(
2529        src: &[u8],
2530        dst_rep: &mut Vec<u16>,
2531        dst_def: &mut Vec<u16>,
2532        bits_to_shift: u8,
2533        mask_to_apply: u32,
2534    ) {
2535        match WORD_SIZE {
2536            1 => {
2537                let word = src[0];
2538                let rep = word >> bits_to_shift;
2539                let def = word & (mask_to_apply as u8);
2540                dst_rep.push(rep as u16);
2541                dst_def.push(def as u16);
2542            }
2543            2 => {
2544                let word = u16::from_le_bytes([src[0], src[1]]);
2545                let rep = word >> bits_to_shift;
2546                let def = word & mask_to_apply as u16;
2547                dst_rep.push(rep);
2548                dst_def.push(def);
2549            }
2550            4 => {
2551                let word = u32::from_le_bytes([src[0], src[1], src[2], src[3]]);
2552                let rep = word >> bits_to_shift;
2553                let def = word & mask_to_apply;
2554                dst_rep.push(rep as u16);
2555                dst_def.push(def as u16);
2556            }
2557            _ => unreachable!(),
2558        }
2559    }
2560
2561    fn parse_desc_both<const WORD_SIZE: u8>(
2562        src: &[u8],
2563        bits_to_shift: u8,
2564        mask_to_apply: u32,
2565        max_rep: u16,
2566        max_visible_def: u16,
2567    ) -> ControlWordDesc {
2568        match WORD_SIZE {
2569            1 => {
2570                let word = src[0];
2571                let rep = word >> bits_to_shift;
2572                let def = word & (mask_to_apply as u8);
2573                let is_visible = def as u16 <= max_visible_def;
2574                let is_new_row = rep as u16 == max_rep;
2575                let is_valid_item = def == 0;
2576                ControlWordDesc {
2577                    is_visible,
2578                    is_new_row,
2579                    is_valid_item,
2580                }
2581            }
2582            2 => {
2583                let word = u16::from_le_bytes([src[0], src[1]]);
2584                let rep = word >> bits_to_shift;
2585                let def = word & mask_to_apply as u16;
2586                let is_visible = def <= max_visible_def;
2587                let is_new_row = rep == max_rep;
2588                let is_valid_item = def == 0;
2589                ControlWordDesc {
2590                    is_visible,
2591                    is_new_row,
2592                    is_valid_item,
2593                }
2594            }
2595            4 => {
2596                let word = u32::from_le_bytes([src[0], src[1], src[2], src[3]]);
2597                let rep = word >> bits_to_shift;
2598                let def = word & mask_to_apply;
2599                let is_visible = def as u16 <= max_visible_def;
2600                let is_new_row = rep as u16 == max_rep;
2601                let is_valid_item = def == 0;
2602                ControlWordDesc {
2603                    is_visible,
2604                    is_new_row,
2605                    is_valid_item,
2606                }
2607            }
2608            _ => unreachable!(),
2609        }
2610    }
2611
2612    fn parse_one<const WORD_SIZE: u8>(src: &[u8], dst: &mut Vec<u16>) {
2613        match WORD_SIZE {
2614            1 => {
2615                let word = src[0];
2616                dst.push(word as u16);
2617            }
2618            2 => {
2619                let word = u16::from_le_bytes([src[0], src[1]]);
2620                dst.push(word);
2621            }
2622            4 => {
2623                let word = u32::from_le_bytes([src[0], src[1], src[2], src[3]]);
2624                dst.push(word as u16);
2625            }
2626            _ => unreachable!(),
2627        }
2628    }
2629
2630    fn parse_rep_desc_one<const WORD_SIZE: u8>(src: &[u8], max_rep: u16) -> ControlWordDesc {
2631        match WORD_SIZE {
2632            1 => ControlWordDesc {
2633                is_new_row: src[0] as u16 == max_rep,
2634                is_visible: true,
2635                is_valid_item: true,
2636            },
2637            2 => ControlWordDesc {
2638                is_new_row: u16::from_le_bytes([src[0], src[1]]) == max_rep,
2639                is_visible: true,
2640                is_valid_item: true,
2641            },
2642            4 => ControlWordDesc {
2643                is_new_row: u32::from_le_bytes([src[0], src[1], src[2], src[3]]) as u16 == max_rep,
2644                is_visible: true,
2645                is_valid_item: true,
2646            },
2647            _ => unreachable!(),
2648        }
2649    }
2650
2651    fn parse_def_desc_one<const WORD_SIZE: u8>(src: &[u8]) -> ControlWordDesc {
2652        match WORD_SIZE {
2653            1 => ControlWordDesc {
2654                is_new_row: true,
2655                is_visible: true,
2656                is_valid_item: src[0] == 0,
2657            },
2658            2 => ControlWordDesc {
2659                is_new_row: true,
2660                is_visible: true,
2661                is_valid_item: u16::from_le_bytes([src[0], src[1]]) == 0,
2662            },
2663            4 => ControlWordDesc {
2664                is_new_row: true,
2665                is_visible: true,
2666                is_valid_item: u32::from_le_bytes([src[0], src[1], src[2], src[3]]) as u16 == 0,
2667            },
2668            _ => unreachable!(),
2669        }
2670    }
2671
2672    /// Returns the number of bytes per control word
2673    pub fn bytes_per_word(&self) -> usize {
2674        match self {
2675            Self::BOTH8(..) => 1,
2676            Self::BOTH16(..) => 2,
2677            Self::BOTH32(..) => 4,
2678            Self::REP8 => 1,
2679            Self::REP16 => 2,
2680            Self::REP32 => 4,
2681            Self::DEF8 => 1,
2682            Self::DEF16 => 2,
2683            Self::DEF32 => 4,
2684            Self::NIL => 0,
2685        }
2686    }
2687
2688    /// Appends the next control word to the rep & def buffers
2689    ///
2690    /// `src` should be pointing at the first byte (little endian) of the control word
2691    ///
2692    /// `dst_rep` and `dst_def` are the buffers to append the rep and def levels to.
2693    /// They will not be appended to if not needed.
2694    pub fn parse(&self, src: &[u8], dst_rep: &mut Vec<u16>, dst_def: &mut Vec<u16>) {
2695        match self {
2696            Self::BOTH8(bits_to_shift, mask_to_apply) => {
2697                Self::parse_both::<1>(src, dst_rep, dst_def, *bits_to_shift, *mask_to_apply)
2698            }
2699            Self::BOTH16(bits_to_shift, mask_to_apply) => {
2700                Self::parse_both::<2>(src, dst_rep, dst_def, *bits_to_shift, *mask_to_apply)
2701            }
2702            Self::BOTH32(bits_to_shift, mask_to_apply) => {
2703                Self::parse_both::<4>(src, dst_rep, dst_def, *bits_to_shift, *mask_to_apply)
2704            }
2705            Self::REP8 => Self::parse_one::<1>(src, dst_rep),
2706            Self::REP16 => Self::parse_one::<2>(src, dst_rep),
2707            Self::REP32 => Self::parse_one::<4>(src, dst_rep),
2708            Self::DEF8 => Self::parse_one::<1>(src, dst_def),
2709            Self::DEF16 => Self::parse_one::<2>(src, dst_def),
2710            Self::DEF32 => Self::parse_one::<4>(src, dst_def),
2711            Self::NIL => {}
2712        }
2713    }
2714
2715    /// Return true if the control words contain repetition information
2716    pub fn has_rep(&self) -> bool {
2717        match self {
2718            Self::BOTH8(..)
2719            | Self::BOTH16(..)
2720            | Self::BOTH32(..)
2721            | Self::REP8
2722            | Self::REP16
2723            | Self::REP32 => true,
2724            Self::DEF8 | Self::DEF16 | Self::DEF32 | Self::NIL => false,
2725        }
2726    }
2727
2728    /// Temporarily parses the control word to inspect its properties but does not append to any buffers
2729    pub fn parse_desc(&self, src: &[u8], max_rep: u16, max_visible_def: u16) -> ControlWordDesc {
2730        match self {
2731            Self::BOTH8(bits_to_shift, mask_to_apply) => Self::parse_desc_both::<1>(
2732                src,
2733                *bits_to_shift,
2734                *mask_to_apply,
2735                max_rep,
2736                max_visible_def,
2737            ),
2738            Self::BOTH16(bits_to_shift, mask_to_apply) => Self::parse_desc_both::<2>(
2739                src,
2740                *bits_to_shift,
2741                *mask_to_apply,
2742                max_rep,
2743                max_visible_def,
2744            ),
2745            Self::BOTH32(bits_to_shift, mask_to_apply) => Self::parse_desc_both::<4>(
2746                src,
2747                *bits_to_shift,
2748                *mask_to_apply,
2749                max_rep,
2750                max_visible_def,
2751            ),
2752            Self::REP8 => Self::parse_rep_desc_one::<1>(src, max_rep),
2753            Self::REP16 => Self::parse_rep_desc_one::<2>(src, max_rep),
2754            Self::REP32 => Self::parse_rep_desc_one::<4>(src, max_rep),
2755            Self::DEF8 => Self::parse_def_desc_one::<1>(src),
2756            Self::DEF16 => Self::parse_def_desc_one::<2>(src),
2757            Self::DEF32 => Self::parse_def_desc_one::<4>(src),
2758            Self::NIL => ControlWordDesc {
2759                is_new_row: true,
2760                is_valid_item: true,
2761                is_visible: true,
2762            },
2763        }
2764    }
2765
2766    /// Creates a new parser from the number of bits used for the repetition and definition levels
2767    pub fn new(bits_rep: u8, bits_def: u8) -> Self {
2768        let total_bits = bits_rep + bits_def;
2769
2770        enum WordSize {
2771            One,
2772            Two,
2773            Four,
2774        }
2775
2776        let word_size = if total_bits <= 8 {
2777            WordSize::One
2778        } else if total_bits <= 16 {
2779            WordSize::Two
2780        } else {
2781            WordSize::Four
2782        };
2783
2784        match (bits_rep > 0, bits_def > 0, word_size) {
2785            (false, false, _) => Self::NIL,
2786            (false, true, WordSize::One) => Self::DEF8,
2787            (false, true, WordSize::Two) => Self::DEF16,
2788            (false, true, WordSize::Four) => Self::DEF32,
2789            (true, false, WordSize::One) => Self::REP8,
2790            (true, false, WordSize::Two) => Self::REP16,
2791            (true, false, WordSize::Four) => Self::REP32,
2792            (true, true, WordSize::One) => Self::BOTH8(bits_def, get_mask(bits_def as u16) as u32),
2793            (true, true, WordSize::Two) => Self::BOTH16(bits_def, get_mask(bits_def as u16) as u32),
2794            (true, true, WordSize::Four) => {
2795                Self::BOTH32(bits_def, get_mask(bits_def as u16) as u32)
2796            }
2797        }
2798    }
2799}
2800
2801#[cfg(test)]
2802mod tests {
2803    use arrow_buffer::{NullBuffer, OffsetBuffer, ScalarBuffer};
2804
2805    use crate::encodings::logical::primitive::sparse::{
2806        SparsePositionSet, SparseStructuralLayerPlan, SparseStructuralPlan, SparseValidityMeaning,
2807        SparseValiditySet,
2808    };
2809    use crate::repdef::{
2810        CompositeRepDefUnraveler, DefinitionInterpretation, RepDefUnraveler, SerializedRepDefs,
2811    };
2812
2813    use super::RepDefBuilder;
2814
2815    fn validity(values: &[bool]) -> NullBuffer {
2816        NullBuffer::from_iter(values.iter().copied())
2817    }
2818
2819    fn offsets_32(values: &[i32]) -> OffsetBuffer<i32> {
2820        OffsetBuffer::<i32>::new(ScalarBuffer::from_iter(values.iter().copied()))
2821    }
2822
2823    fn offsets_64(values: &[i64]) -> OffsetBuffer<i64> {
2824        OffsetBuffer::<i64>::new(ScalarBuffer::from_iter(values.iter().copied()))
2825    }
2826
2827    #[test]
2828    fn sparse_sibling_validity_mismatch_is_invalid_input() {
2829        let sparse = |positions| {
2830            RepDefUnraveler::new_sparse(SparseStructuralPlan {
2831                layers: vec![SparseStructuralLayerPlan::Validity {
2832                    num_slots: 2,
2833                    validity: SparseValiditySet {
2834                        meaning: SparseValidityMeaning::NullPositions,
2835                        positions,
2836                    },
2837                }],
2838                num_items: 2,
2839                num_visible_items: 2,
2840            })
2841        };
2842        let mut repdef = CompositeRepDefUnraveler::new(vec![sparse(SparsePositionSet::Empty)]);
2843        repdef.add_compatibility_check(CompositeRepDefUnraveler::new(vec![sparse(
2844            SparsePositionSet::Explicit(vec![0]),
2845        )]));
2846
2847        let err = repdef.unravel_validity(2).unwrap_err();
2848        assert!(matches!(err, lance_core::Error::InvalidInput { .. }));
2849        assert!(err.to_string().contains("incompatible validity metadata"));
2850    }
2851
2852    #[test]
2853    fn test_repdef_empty_offsets() {
2854        // Empty offsets should serialize without panicking.
2855        let mut builder = RepDefBuilder::default();
2856        builder.add_offsets(offsets_32(&[0]), None);
2857        let repdefs = RepDefBuilder::serialize(vec![builder]);
2858        assert!(repdefs.repetition_levels.is_none());
2859        assert!(repdefs.definition_levels.is_none());
2860    }
2861
2862    #[test]
2863    fn test_repdef_basic() {
2864        // Basic case, rep & def
2865        let mut builder = RepDefBuilder::default();
2866        builder.add_offsets(
2867            offsets_64(&[0, 2, 2, 5]),
2868            Some(validity(&[true, false, true])),
2869        );
2870        builder.add_offsets(
2871            offsets_64(&[0, 1, 3, 5, 5, 9]),
2872            Some(validity(&[true, true, true, false, true])),
2873        );
2874        builder.add_validity_bitmap(validity(&[
2875            true, true, true, false, false, false, true, true, false,
2876        ]));
2877
2878        let repdefs = RepDefBuilder::serialize(vec![builder]);
2879        let rep = repdefs.repetition_levels.unwrap();
2880        let def = repdefs.definition_levels.unwrap();
2881
2882        assert_eq!(vec![0, 0, 0, 3, 1, 1, 2, 1, 0, 0, 1], *def);
2883        assert_eq!(vec![2, 1, 0, 2, 2, 0, 1, 1, 0, 0, 0], *rep);
2884
2885        // [[I], [I, I]], NULL, [[NULL, NULL], NULL, [NULL, I, I, NULL]]
2886
2887        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
2888            Some(rep.as_ref().to_vec()),
2889            Some(def.as_ref().to_vec()),
2890            repdefs.def_meaning.into(),
2891            9,
2892        )]);
2893
2894        // Note: validity doesn't exactly round-trip because repdef normalizes some of the
2895        // redundant validity values
2896        assert_eq!(
2897            unraveler.unravel_validity(9).unwrap(),
2898            Some(validity(&[
2899                true, true, true, false, false, false, true, true, false
2900            ]))
2901        );
2902        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
2903        assert_eq!(off.inner(), offsets_32(&[0, 1, 3, 5, 5, 9]).inner());
2904        assert_eq!(val, Some(validity(&[true, true, true, false, true])));
2905        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
2906        assert_eq!(off.inner(), offsets_32(&[0, 2, 2, 5]).inner());
2907        assert_eq!(val, Some(validity(&[true, false, true])));
2908    }
2909
2910    #[test]
2911    fn test_repdef_simple_null_empty_list() {
2912        let check = |repdefs: SerializedRepDefs, last_def: DefinitionInterpretation| {
2913            let rep = repdefs.repetition_levels.unwrap();
2914            let def = repdefs.definition_levels.unwrap();
2915
2916            assert_eq!([1, 0, 1, 1, 0, 0], *rep);
2917            assert_eq!([0, 0, 2, 0, 1, 0], *def);
2918            assert_eq!(
2919                vec![DefinitionInterpretation::NullableItem, last_def,],
2920                repdefs.def_meaning
2921            );
2922        };
2923
2924        // Null list and empty list should be serialized mostly the same
2925
2926        // Null case
2927        let mut builder = RepDefBuilder::default();
2928        builder.add_offsets(
2929            offsets_32(&[0, 2, 2, 5]),
2930            Some(validity(&[true, false, true])),
2931        );
2932        builder.add_validity_bitmap(validity(&[true, true, true, false, true]));
2933
2934        let repdefs = RepDefBuilder::serialize(vec![builder]);
2935
2936        check(repdefs, DefinitionInterpretation::NullableList);
2937
2938        // Empty case
2939        let mut builder = RepDefBuilder::default();
2940        builder.add_offsets(offsets_32(&[0, 2, 2, 5]), None);
2941        builder.add_validity_bitmap(validity(&[true, true, true, false, true]));
2942
2943        let repdefs = RepDefBuilder::serialize(vec![builder]);
2944
2945        check(repdefs, DefinitionInterpretation::EmptyableList);
2946    }
2947
2948    #[test]
2949    fn test_repdef_empty_list_at_end() {
2950        // Regresses a failure we encountered when the last item was an empty list
2951        let mut builder = RepDefBuilder::default();
2952        builder.add_offsets(offsets_32(&[0, 2, 5, 5]), None);
2953        builder.add_validity_bitmap(validity(&[true, true, true, false, true]));
2954
2955        let repdefs = RepDefBuilder::serialize(vec![builder]);
2956
2957        let rep = repdefs.repetition_levels.unwrap();
2958        let def = repdefs.definition_levels.unwrap();
2959
2960        assert_eq!([1, 0, 1, 0, 0, 1], *rep);
2961        assert_eq!([0, 0, 0, 1, 0, 2], *def);
2962        assert_eq!(
2963            vec![
2964                DefinitionInterpretation::NullableItem,
2965                DefinitionInterpretation::EmptyableList,
2966            ],
2967            repdefs.def_meaning
2968        );
2969    }
2970
2971    #[test]
2972    fn test_repdef_abnormal_nulls() {
2973        // List nulls are allowed to have non-empty offsets and garbage values
2974        // and the add_offsets call should normalize this
2975        let mut builder = RepDefBuilder::default();
2976        builder.add_offsets(
2977            offsets_32(&[0, 2, 5, 8]),
2978            Some(validity(&[true, false, true])),
2979        );
2980        // Note: we pass 5 here and not 8.  If add_offsets tells us there is garbage nulls they
2981        // should be removed before continuing
2982        builder.add_no_null(5);
2983
2984        let repdefs = RepDefBuilder::serialize(vec![builder]);
2985
2986        let rep = repdefs.repetition_levels.unwrap();
2987        let def = repdefs.definition_levels.unwrap();
2988
2989        assert_eq!([1, 0, 1, 1, 0, 0], *rep);
2990        assert_eq!([0, 0, 1, 0, 0, 0], *def);
2991
2992        assert_eq!(
2993            vec![
2994                DefinitionInterpretation::AllValidItem,
2995                DefinitionInterpretation::NullableList,
2996            ],
2997            repdefs.def_meaning
2998        );
2999    }
3000
3001    #[test]
3002    fn test_repdef_fsl() {
3003        let mut builder = RepDefBuilder::default();
3004        builder.add_fsl(Some(validity(&[true, false])), 2, 2);
3005        builder.add_fsl(None, 2, 4);
3006        builder.add_validity_bitmap(validity(&[
3007            true, false, true, false, true, false, true, false,
3008        ]));
3009
3010        let repdefs = RepDefBuilder::serialize(vec![builder]);
3011
3012        assert_eq!(
3013            vec![
3014                DefinitionInterpretation::NullableItem,
3015                DefinitionInterpretation::AllValidItem,
3016                DefinitionInterpretation::NullableItem
3017            ],
3018            repdefs.def_meaning
3019        );
3020
3021        assert!(repdefs.repetition_levels.is_none());
3022
3023        let def = repdefs.definition_levels.unwrap();
3024
3025        assert_eq!([0, 1, 0, 1, 2, 2, 2, 2], *def);
3026
3027        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3028            None,
3029            Some(def.as_ref().to_vec()),
3030            repdefs.def_meaning.into(),
3031            8,
3032        )]);
3033
3034        assert_eq!(
3035            unraveler.unravel_validity(8).unwrap(),
3036            Some(validity(&[
3037                true, false, true, false, false, false, false, false
3038            ]))
3039        );
3040        assert_eq!(unraveler.unravel_fsl_validity(4, 2).unwrap(), None);
3041        assert_eq!(
3042            unraveler.unravel_fsl_validity(2, 2).unwrap(),
3043            Some(validity(&[true, false]))
3044        );
3045    }
3046
3047    #[test]
3048    fn test_repdef_fsl_allvalid_item() {
3049        let mut builder = RepDefBuilder::default();
3050        builder.add_fsl(Some(validity(&[true, false])), 2, 2);
3051        builder.add_fsl(None, 2, 4);
3052        builder.add_no_null(8);
3053
3054        let repdefs = RepDefBuilder::serialize(vec![builder]);
3055
3056        assert_eq!(
3057            vec![
3058                DefinitionInterpretation::AllValidItem,
3059                DefinitionInterpretation::AllValidItem,
3060                DefinitionInterpretation::NullableItem
3061            ],
3062            repdefs.def_meaning
3063        );
3064
3065        assert!(repdefs.repetition_levels.is_none());
3066
3067        let def = repdefs.definition_levels.unwrap();
3068
3069        assert_eq!([0, 0, 0, 0, 1, 1, 1, 1], *def);
3070
3071        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3072            None,
3073            Some(def.as_ref().to_vec()),
3074            repdefs.def_meaning.into(),
3075            8,
3076        )]);
3077
3078        assert_eq!(unraveler.unravel_validity(8).unwrap(), None);
3079        assert_eq!(unraveler.unravel_fsl_validity(4, 2).unwrap(), None);
3080        assert_eq!(
3081            unraveler.unravel_fsl_validity(2, 2).unwrap(),
3082            Some(validity(&[true, false]))
3083        );
3084    }
3085
3086    #[test]
3087    fn test_repdef_sliced_offsets() {
3088        // Sliced lists may have offsets that don't start with zero.  The
3089        // add_offsets call needs to normalize these to operate correctly.
3090        let mut builder = RepDefBuilder::default();
3091        builder.add_offsets(
3092            offsets_32(&[5, 7, 7, 10]),
3093            Some(validity(&[true, false, true])),
3094        );
3095        builder.add_no_null(5);
3096
3097        let repdefs = RepDefBuilder::serialize(vec![builder]);
3098
3099        let rep = repdefs.repetition_levels.unwrap();
3100        let def = repdefs.definition_levels.unwrap();
3101
3102        assert_eq!([1, 0, 1, 1, 0, 0], *rep);
3103        assert_eq!([0, 0, 1, 0, 0, 0], *def);
3104
3105        assert_eq!(
3106            vec![
3107                DefinitionInterpretation::AllValidItem,
3108                DefinitionInterpretation::NullableList,
3109            ],
3110            repdefs.def_meaning
3111        );
3112    }
3113
3114    #[test]
3115    fn test_repdef_complex_null_empty() {
3116        let mut builder = RepDefBuilder::default();
3117        builder.add_offsets(
3118            offsets_32(&[0, 4, 4, 4, 6]),
3119            Some(validity(&[true, false, true, true])),
3120        );
3121        builder.add_offsets(
3122            offsets_32(&[0, 1, 1, 2, 2, 2, 3]),
3123            Some(validity(&[true, false, true, false, true, true])),
3124        );
3125        builder.add_no_null(3);
3126
3127        let repdefs = RepDefBuilder::serialize(vec![builder]);
3128
3129        let rep = repdefs.repetition_levels.unwrap();
3130        let def = repdefs.definition_levels.unwrap();
3131
3132        assert_eq!([2, 1, 1, 1, 2, 2, 2, 1], *rep);
3133        assert_eq!([0, 1, 0, 1, 3, 4, 2, 0], *def);
3134    }
3135
3136    #[test]
3137    fn test_repdef_empty_list_no_null() {
3138        // Tests when we have some empty lists but no null lists.  This case
3139        // caused some bugs because we have definition but no nulls
3140        let mut builder = RepDefBuilder::default();
3141        builder.add_offsets(offsets_32(&[0, 4, 4, 4, 6]), None);
3142        builder.add_no_null(6);
3143
3144        let repdefs = RepDefBuilder::serialize(vec![builder]);
3145
3146        let rep = repdefs.repetition_levels.unwrap();
3147        let def = repdefs.definition_levels.unwrap();
3148
3149        assert_eq!([1, 0, 0, 0, 1, 1, 1, 0], *rep);
3150        assert_eq!([0, 0, 0, 0, 1, 1, 0, 0], *def);
3151
3152        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3153            Some(rep.as_ref().to_vec()),
3154            Some(def.as_ref().to_vec()),
3155            repdefs.def_meaning.into(),
3156            8,
3157        )]);
3158
3159        assert_eq!(unraveler.unravel_validity(6).unwrap(), None);
3160        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3161        assert_eq!(off.inner(), offsets_32(&[0, 4, 4, 4, 6]).inner());
3162        assert_eq!(val, None);
3163    }
3164
3165    #[test]
3166    fn test_repdef_all_valid() {
3167        let mut builder = RepDefBuilder::default();
3168        builder.add_offsets(offsets_64(&[0, 2, 3, 5]), None);
3169        builder.add_offsets(offsets_64(&[0, 1, 3, 5, 7, 9]), None);
3170        builder.add_no_null(9);
3171
3172        let repdefs = RepDefBuilder::serialize(vec![builder]);
3173        let rep = repdefs.repetition_levels.unwrap();
3174        assert!(repdefs.definition_levels.is_none());
3175
3176        assert_eq!([2, 1, 0, 2, 0, 2, 0, 1, 0], *rep);
3177
3178        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3179            Some(rep.as_ref().to_vec()),
3180            None,
3181            repdefs.def_meaning.into(),
3182            9,
3183        )]);
3184
3185        assert_eq!(unraveler.unravel_validity(9).unwrap(), None);
3186        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3187        assert_eq!(off.inner(), offsets_32(&[0, 1, 3, 5, 7, 9]).inner());
3188        assert_eq!(val, None);
3189        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3190        assert_eq!(off.inner(), offsets_32(&[0, 2, 3, 5]).inner());
3191        assert_eq!(val, None);
3192    }
3193
3194    #[test]
3195    fn test_repdef_nested_list_multibatch_matches_single() {
3196        // Single builder: List<List<i32>>, 3 rows.
3197        //   outer [0,2,3,5] -> rows have 2,1,2 inner lists
3198        //   inner [0,1,3,5,7,9] -> 5 inner lists, lengths 1,2,2,2,2 (9 leaf)
3199        let mut single = RepDefBuilder::default();
3200        single.add_offsets(offsets_64(&[0, 2, 3, 5]), None);
3201        single.add_offsets(offsets_64(&[0, 1, 3, 5, 7, 9]), None);
3202        single.add_no_null(9);
3203        let single_rep = RepDefBuilder::serialize(vec![single])
3204            .repetition_levels
3205            .unwrap();
3206
3207        // Same logical data split into two batches:
3208        //   batch0 = rows 0,1 : outer [0,2,3], inner [0,1,3,5] (3 inner, 5 leaf)
3209        //   batch1 = row 2    : outer [0,2],   inner [0,2,4]   (2 inner, 4 leaf)
3210        let mut b0 = RepDefBuilder::default();
3211        b0.add_offsets(offsets_64(&[0, 2, 3]), None);
3212        b0.add_offsets(offsets_64(&[0, 1, 3, 5]), None);
3213        b0.add_no_null(5);
3214        let mut b1 = RepDefBuilder::default();
3215        b1.add_offsets(offsets_64(&[0, 2]), None);
3216        b1.add_offsets(offsets_64(&[0, 2, 4]), None);
3217        b1.add_no_null(4);
3218        let multi_rep = RepDefBuilder::serialize(vec![b0, b1])
3219            .repetition_levels
3220            .unwrap();
3221
3222        assert_eq!(
3223            *single_rep, *multi_rep,
3224            "multi-batch nested-list rep levels must equal single-batch"
3225        );
3226    }
3227
3228    #[test]
3229    fn test_only_empty_lists() {
3230        let mut builder = RepDefBuilder::default();
3231        builder.add_offsets(offsets_32(&[0, 4, 4, 4, 6]), None);
3232        builder.add_no_null(6);
3233
3234        let repdefs = RepDefBuilder::serialize(vec![builder]);
3235
3236        let rep = repdefs.repetition_levels.unwrap();
3237        let def = repdefs.definition_levels.unwrap();
3238
3239        assert_eq!([1, 0, 0, 0, 1, 1, 1, 0], *rep);
3240        assert_eq!([0, 0, 0, 0, 1, 1, 0, 0], *def);
3241
3242        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3243            Some(rep.as_ref().to_vec()),
3244            Some(def.as_ref().to_vec()),
3245            repdefs.def_meaning.into(),
3246            8,
3247        )]);
3248
3249        assert_eq!(unraveler.unravel_validity(6).unwrap(), None);
3250        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3251        assert_eq!(off.inner(), offsets_32(&[0, 4, 4, 4, 6]).inner());
3252        assert_eq!(val, None);
3253    }
3254
3255    #[test]
3256    fn test_only_null_lists() {
3257        let mut builder = RepDefBuilder::default();
3258        builder.add_offsets(
3259            offsets_32(&[0, 4, 4, 4, 6]),
3260            Some(validity(&[true, false, false, true])),
3261        );
3262        builder.add_no_null(6);
3263
3264        let repdefs = RepDefBuilder::serialize(vec![builder]);
3265
3266        let rep = repdefs.repetition_levels.unwrap();
3267        let def = repdefs.definition_levels.unwrap();
3268
3269        assert_eq!([1, 0, 0, 0, 1, 1, 1, 0], *rep);
3270        assert_eq!([0, 0, 0, 0, 1, 1, 0, 0], *def);
3271
3272        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3273            Some(rep.as_ref().to_vec()),
3274            Some(def.as_ref().to_vec()),
3275            repdefs.def_meaning.into(),
3276            8,
3277        )]);
3278
3279        assert_eq!(unraveler.unravel_validity(6).unwrap(), None);
3280        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3281        assert_eq!(off.inner(), offsets_32(&[0, 4, 4, 4, 6]).inner());
3282        assert_eq!(val, Some(validity(&[true, false, false, true])));
3283    }
3284
3285    #[test]
3286    fn test_null_and_empty_lists() {
3287        let mut builder = RepDefBuilder::default();
3288        builder.add_offsets(
3289            offsets_32(&[0, 4, 4, 4, 6]),
3290            Some(validity(&[true, false, true, true])),
3291        );
3292        builder.add_no_null(6);
3293
3294        let repdefs = RepDefBuilder::serialize(vec![builder]);
3295
3296        let rep = repdefs.repetition_levels.unwrap();
3297        let def = repdefs.definition_levels.unwrap();
3298
3299        assert_eq!([1, 0, 0, 0, 1, 1, 1, 0], *rep);
3300        assert_eq!([0, 0, 0, 0, 1, 2, 0, 0], *def);
3301
3302        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3303            Some(rep.as_ref().to_vec()),
3304            Some(def.as_ref().to_vec()),
3305            repdefs.def_meaning.into(),
3306            8,
3307        )]);
3308
3309        assert_eq!(unraveler.unravel_validity(6).unwrap(), None);
3310        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3311        assert_eq!(off.inner(), offsets_32(&[0, 4, 4, 4, 6]).inner());
3312        assert_eq!(val, Some(validity(&[true, false, true, true])));
3313    }
3314
3315    #[test]
3316    fn test_repdef_null_struct_valid_list() {
3317        // This regresses a bug
3318
3319        let rep = vec![1, 0, 0, 0];
3320        let def = vec![2, 0, 2, 2];
3321        // AllValidList<NullableStruct<NullableItem>>
3322        let def_meaning = vec![
3323            DefinitionInterpretation::NullableItem,
3324            DefinitionInterpretation::NullableItem,
3325            DefinitionInterpretation::AllValidList,
3326        ];
3327        let num_items = 4;
3328
3329        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3330            Some(rep),
3331            Some(def),
3332            def_meaning.into(),
3333            num_items,
3334        )]);
3335
3336        assert_eq!(
3337            unraveler.unravel_validity(4).unwrap(),
3338            Some(validity(&[false, true, false, false]))
3339        );
3340        assert_eq!(
3341            unraveler.unravel_validity(4).unwrap(),
3342            Some(validity(&[false, true, false, false]))
3343        );
3344        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3345        assert_eq!(off.inner(), offsets_32(&[0, 4]).inner());
3346        assert_eq!(val, None);
3347    }
3348
3349    #[test]
3350    fn test_repdef_no_rep() {
3351        let mut builder = RepDefBuilder::default();
3352        builder.add_no_null(5);
3353        builder.add_validity_bitmap(validity(&[false, false, true, true, true]));
3354        builder.add_validity_bitmap(validity(&[false, true, true, true, false]));
3355
3356        let repdefs = RepDefBuilder::serialize(vec![builder]);
3357        assert!(repdefs.repetition_levels.is_none());
3358        let def = repdefs.definition_levels.unwrap();
3359
3360        assert_eq!([2, 2, 0, 0, 1], *def);
3361
3362        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3363            None,
3364            Some(def.as_ref().to_vec()),
3365            repdefs.def_meaning.into(),
3366            5,
3367        )]);
3368
3369        assert_eq!(
3370            unraveler.unravel_validity(5).unwrap(),
3371            Some(validity(&[false, false, true, true, false]))
3372        );
3373        assert_eq!(
3374            unraveler.unravel_validity(5).unwrap(),
3375            Some(validity(&[false, false, true, true, true]))
3376        );
3377        assert_eq!(unraveler.unravel_validity(5).unwrap(), None);
3378    }
3379
3380    #[test]
3381    fn test_composite_unravel() {
3382        let mut builder = RepDefBuilder::default();
3383        builder.add_offsets(
3384            offsets_64(&[0, 2, 2, 5]),
3385            Some(validity(&[true, false, true])),
3386        );
3387        builder.add_no_null(5);
3388        let repdef1 = RepDefBuilder::serialize(vec![builder]);
3389
3390        let mut builder = RepDefBuilder::default();
3391        builder.add_offsets(offsets_64(&[0, 1, 3, 5, 7, 9]), None);
3392        builder.add_no_null(9);
3393        let repdef2 = RepDefBuilder::serialize(vec![builder]);
3394
3395        let rep1 = repdef1.repetition_levels.clone().unwrap();
3396        let def1 = repdef1.definition_levels.clone().unwrap();
3397        let rep2 = repdef2.repetition_levels.clone().unwrap();
3398        assert!(repdef2.definition_levels.is_none());
3399
3400        assert_eq!([1, 0, 1, 1, 0, 0], *rep1);
3401        assert_eq!([0, 0, 1, 0, 0, 0], *def1);
3402        assert_eq!([1, 1, 0, 1, 0, 1, 0, 1, 0], *rep2);
3403
3404        let unravel1 = RepDefUnraveler::new(
3405            repdef1.repetition_levels.map(|l| l.to_vec()),
3406            repdef1.definition_levels.map(|l| l.to_vec()),
3407            repdef1.def_meaning.into(),
3408            5,
3409        );
3410        let unravel2 = RepDefUnraveler::new(
3411            repdef2.repetition_levels.map(|l| l.to_vec()),
3412            repdef2.definition_levels.map(|l| l.to_vec()),
3413            repdef2.def_meaning.into(),
3414            9,
3415        );
3416
3417        let mut unraveler = CompositeRepDefUnraveler::new(vec![unravel1, unravel2]);
3418
3419        assert!(unraveler.unravel_validity(9).unwrap().is_none());
3420        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3421        assert_eq!(
3422            off.inner(),
3423            offsets_32(&[0, 2, 2, 5, 6, 8, 10, 12, 14]).inner()
3424        );
3425        assert_eq!(
3426            val,
3427            Some(validity(&[true, false, true, true, true, true, true, true]))
3428        );
3429    }
3430
3431    #[test]
3432    fn test_repdef_multiple_builders() {
3433        // Basic case, rep & def
3434        let mut builder1 = RepDefBuilder::default();
3435        builder1.add_offsets(offsets_64(&[0, 2]), None);
3436        builder1.add_offsets(offsets_64(&[0, 1, 3]), None);
3437        builder1.add_validity_bitmap(validity(&[true, true, true]));
3438
3439        let mut builder2 = RepDefBuilder::default();
3440        builder2.add_offsets(offsets_64(&[0, 0, 3]), Some(validity(&[false, true])));
3441        builder2.add_offsets(
3442            offsets_64(&[0, 2, 2, 6]),
3443            Some(validity(&[true, false, true])),
3444        );
3445        builder2.add_validity_bitmap(validity(&[false, false, false, true, true, false]));
3446
3447        let repdefs = RepDefBuilder::serialize(vec![builder1, builder2]);
3448
3449        let rep = repdefs.repetition_levels.unwrap();
3450        let def = repdefs.definition_levels.unwrap();
3451
3452        assert_eq!([2, 1, 0, 2, 2, 0, 1, 1, 0, 0, 0], *rep);
3453        assert_eq!([0, 0, 0, 3, 1, 1, 2, 1, 0, 0, 1], *def);
3454    }
3455
3456    #[test]
3457    fn test_all_valid_validity_bitmap_serializes_as_no_null() {
3458        let mut from_bitmap = RepDefBuilder::default();
3459        from_bitmap.add_validity_bitmap(validity(&[true, true, true, true]));
3460
3461        let mut from_no_null = RepDefBuilder::default();
3462        from_no_null.add_no_null(4);
3463
3464        let from_bitmap = RepDefBuilder::serialize(vec![from_bitmap]);
3465        let from_no_null = RepDefBuilder::serialize(vec![from_no_null]);
3466
3467        assert!(from_bitmap.repetition_levels.is_none());
3468        assert!(from_bitmap.definition_levels.is_none());
3469        assert_eq!(from_bitmap.def_meaning, from_no_null.def_meaning);
3470        assert_eq!(
3471            from_bitmap.max_visible_level,
3472            from_no_null.max_visible_level
3473        );
3474    }
3475
3476    #[test]
3477    fn test_slicer() {
3478        let mut builder = RepDefBuilder::default();
3479        builder.add_offsets(
3480            offsets_64(&[0, 2, 2, 30, 30]),
3481            Some(validity(&[true, false, true, true])),
3482        );
3483        builder.add_no_null(30);
3484
3485        let repdefs = RepDefBuilder::serialize(vec![builder]);
3486
3487        let mut rep_slicer = repdefs.rep_slicer().unwrap();
3488
3489        // First 5 items include a null list so we get 6 levels (12 bytes)
3490        assert_eq!(rep_slicer.slice_next(5).len(), 12);
3491        // Next 20 are all plain
3492        assert_eq!(rep_slicer.slice_next(20).len(), 40);
3493        // Last 5 include an empty list so we get 6 levels (12 bytes)
3494        assert_eq!(rep_slicer.slice_rest().len(), 12);
3495
3496        let mut def_slicer = repdefs.rep_slicer().unwrap();
3497
3498        // First 5 items include a null list so we get 6 levels (12 bytes)
3499        assert_eq!(def_slicer.slice_next(5).len(), 12);
3500        // Next 20 are all plain
3501        assert_eq!(def_slicer.slice_next(20).len(), 40);
3502        // Last 5 include an empty list so we get 6 levels (12 bytes)
3503        assert_eq!(def_slicer.slice_rest().len(), 12);
3504    }
3505
3506    #[test]
3507    fn test_control_words() {
3508        // Convert to control words, verify expected, convert back, verify same as original
3509        fn check(
3510            rep: &[u16],
3511            def: &[u16],
3512            expected_values: Vec<u8>,
3513            expected_bytes_per_word: usize,
3514            expected_bits_rep: u8,
3515            expected_bits_def: u8,
3516        ) {
3517            let num_vals = rep.len().max(def.len());
3518            let max_rep = rep.iter().max().copied().unwrap_or(0);
3519            let max_def = def.iter().max().copied().unwrap_or(0);
3520
3521            let in_rep = if rep.is_empty() { None } else { Some(rep) };
3522            let in_def = if def.is_empty() { None } else { Some(def) };
3523
3524            let mut iter = super::build_control_word_iterator(
3525                in_rep,
3526                max_rep,
3527                in_def,
3528                max_def,
3529                max_def + 1,
3530                expected_values.len(),
3531            );
3532            assert_eq!(iter.bytes_per_word(), expected_bytes_per_word);
3533            assert_eq!(iter.bits_rep(), expected_bits_rep);
3534            assert_eq!(iter.bits_def(), expected_bits_def);
3535            let mut cw_vec = Vec::with_capacity(num_vals * iter.bytes_per_word());
3536
3537            for _ in 0..num_vals {
3538                iter.append_next(&mut cw_vec);
3539            }
3540            assert!(iter.append_next(&mut cw_vec).is_none());
3541
3542            assert_eq!(expected_values, cw_vec);
3543
3544            let parser = super::ControlWordParser::new(expected_bits_rep, expected_bits_def);
3545
3546            let mut rep_out = Vec::with_capacity(num_vals);
3547            let mut def_out = Vec::with_capacity(num_vals);
3548
3549            if expected_bytes_per_word > 0 {
3550                for slice in cw_vec.chunks_exact(expected_bytes_per_word) {
3551                    parser.parse(slice, &mut rep_out, &mut def_out);
3552                }
3553            }
3554
3555            assert_eq!(rep, rep_out.as_slice());
3556            assert_eq!(def, def_out.as_slice());
3557        }
3558
3559        // Each will need 4 bits and so we should get 1-byte control words
3560        let rep = &[0_u16, 7, 3, 2, 9, 8, 12, 5];
3561        let def = &[5_u16, 3, 1, 2, 12, 15, 0, 2];
3562        let expected = vec![
3563            0b00000101, // 0, 5
3564            0b01110011, // 7, 3
3565            0b00110001, // 3, 1
3566            0b00100010, // 2, 2
3567            0b10011100, // 9, 12
3568            0b10001111, // 8, 15
3569            0b11000000, // 12, 0
3570            0b01010010, // 5, 2
3571        ];
3572        check(rep, def, expected, 1, 4, 4);
3573
3574        // Now we need 5 bits for def so we get 2-byte control words
3575        let rep = &[0_u16, 7, 3, 2, 9, 8, 12, 5];
3576        let def = &[5_u16, 3, 1, 2, 12, 22, 0, 2];
3577        let expected = vec![
3578            0b00000101, 0b00000000, // 0, 5
3579            0b11100011, 0b00000000, // 7, 3
3580            0b01100001, 0b00000000, // 3, 1
3581            0b01000010, 0b00000000, // 2, 2
3582            0b00101100, 0b00000001, // 9, 12
3583            0b00010110, 0b00000001, // 8, 22
3584            0b10000000, 0b00000001, // 12, 0
3585            0b10100010, 0b00000000, // 5, 2
3586        ];
3587        check(rep, def, expected, 2, 4, 5);
3588
3589        // Just rep, 4 bits so 1 byte each
3590        let levels = &[0_u16, 7, 3, 2, 9, 8, 12, 5];
3591        let expected = vec![
3592            0b00000000, // 0
3593            0b00000111, // 7
3594            0b00000011, // 3
3595            0b00000010, // 2
3596            0b00001001, // 9
3597            0b00001000, // 8
3598            0b00001100, // 12
3599            0b00000101, // 5
3600        ];
3601        check(levels, &[], expected.clone(), 1, 4, 0);
3602
3603        // Just def
3604        check(&[], levels, expected, 1, 0, 4);
3605
3606        // No rep, no def, no bytes
3607        check(&[], &[], Vec::default(), 0, 0, 0);
3608    }
3609
3610    #[test]
3611    fn test_control_words_rep_index() {
3612        fn check(
3613            rep: &[u16],
3614            def: &[u16],
3615            expected_new_rows: Vec<bool>,
3616            expected_is_visible: Vec<bool>,
3617        ) {
3618            let num_vals = rep.len().max(def.len());
3619            let max_rep = rep.iter().max().copied().unwrap_or(0);
3620            let max_def = def.iter().max().copied().unwrap_or(0);
3621
3622            let in_rep = if rep.is_empty() { None } else { Some(rep) };
3623            let in_def = if def.is_empty() { None } else { Some(def) };
3624
3625            let mut iter = super::build_control_word_iterator(
3626                in_rep,
3627                max_rep,
3628                in_def,
3629                max_def,
3630                /*max_visible_def=*/ 2,
3631                expected_new_rows.len(),
3632            );
3633
3634            let mut cw_vec = Vec::with_capacity(num_vals * iter.bytes_per_word());
3635            let mut expected_new_rows = expected_new_rows.iter().copied();
3636            let mut expected_is_visible = expected_is_visible.iter().copied();
3637            for _ in 0..expected_new_rows.len() {
3638                let word_desc = iter.append_next(&mut cw_vec).unwrap();
3639                assert_eq!(word_desc.is_new_row, expected_new_rows.next().unwrap());
3640                assert_eq!(word_desc.is_visible, expected_is_visible.next().unwrap());
3641            }
3642            assert!(iter.append_next(&mut cw_vec).is_none());
3643        }
3644
3645        // 2 means new list
3646        let rep = &[2_u16, 1, 0, 2, 2, 0, 1, 1, 0, 2, 0];
3647        // These values don't matter for this test
3648        let def = &[0_u16, 0, 0, 3, 1, 1, 2, 1, 0, 0, 1];
3649
3650        // Rep & def
3651        check(
3652            rep,
3653            def,
3654            vec![
3655                true, false, false, true, true, false, false, false, false, true, false,
3656            ],
3657            vec![
3658                true, true, true, false, true, true, true, true, true, true, true,
3659            ],
3660        );
3661        // Rep only
3662        check(
3663            rep,
3664            &[],
3665            vec![
3666                true, false, false, true, true, false, false, false, false, true, false,
3667            ],
3668            vec![true; 11],
3669        );
3670        // No repetition
3671        check(
3672            &[],
3673            def,
3674            vec![
3675                true, true, true, true, true, true, true, true, true, true, true,
3676            ],
3677            vec![true; 11],
3678        );
3679        // No repetition, no definition
3680        check(
3681            &[],
3682            &[],
3683            vec![
3684                true, true, true, true, true, true, true, true, true, true, true,
3685            ],
3686            vec![true; 11],
3687        );
3688    }
3689
3690    #[test]
3691    fn regress_empty_list_case() {
3692        // This regresses a case where we had 3 null lists inside a struct
3693        let mut builder = RepDefBuilder::default();
3694        builder.add_validity_bitmap(validity(&[true, false, true]));
3695        builder.add_offsets(
3696            offsets_32(&[0, 0, 0, 0]),
3697            Some(validity(&[false, false, false])),
3698        );
3699        builder.add_no_null(0);
3700
3701        let repdefs = RepDefBuilder::serialize(vec![builder]);
3702        let rep = repdefs.repetition_levels.unwrap();
3703        let def = repdefs.definition_levels.unwrap();
3704
3705        assert_eq!([1, 1, 1], *rep);
3706        assert_eq!([1, 2, 1], *def);
3707
3708        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3709            Some(rep.as_ref().to_vec()),
3710            Some(def.as_ref().to_vec()),
3711            repdefs.def_meaning.into(),
3712            0,
3713        )]);
3714
3715        assert_eq!(unraveler.unravel_validity(0).unwrap(), None);
3716        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3717        assert_eq!(off.inner(), offsets_32(&[0, 0, 0, 0]).inner());
3718        assert_eq!(val, Some(validity(&[false, false, false])));
3719        let val = unraveler.unravel_validity(3).unwrap().unwrap();
3720        assert_eq!(val.inner(), validity(&[true, false, true]).inner());
3721    }
3722
3723    #[test]
3724    fn regress_list_ends_null_case() {
3725        let mut builder = RepDefBuilder::default();
3726        builder.add_offsets(
3727            offsets_64(&[0, 1, 2, 2]),
3728            Some(validity(&[true, true, false])),
3729        );
3730        builder.add_offsets(offsets_64(&[0, 1, 1]), Some(validity(&[true, false])));
3731        builder.add_no_null(1);
3732
3733        let repdefs = RepDefBuilder::serialize(vec![builder]);
3734        let rep = repdefs.repetition_levels.unwrap();
3735        let def = repdefs.definition_levels.unwrap();
3736
3737        assert_eq!([2, 2, 2], *rep);
3738        assert_eq!([0, 1, 2], *def);
3739
3740        let mut unraveler = CompositeRepDefUnraveler::new(vec![RepDefUnraveler::new(
3741            Some(rep.as_ref().to_vec()),
3742            Some(def.as_ref().to_vec()),
3743            repdefs.def_meaning.into(),
3744            1,
3745        )]);
3746
3747        assert_eq!(unraveler.unravel_validity(1).unwrap(), None);
3748        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3749        assert_eq!(off.inner(), offsets_32(&[0, 1, 1]).inner());
3750        assert_eq!(val, Some(validity(&[true, false])));
3751        let (off, val) = unraveler.unravel_offsets::<i32>().unwrap();
3752        assert_eq!(off.inner(), offsets_32(&[0, 1, 2, 2]).inner());
3753        assert_eq!(val, Some(validity(&[true, true, false])));
3754    }
3755
3756    #[test]
3757    fn test_mixed_unraveler() {
3758        // This tests cases where the validity is different between two different pages
3759        // because one page has nulls and the other doesn't.
3760
3761        // Simple case with one layer of validity and no repetition
3762        let mut unraveler = CompositeRepDefUnraveler::new(vec![
3763            RepDefUnraveler::new(
3764                None,
3765                Some(vec![0, 1, 0, 1]),
3766                vec![DefinitionInterpretation::NullableItem].into(),
3767                4,
3768            ),
3769            RepDefUnraveler::new(
3770                None,
3771                None,
3772                vec![DefinitionInterpretation::AllValidItem].into(),
3773                4,
3774            ),
3775        ]);
3776
3777        assert_eq!(
3778            unraveler.unravel_validity(8).unwrap(),
3779            Some(validity(&[
3780                true, false, true, false, true, true, true, true
3781            ]))
3782        );
3783
3784        // More complex case with two layers of validity and repetition
3785        let def1 = Some(vec![0, 1, 2]);
3786        let rep1 = Some(vec![1, 0, 1]);
3787
3788        let def2 = Some(vec![1, 0, 0]);
3789        let rep2 = Some(vec![1, 1, 0]);
3790
3791        let mut unraveler = CompositeRepDefUnraveler::new(vec![
3792            RepDefUnraveler::new(
3793                rep1,
3794                def1,
3795                vec![
3796                    DefinitionInterpretation::NullableItem,
3797                    DefinitionInterpretation::EmptyableList,
3798                ]
3799                .into(),
3800                2,
3801            ),
3802            RepDefUnraveler::new(
3803                rep2,
3804                def2,
3805                vec![
3806                    DefinitionInterpretation::AllValidItem,
3807                    DefinitionInterpretation::NullableList,
3808                ]
3809                .into(),
3810                2,
3811            ),
3812        ]);
3813
3814        assert_eq!(
3815            unraveler.unravel_validity(4).unwrap(),
3816            Some(validity(&[true, false, true, true]))
3817        );
3818        assert_eq!(
3819            unraveler.unravel_offsets::<i32>().unwrap(),
3820            (
3821                offsets_32(&[0, 2, 2, 2, 4]),
3822                Some(validity(&[true, true, false, true]))
3823            )
3824        );
3825    }
3826
3827    #[test]
3828    fn test_mixed_unraveler_nullable_without_def_levels() {
3829        // A page can keep nullable layer metadata even when all definition levels are 0
3830        // and no definition buffer needs to be materialized. This should decode as all-valid.
3831        let mut unraveler = CompositeRepDefUnraveler::new(vec![
3832            RepDefUnraveler::new(
3833                None,
3834                Some(vec![0, 1, 0, 1]),
3835                vec![DefinitionInterpretation::NullableItem].into(),
3836                4,
3837            ),
3838            RepDefUnraveler::new(
3839                None,
3840                None,
3841                vec![DefinitionInterpretation::NullableItem].into(),
3842                4,
3843            ),
3844        ]);
3845
3846        assert_eq!(
3847            unraveler.unravel_validity(8).unwrap(),
3848            Some(validity(&[
3849                true, false, true, false, true, true, true, true
3850            ]))
3851        );
3852    }
3853}