Partition a batch of rows by a key extracted from each row. `key_fn` maps each row to a partition key (e.g., the branch a row takes in an IF/ELSE trigger body). Rows with the same key go to the same partition. If the number of unique keys exceeds `max_partitions`, returns `CircuitBroken` and the caller should fall back to row-at-a-time.
(
rows: &[TriggerBatchRow],
max_partitions: usize,
key_fn: F,
)
| 39 | /// If the number of unique keys exceeds `max_partitions`, returns |
| 40 | /// `CircuitBroken` and the caller should fall back to row-at-a-time. |
| 41 | pub fn partition_batch<F>( |
| 42 | rows: &[TriggerBatchRow], |
| 43 | max_partitions: usize, |
| 44 | key_fn: F, |
| 45 | ) -> PartitionResult |
| 46 | where |
| 47 | F: Fn(&TriggerBatchRow) -> String, |
| 48 | { |
| 49 | let mut partitions: std::collections::HashMap<String, Vec<usize>> = |
| 50 | std::collections::HashMap::new(); |
| 51 | |
| 52 | for (idx, row) in rows.iter().enumerate() { |
| 53 | let key = key_fn(row); |
| 54 | partitions.entry(key).or_default().push(idx); |
| 55 | |
| 56 | // Early exit if we exceed the limit. |
| 57 | if partitions.len() > max_partitions { |
| 58 | return PartitionResult::CircuitBroken { |
| 59 | partition_count: partitions.len(), |
| 60 | }; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | let result = partitions |
| 65 | .into_iter() |
| 66 | .map(|(key, row_indices)| BatchPartition { key, row_indices }) |
| 67 | .collect(); |
| 68 | |
| 69 | PartitionResult::Partitions(result) |
| 70 | } |
| 71 | |
| 72 | /// Partition rows by a field value from NEW fields. |
| 73 | /// |