parquet/arrow/record_reader/
definition_levels.rs1use arrow_array::builder::BooleanBufferBuilder;
19use arrow_buffer::Buffer;
20use arrow_buffer::bit_chunk_iterator::UnalignedBitChunk;
21use arrow_buffer::bit_util::compress;
22use bytes::Bytes;
23
24use crate::arrow::buffer::bit_util::count_set_bits;
25use crate::basic::Encoding;
26use crate::column::reader::decoder::{
27 ColumnLevelDecoder, DefinitionLevelDecoder, DefinitionLevelDecoderImpl,
28};
29use crate::encodings::rle::run_len;
30use crate::errors::{ParquetError, Result};
31use crate::schema::types::ColumnDescPtr;
32
33enum BufferInner {
34 Full {
36 levels: Vec<i16>,
37 nulls: BooleanBufferBuilder,
38 max_level: i16,
39 },
40 Mask { nulls: BooleanBufferBuilder },
46}
47
48pub struct DefinitionLevelBuffer {
49 inner: BufferInner,
50
51 len: usize,
55}
56
57impl DefinitionLevelBuffer {
58 pub fn new(desc: &ColumnDescPtr, null_mask_only: bool) -> Self {
59 let inner = match null_mask_only {
60 true => {
61 assert_eq!(
62 desc.max_def_level(),
63 1,
64 "max definition level must be 1 to only compute null bitmask"
65 );
66
67 assert_eq!(
68 desc.max_rep_level(),
69 0,
70 "max repetition level must be 0 to only compute null bitmask"
71 );
72
73 BufferInner::Mask {
74 nulls: BooleanBufferBuilder::new(0),
75 }
76 }
77 false => BufferInner::Full {
78 levels: Vec::new(),
79 nulls: BooleanBufferBuilder::new(0),
80 max_level: desc.max_def_level(),
81 },
82 };
83
84 Self { inner, len: 0 }
85 }
86
87 pub fn consume_levels(&mut self) -> Option<Vec<i16>> {
89 match &mut self.inner {
90 BufferInner::Full { levels, .. } => Some(std::mem::take(levels)),
91 BufferInner::Mask { .. } => None,
92 }
93 }
94
95 pub fn consume_bitmask(&mut self) -> Option<Buffer> {
97 self.len = 0;
98 let nulls = match &mut self.inner {
99 BufferInner::Full { nulls, .. } => nulls,
100 BufferInner::Mask { nulls } => nulls,
101 };
102
103 let buffer = nulls.finish().into_inner();
105
106 if buffer.is_empty() {
108 return None;
109 }
110
111 Some(buffer)
112 }
113
114 pub fn nulls(&self) -> &BooleanBufferBuilder {
115 match &self.inner {
116 BufferInner::Full { nulls, .. } => nulls,
117 BufferInner::Mask { nulls } => nulls,
118 }
119 }
120
121 pub fn levels(&self) -> Option<&[i16]> {
124 match &self.inner {
125 BufferInner::Full { levels, .. } => Some(levels.as_slice()),
126 BufferInner::Mask { .. } => None,
127 }
128 }
129}
130
131pub(crate) fn build_filtered_validity_bitmap(
144 def_levels: &[i16],
145 rep_filter: Option<(&[i16], i16)>,
146 include_threshold: Option<i16>,
147 value_level: i16,
148 bitmap: &mut BooleanBufferBuilder,
149) -> usize {
150 const CHUNKS: usize = u64::BITS as usize;
151 if include_threshold.is_none() && rep_filter.is_none() {
153 let (chunks, remainder) = def_levels.as_chunks::<CHUNKS>();
154 for chunk in chunks {
155 let mut word: u64 = 0;
156 for (i, &d) in chunk.iter().enumerate() {
157 word |= ((d >= value_level) as u64) << i;
158 }
159 bitmap.append_word(word, u64::BITS as usize);
160 }
161 for &d in remainder {
162 bitmap.append(d >= value_level);
163 }
164 return def_levels.len();
165 }
166
167 let mut item_count: usize = 0;
169 let (chunks, remainder) = def_levels.as_chunks::<CHUNKS>();
170 let remainder_offset = def_levels.len() - remainder.len();
171
172 for (chunk_idx, chunk) in chunks.iter().enumerate() {
173 let base = chunk_idx * u64::BITS as usize;
174 let mut include_mask: u64 = 0;
175 let mut value_mask: u64 = 0;
176 for (i, &d) in chunk.iter().enumerate() {
177 let include = include_threshold.is_none_or(|threshold| threshold <= d)
178 && rep_filter.is_none_or(|(reps, max_rep)| reps[base + i] <= max_rep);
179 include_mask |= (include as u64) << i;
180 value_mask |= ((d >= value_level) as u64) << i;
181 }
182
183 let count = include_mask.count_ones() as usize;
184 let compact = compress(value_mask, include_mask);
185 bitmap.append_word(compact, count);
186 item_count += count;
187 }
188
189 for idx in remainder_offset..def_levels.len() {
190 let d = def_levels[idx];
191 if let Some(threshold) = include_threshold
192 && d < threshold
193 {
194 continue;
195 }
196 if let Some((reps, max_rep)) = rep_filter
197 && reps[idx] > max_rep
198 {
199 continue;
200 }
201 bitmap.append(d >= value_level);
202 item_count += 1;
203 }
204
205 item_count
206}
207
208enum MaybePacked {
209 Packed(PackedDecoder),
210 Fallback(DefinitionLevelDecoderImpl),
211}
212
213pub struct DefinitionLevelBufferDecoder {
214 max_level: i16,
215 decoder: MaybePacked,
216}
217
218impl DefinitionLevelBufferDecoder {
219 pub fn new(max_level: i16, packed: bool) -> Self {
220 let decoder = match packed {
221 true => MaybePacked::Packed(PackedDecoder::new()),
222 false => MaybePacked::Fallback(DefinitionLevelDecoderImpl::new(max_level)),
223 };
224
225 Self { max_level, decoder }
226 }
227}
228
229impl ColumnLevelDecoder for DefinitionLevelBufferDecoder {
230 type Buffer = DefinitionLevelBuffer;
231
232 fn set_data(&mut self, encoding: Encoding, data: Bytes) -> Result<()> {
233 match &mut self.decoder {
234 MaybePacked::Packed(d) => d.set_data(encoding, data),
235 MaybePacked::Fallback(d) => d.set_data(encoding, data)?,
236 }
237 Ok(())
238 }
239}
240
241impl DefinitionLevelDecoder for DefinitionLevelBufferDecoder {
242 fn read_def_levels(
243 &mut self,
244 writer: &mut Self::Buffer,
245 num_levels: usize,
246 ) -> Result<(usize, usize)> {
247 match (&mut writer.inner, &mut self.decoder) {
248 (
249 BufferInner::Full {
250 levels,
251 nulls,
252 max_level,
253 },
254 MaybePacked::Fallback(decoder),
255 ) => {
256 assert_eq!(self.max_level, *max_level);
257
258 let start = levels.len();
259 let (values_read, levels_read) = decoder.read_def_levels(levels, num_levels)?;
260
261 if values_read == levels_read {
262 nulls.append_n(levels_read, true);
264 } else if values_read == 0 {
265 nulls.append_n(levels_read, false);
267 } else {
268 unsafe {
270 nulls.extend_trusted_len(
271 levels[start..].iter().map(|level| level == max_level),
272 );
273 }
274 }
275
276 Ok((values_read, levels_read))
277 }
278 (BufferInner::Mask { nulls }, MaybePacked::Packed(decoder)) => {
279 assert_eq!(self.max_level, 1);
280
281 if let Some(count) = decoder.try_consume_all_valid(num_levels)? {
285 nulls.append_n(count, true);
286 return Ok((count, count)); }
288
289 let start = nulls.len();
291 let levels_read = decoder.read(nulls, num_levels)?;
292
293 let values_read = count_set_bits(nulls.as_slice(), start..start + levels_read);
294 Ok((values_read, levels_read))
295 }
296 _ => unreachable!("inconsistent null mask"),
297 }
298 }
299
300 fn skip_def_levels(&mut self, num_levels: usize) -> Result<(usize, usize)> {
301 match &mut self.decoder {
302 MaybePacked::Fallback(decoder) => decoder.skip_def_levels(num_levels),
303 MaybePacked::Packed(decoder) => decoder.skip(num_levels),
304 }
305 }
306}
307
308struct PackedDecoder {
323 data: Bytes,
324 data_offset: usize,
325 rle_left: usize,
326 rle_value: bool,
327 packed_count: usize,
328 packed_offset: usize,
329}
330
331impl PackedDecoder {
332 fn next_rle_block(&mut self) -> Result<()> {
333 let indicator_value = self.decode_header()?;
334 let num_values = run_len(indicator_value as u64)? as usize;
335 if indicator_value & 1 == 1 {
336 self.packed_count = num_values;
337 self.packed_offset = 0;
338 } else {
339 self.rle_left = num_values;
340 let byte = *self.data.as_ref().get(self.data_offset).ok_or_else(|| {
341 ParquetError::EOF(
342 "unexpected end of file whilst decoding definition levels rle value".into(),
343 )
344 })?;
345
346 self.data_offset += 1;
347 self.rle_value = byte != 0;
348 }
349 Ok(())
350 }
351
352 fn decode_header(&mut self) -> Result<i64> {
354 let mut offset = 0;
355 let mut v: i64 = 0;
356 while offset < 10 {
357 let byte = *self
358 .data
359 .as_ref()
360 .get(self.data_offset + offset)
361 .ok_or_else(|| {
362 ParquetError::EOF(
363 "unexpected end of file whilst decoding definition levels rle header"
364 .into(),
365 )
366 })?;
367
368 v |= ((byte & 0x7F) as i64) << (offset * 7);
369 offset += 1;
370 if byte & 0x80 == 0 {
371 self.data_offset += offset;
372 return Ok(v);
373 }
374 }
375 Err(general_err!("too many bytes for VLQ"))
376 }
377}
378
379impl PackedDecoder {
380 fn new() -> Self {
381 Self {
382 data: Bytes::from(vec![]),
383 data_offset: 0,
384 rle_left: 0,
385 rle_value: false,
386 packed_count: 0,
387 packed_offset: 0,
388 }
389 }
390
391 fn set_data(&mut self, encoding: Encoding, data: Bytes) {
392 self.rle_left = 0;
393 self.rle_value = false;
394 self.packed_offset = 0;
395 self.packed_count = match encoding {
396 Encoding::RLE => 0,
397 #[expect(deprecated)]
398 Encoding::BIT_PACKED => data.len() * 8,
399 _ => unreachable!("invalid level encoding: {}", encoding),
400 };
401 self.data = data;
402 self.data_offset = 0;
403 }
404
405 fn try_consume_all_valid(&mut self, len: usize) -> Result<Option<usize>> {
414 if self.rle_left == 0 && self.packed_count == self.packed_offset {
416 if self.data_offset < self.data.len() {
417 self.next_rle_block()?;
418 } else {
419 return Ok(None);
421 }
422 }
423
424 if self.rle_left >= len && self.rle_value {
427 self.rle_left -= len;
428 return Ok(Some(len));
429 }
430
431 Ok(None)
434 }
435
436 fn read(&mut self, buffer: &mut BooleanBufferBuilder, len: usize) -> Result<usize> {
437 let mut read = 0;
438 while read != len {
439 if self.rle_left != 0 {
440 let to_read = self.rle_left.min(len - read);
441 buffer.append_n(to_read, self.rle_value);
442 self.rle_left -= to_read;
443 read += to_read;
444 } else if self.packed_count != self.packed_offset {
445 let to_read = (self.packed_count - self.packed_offset).min(len - read);
446 let offset = self.data_offset * 8 + self.packed_offset;
447 buffer.append_packed_range(offset..offset + to_read, self.data.as_ref());
448 self.packed_offset += to_read;
449 read += to_read;
450
451 if self.packed_offset == self.packed_count {
452 self.data_offset += self.packed_count / 8;
453 }
454 } else if self.data_offset == self.data.len() {
455 break;
456 } else {
457 self.next_rle_block()?
458 }
459 }
460 Ok(read)
461 }
462
463 fn skip(&mut self, level_num: usize) -> Result<(usize, usize)> {
467 let mut skipped_value = 0;
468 let mut skipped_level = 0;
469 while skipped_level != level_num {
470 if self.rle_left != 0 {
471 let to_skip = self.rle_left.min(level_num - skipped_level);
472 self.rle_left -= to_skip;
473 skipped_level += to_skip;
474 if self.rle_value {
475 skipped_value += to_skip;
476 }
477 } else if self.packed_count != self.packed_offset {
478 let to_skip =
479 (self.packed_count - self.packed_offset).min(level_num - skipped_level);
480 let offset = self.data_offset * 8 + self.packed_offset;
481 let bit_chunk = UnalignedBitChunk::new(self.data.as_ref(), offset, to_skip);
482 skipped_value += bit_chunk.count_ones();
483 self.packed_offset += to_skip;
484 skipped_level += to_skip;
485 if self.packed_offset == self.packed_count {
486 self.data_offset += self.packed_count / 8;
487 }
488 } else if self.data_offset == self.data.len() {
489 break;
490 } else {
491 self.next_rle_block()?
492 }
493 }
494 Ok((skipped_value, skipped_level))
495 }
496}
497
498#[cfg(test)]
499mod tests {
500 use super::*;
501
502 use crate::encodings::rle::RleEncoder;
503 use crate::util::bit_util::BitWriter;
504 use rand::{RngExt, rng};
505
506 #[test]
507 fn test_build_validity_bitmap_unfiltered_word_chunk() {
508 let def_levels = (0..65)
511 .map(|i| if i % 3 == 0 { 2 } else { 1 })
512 .collect::<Vec<_>>();
513 let mut bitmap = BooleanBufferBuilder::new(0);
514
515 assert_eq!(
516 build_filtered_validity_bitmap(&def_levels, None, None, 2, &mut bitmap),
517 def_levels.len()
518 );
519
520 let bitmap = bitmap.finish();
521 for (idx, def) in def_levels.iter().enumerate() {
522 assert_eq!(bitmap.value(idx), *def >= 2);
523 }
524 }
525
526 #[test]
527 fn test_packed_decoder() {
528 let mut rng = rng();
529 let len: usize = rng.random_range(512..1024);
530
531 let mut expected = BooleanBufferBuilder::new(len);
532 let mut encoder = RleEncoder::new(1, 1024);
533 for _ in 0..len {
534 let bool = rng.random_bool(0.8);
535 encoder.put(bool as u64);
536 expected.append(bool);
537 }
538 assert_eq!(expected.len(), len);
539
540 let encoded = encoder.consume();
541 let mut decoder = PackedDecoder::new();
542 decoder.set_data(Encoding::RLE, encoded.into());
543
544 let mut decoded = BooleanBufferBuilder::new(len);
546 loop {
547 let remaining = len - decoded.len();
548 if remaining == 0 {
549 break;
550 }
551
552 let to_read = rng.random_range(1..=remaining);
553 decoder.read(&mut decoded, to_read).unwrap();
554 }
555
556 assert_eq!(decoded.len(), len);
557 assert_eq!(decoded.as_slice(), expected.as_slice());
558 }
559
560 #[test]
561 fn test_packed_decoder_skip() {
562 let mut rng = rng();
563 let len: usize = rng.random_range(512..1024);
564
565 let mut expected = BooleanBufferBuilder::new(len);
566 let mut encoder = RleEncoder::new(1, 1024);
567
568 let mut total_value = 0;
569 for _ in 0..len {
570 let bool = rng.random_bool(0.8);
571 encoder.put(bool as u64);
572 expected.append(bool);
573 if bool {
574 total_value += 1;
575 }
576 }
577 assert_eq!(expected.len(), len);
578
579 let encoded = encoder.consume();
580 let mut decoder = PackedDecoder::new();
581 decoder.set_data(Encoding::RLE, encoded.into());
582
583 let mut skip_value = 0;
584 let mut read_value = 0;
585 let mut skip_level = 0;
586 let mut read_level = 0;
587
588 loop {
589 let offset = skip_level + read_level;
590 let remaining_levels = len - offset;
591 if remaining_levels == 0 {
592 break;
593 }
594 let to_read_or_skip_level = rng.random_range(1..=remaining_levels);
595 if rng.random_bool(0.5) {
596 let (skip_val_num, skip_level_num) = decoder.skip(to_read_or_skip_level).unwrap();
597 skip_value += skip_val_num;
598 skip_level += skip_level_num
599 } else {
600 let mut decoded = BooleanBufferBuilder::new(to_read_or_skip_level);
601 let read_level_num = decoder.read(&mut decoded, to_read_or_skip_level).unwrap();
602 read_level += read_level_num;
603 for i in 0..read_level_num {
604 assert!(!decoded.is_empty());
605 let read_bit = decoded.get_bit(i);
607 if read_bit {
608 read_value += 1;
609 }
610 let expect_bit = expected.get_bit(i + offset);
611 assert_eq!(read_bit, expect_bit);
612 }
613 }
614 }
615 assert_eq!(read_level + skip_level, len);
616 assert_eq!(read_value + skip_value, total_value);
617 }
618
619 #[test]
620 fn test_try_consume_all_valid() {
621 let len = 100;
623 let mut encoder = RleEncoder::new(1, 1024);
624 for _ in 0..len {
625 encoder.put(1); }
627 let encoded = encoder.consume();
628 let mut decoder = PackedDecoder::new();
629 decoder.set_data(Encoding::RLE, encoded.into());
630
631 let result = decoder.try_consume_all_valid(len).unwrap();
633 assert_eq!(result, Some(len));
634
635 let mut encoder = RleEncoder::new(1, 1024);
637 for _ in 0..len {
638 encoder.put(0); }
640 let encoded = encoder.consume();
641 let mut decoder = PackedDecoder::new();
642 decoder.set_data(Encoding::RLE, encoded.into());
643
644 let result = decoder.try_consume_all_valid(len).unwrap();
646 assert_eq!(result, None);
647
648 let mut encoder = RleEncoder::new(1, 1024);
650 for _ in 0..10 {
651 encoder.put(1); }
653 for _ in 0..10 {
654 encoder.put(0); }
656 let encoded = encoder.consume();
657 let mut decoder = PackedDecoder::new();
658 decoder.set_data(Encoding::RLE, encoded.into());
659
660 let result = decoder.try_consume_all_valid(20).unwrap();
663 assert_eq!(result, None);
664
665 decoder.set_data(Encoding::RLE, {
667 let mut encoder = RleEncoder::new(1, 1024);
668 for _ in 0..10 {
669 encoder.put(1);
670 }
671 for _ in 0..10 {
672 encoder.put(0);
673 }
674 encoder.consume().into()
675 });
676
677 let result = decoder.try_consume_all_valid(5).unwrap();
678 assert_eq!(result, Some(5));
679
680 let result = decoder.try_consume_all_valid(5).unwrap();
682 assert_eq!(result, Some(5));
683
684 let result = decoder.try_consume_all_valid(5).unwrap();
686 assert_eq!(result, None);
687 }
688
689 #[test]
690 fn test_packed_decoder_invalid_run_len() {
691 let mut writer = BitWriter::new(16);
692 writer.put_vlq_int(u64::MAX);
693 let mut decoder = PackedDecoder::new();
694 decoder.set_data(Encoding::RLE, writer.consume().into());
695
696 let mut decoded = BooleanBufferBuilder::new(8);
697 let err = decoder.read(&mut decoded, 8).unwrap_err();
698 assert_eq!(
699 err.to_string(),
700 "Parquet error: Invalid or corrupted RLE run length 18446744073709551615. Max allowed is 2147483647"
701 );
702 }
703}