(
&self,
nested: &mut Iterative<'b, S, u64>,
local_arrangements: &VariableMap<Iterative<'b, S, u64>>,
context: &mut I,
)
| 65 | } |
| 66 | |
| 67 | fn implement<'b, T, I, S>( |
| 68 | &self, |
| 69 | nested: &mut Iterative<'b, S, u64>, |
| 70 | local_arrangements: &VariableMap<Iterative<'b, S, u64>>, |
| 71 | context: &mut I, |
| 72 | ) -> (Implemented<'b, S>, ShutdownHandle) |
| 73 | where |
| 74 | T: Timestamp + Lattice, |
| 75 | I: ImplContext<T>, |
| 76 | S: Scope<Timestamp = T>, |
| 77 | { |
| 78 | let (relation, mut shutdown_handle) = |
| 79 | self.plan.implement(nested, local_arrangements, context); |
| 80 | |
| 81 | // We split the incoming tuples into their (key, value) parts. |
| 82 | let tuples = { |
| 83 | let (tuples, shutdown) = |
| 84 | relation.tuples_by_variables(nested, context, &self.key_variables); |
| 85 | shutdown_handle.merge_with(shutdown); |
| 86 | tuples |
| 87 | }; |
| 88 | |
| 89 | // For each aggregation function that is to be applied, we |
| 90 | // need to determine the index (into the value part of each |
| 91 | // tuple) at which its argument is to be found. |
| 92 | |
| 93 | let mut value_offsets = Vec::new(); |
| 94 | let mut seen = Vec::new(); |
| 95 | |
| 96 | for variable in self.aggregation_variables.iter() { |
| 97 | if !seen.contains(variable) { |
| 98 | seen.push(*variable); |
| 99 | value_offsets.push(seen.len() - 1); |
| 100 | } else { |
| 101 | value_offsets.push(AsBinding::binds(&seen, *variable).unwrap()); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | // Users can specify weird find clauses like [:find ?key1 (min ?v1) ?key2] |
| 106 | // and we would like to avoid an extra projection. Thus, we pre-compute |
| 107 | // the correct output offset for each aggregation. |
| 108 | |
| 109 | let mut variables = self.variables.clone(); |
| 110 | let mut output_offsets = Vec::new(); |
| 111 | |
| 112 | for variable in self.aggregation_variables.iter() { |
| 113 | let output_index = AsBinding::binds(&variables, *variable).unwrap(); |
| 114 | output_offsets.push(output_index); |
| 115 | |
| 116 | variables[output_index] = 0; |
| 117 | } |
| 118 | |
| 119 | let mut collections = Vec::new(); |
| 120 | |
| 121 | // We iterate over all aggregations and keep track of the |
| 122 | // resulting collections, s.t. they can be joined afterwards. |
| 123 | for (i, aggregation_fn) in self.aggregation_fns.iter().enumerate() { |
| 124 | let value_offset = value_offsets[i]; |
nothing calls this directly
no test coverage detected