| 596 | |
| 597 | impl<S: ValueState + 'static> GroupsAccumulator for FirstLastGroupsAccumulator<S> { |
| 598 | fn update_batch( |
| 599 | &mut self, |
| 600 | // e.g. first_value(a order by b): values_and_order_cols will be [a, b] |
| 601 | values_and_order_cols: &[ArrayRef], |
| 602 | group_indices: &[usize], |
| 603 | opt_filter: Option<&BooleanArray>, |
| 604 | total_num_groups: usize, |
| 605 | ) -> Result<()> { |
| 606 | self.resize_states(total_num_groups); |
| 607 | |
| 608 | let vals = &values_and_order_cols[0]; |
| 609 | |
| 610 | let mut ordering_buf = Vec::with_capacity(self.ordering_req.len()); |
| 611 | |
| 612 | // The overhead of calling `extract_row_at_idx_to_buf` is somewhat high, so we need to minimize its calls as much as possible. |
| 613 | for (group_idx, idx) in self |
| 614 | .get_filtered_extreme_of_each_group( |
| 615 | &values_and_order_cols[1..], |
| 616 | group_indices, |
| 617 | opt_filter, |
| 618 | vals, |
| 619 | None, |
| 620 | )? |
| 621 | .into_iter() |
| 622 | { |
| 623 | extract_row_at_idx_to_buf( |
| 624 | &values_and_order_cols[1..], |
| 625 | idx, |
| 626 | &mut ordering_buf, |
| 627 | )?; |
| 628 | |
| 629 | if self.should_update_state(group_idx, &ordering_buf)? { |
| 630 | self.update_state(group_idx, &ordering_buf, vals, idx)?; |
| 631 | } |
| 632 | } |
| 633 | |
| 634 | Ok(()) |
| 635 | } |
| 636 | |
| 637 | fn evaluate(&mut self, emit_to: EmitTo) -> Result<ArrayRef> { |
| 638 | Ok(self.take_state(emit_to)?.0) |