Inner loop for set operations, parameterized by const generic to avoid branching inside the hot loop.
(
l: &GenericListArray<OffsetSize>,
r: &GenericListArray<OffsetSize>,
rows_l: &arrow::row::Rows,
rows_r: &arrow::row::Rows,
field: Arc<Field>,
combined_values: &ArrayRef,
r
| 394 | /// Inner loop for set operations, parameterized by const generic to |
| 395 | /// avoid branching inside the hot loop. |
| 396 | fn generic_set_loop<OffsetSize: OffsetSizeTrait, const IS_UNION: bool>( |
| 397 | l: &GenericListArray<OffsetSize>, |
| 398 | r: &GenericListArray<OffsetSize>, |
| 399 | rows_l: &arrow::row::Rows, |
| 400 | rows_r: &arrow::row::Rows, |
| 401 | field: Arc<Field>, |
| 402 | combined_values: &ArrayRef, |
| 403 | r_offset: usize, |
| 404 | ) -> Result<ArrayRef> { |
| 405 | let l_offsets = l.value_offsets(); |
| 406 | let r_offsets = r.value_offsets(); |
| 407 | let l_first = l.offsets()[0].as_usize(); |
| 408 | let r_first = r.offsets()[0].as_usize(); |
| 409 | |
| 410 | let mut result_offsets = Vec::with_capacity(l.len() + 1); |
| 411 | result_offsets.push(OffsetSize::usize_as(0)); |
| 412 | let initial_capacity = if IS_UNION { |
| 413 | // Union can include all elements from both sides |
| 414 | rows_l.num_rows() |
| 415 | } else { |
| 416 | // Intersect result is bounded by the smaller side |
| 417 | rows_l.num_rows().min(rows_r.num_rows()) |
| 418 | }; |
| 419 | |
| 420 | let mut indices: Vec<usize> = Vec::with_capacity(initial_capacity); |
| 421 | |
| 422 | // Reuse hash sets across iterations |
| 423 | let mut seen = HashSet::new(); |
| 424 | let mut lookup_set = HashSet::new(); |
| 425 | for i in 0..l.len() { |
| 426 | let last_offset = *result_offsets.last().unwrap(); |
| 427 | |
| 428 | if l.is_null(i) || r.is_null(i) { |
| 429 | result_offsets.push(last_offset); |
| 430 | continue; |
| 431 | } |
| 432 | |
| 433 | let l_start = l_offsets[i].as_usize() - l_first; |
| 434 | let l_end = l_offsets[i + 1].as_usize() - l_first; |
| 435 | let r_start = r_offsets[i].as_usize() - r_first; |
| 436 | let r_end = r_offsets[i + 1].as_usize() - r_first; |
| 437 | |
| 438 | seen.clear(); |
| 439 | |
| 440 | if IS_UNION { |
| 441 | for idx in l_start..l_end { |
| 442 | let row = rows_l.row(idx); |
| 443 | if seen.insert(row) { |
| 444 | indices.push(idx); |
| 445 | } |
| 446 | } |
| 447 | for idx in r_start..r_end { |
| 448 | let row = rows_r.row(idx); |
| 449 | if seen.insert(row) { |
| 450 | indices.push(idx + r_offset); |
| 451 | } |
| 452 | } |
| 453 | } else { |
nothing calls this directly
no test coverage detected
searching dependent graphs…