| 668 | } |
| 669 | |
| 670 | fn merge_batch( |
| 671 | &mut self, |
| 672 | values: &[ArrayRef], |
| 673 | group_indices: &[usize], |
| 674 | opt_filter: Option<&BooleanArray>, |
| 675 | total_num_groups: usize, |
| 676 | ) -> Result<()> { |
| 677 | self.resize_states(total_num_groups); |
| 678 | |
| 679 | let mut ordering_buf = Vec::with_capacity(self.ordering_req.len()); |
| 680 | |
| 681 | let (is_set_arr, val_and_order_cols) = match values.split_last() { |
| 682 | Some(result) => result, |
| 683 | None => return internal_err!("Empty row in FIRST_VALUE"), |
| 684 | }; |
| 685 | |
| 686 | let is_set_arr = as_boolean_array(is_set_arr)?; |
| 687 | |
| 688 | let vals = &values[0]; |
| 689 | // The overhead of calling `extract_row_at_idx_to_buf` is somewhat high, so we need to minimize its calls as much as possible. |
| 690 | let groups = self.get_filtered_extreme_of_each_group( |
| 691 | &val_and_order_cols[1..], |
| 692 | group_indices, |
| 693 | opt_filter, |
| 694 | vals, |
| 695 | Some(is_set_arr), |
| 696 | )?; |
| 697 | |
| 698 | for (group_idx, idx) in groups.into_iter() { |
| 699 | extract_row_at_idx_to_buf(&val_and_order_cols[1..], idx, &mut ordering_buf)?; |
| 700 | |
| 701 | if self.should_update_state(group_idx, &ordering_buf)? { |
| 702 | self.update_state(group_idx, &ordering_buf, vals, idx)?; |
| 703 | } |
| 704 | } |
| 705 | |
| 706 | Ok(()) |
| 707 | } |
| 708 | |
| 709 | fn size(&self) -> usize { |
| 710 | self.state.size() |