| 461 | } |
| 462 | |
| 463 | fn logical_nulls(&self) -> Option<NullBuffer> { |
| 464 | let len = self.len(); |
| 465 | let nulls = self.values.logical_nulls()?; |
| 466 | let mut out = BooleanBufferBuilder::new(len); |
| 467 | let offset = self.run_ends.offset(); |
| 468 | let mut valid_start = 0; |
| 469 | let mut last_end = 0; |
| 470 | for (idx, end) in self.run_ends.values().iter().enumerate() { |
| 471 | let end = end.as_usize(); |
| 472 | if end < offset { |
| 473 | continue; |
| 474 | } |
| 475 | let end = (end - offset).min(len); |
| 476 | if nulls.is_null(idx) { |
| 477 | if valid_start < last_end { |
| 478 | out.append_n(last_end - valid_start, true); |
| 479 | } |
| 480 | out.append_n(end - last_end, false); |
| 481 | valid_start = end; |
| 482 | } |
| 483 | last_end = end; |
| 484 | if end == len { |
| 485 | break; |
| 486 | } |
| 487 | } |
| 488 | if valid_start < len { |
| 489 | out.append_n(len - valid_start, true) |
| 490 | } |
| 491 | // Sanity check |
| 492 | assert_eq!(out.len(), len); |
| 493 | Some(out.finish().into()) |
| 494 | } |
| 495 | |
| 496 | fn is_nullable(&self) -> bool { |
| 497 | !self.is_empty() && self.values.is_nullable() |