(
op: BinOp,
left: &[InstantSample],
right: &[InstantSample],
return_bool: bool,
ts: i64,
)
| 53 | } |
| 54 | |
| 55 | fn eval_vector_binop( |
| 56 | op: BinOp, |
| 57 | left: &[InstantSample], |
| 58 | right: &[InstantSample], |
| 59 | return_bool: bool, |
| 60 | ts: i64, |
| 61 | ) -> Result<Value, PromqlError> { |
| 62 | let right_map: BTreeMap<String, &InstantSample> = |
| 63 | right.iter().map(|s| (match_key(&s.labels), s)).collect(); |
| 64 | |
| 65 | let mut result = Vec::new(); |
| 66 | for l in left { |
| 67 | let key = match_key(&l.labels); |
| 68 | if let Some(r) = right_map.get(&key) { |
| 69 | let val = apply_binop(op, l.value, r.value, return_bool); |
| 70 | if !val.is_nan() || !op.is_comparison() || return_bool { |
| 71 | let mut labels = l.labels.clone(); |
| 72 | labels.remove("__name__"); |
| 73 | result.push(InstantSample { |
| 74 | labels, |
| 75 | value: val, |
| 76 | timestamp_ms: ts, |
| 77 | }); |
| 78 | } |
| 79 | } else if op.is_set_op() && matches!(op, BinOp::Or) { |
| 80 | result.push(l.clone()); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | if matches!(op, BinOp::Or) { |
| 85 | let left_keys: std::collections::HashSet<String> = |
| 86 | left.iter().map(|s| match_key(&s.labels)).collect(); |
| 87 | for r in right { |
| 88 | if !left_keys.contains(&match_key(&r.labels)) { |
| 89 | result.push(r.clone()); |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | Ok(Value::Vector(result)) |
| 95 | } |
| 96 | |
| 97 | fn apply_binop(op: BinOp, a: f64, b: f64, return_bool: bool) -> f64 { |
| 98 | match op { |
no test coverage detected