mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-11-14 06:46:56 +00:00
feat(promql): add max_of, min_of and query context functions to native kernels
Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
This commit is contained in:
@@ -23,7 +23,10 @@ mod go_math;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use broadcast::{ScalarSeriesOperand, map_arithmetic_series, map_compare_series};
|
||||
pub use broadcast::{
|
||||
ScalarFunction, ScalarSeriesOperand, map_arithmetic_series, map_compare_series,
|
||||
map_scalar_function,
|
||||
};
|
||||
pub use comparison::{Comparison, ComparisonOp, map_compare, scalar_arithmetic, scalar_compare};
|
||||
|
||||
use std::f64::consts::PI;
|
||||
|
||||
@@ -74,6 +74,58 @@ pub fn map_compare_series(
|
||||
})
|
||||
}
|
||||
|
||||
/// `max_of(a, b)` and `min_of(a, b)`, which Prometheus evaluates with Go's `math.Max` and
|
||||
/// `math.Min`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum ScalarFunction {
|
||||
MaxOf,
|
||||
MinOf,
|
||||
}
|
||||
|
||||
impl ScalarFunction {
|
||||
/// Go's `math.Max` / `math.Min`: an infinity of the function's own sign wins over NaN, NaN
|
||||
/// over any other value, and `+0` is greater than `-0`.
|
||||
pub fn apply(self, a: f64, b: f64) -> f64 {
|
||||
let (wins, signed_zero_wins) = match self {
|
||||
Self::MaxOf => (f64::INFINITY, false),
|
||||
Self::MinOf => (f64::NEG_INFINITY, true),
|
||||
};
|
||||
if a == wins || b == wins {
|
||||
wins
|
||||
} else if a.is_nan() || b.is_nan() {
|
||||
f64::NAN
|
||||
} else if a == 0.0 && a == b {
|
||||
if a.is_sign_negative() == signed_zero_wins {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
}
|
||||
} else if (a > b) == (self == Self::MaxOf) {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies `function` to two time-varying scalars, aligned by absolute grid index; a point where
|
||||
/// either has no value has no result. Both operands must be unlabelled single-field series.
|
||||
pub fn map_scalar_function(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
function: ScalarFunction,
|
||||
left: &Series,
|
||||
right: &Series,
|
||||
) -> Result<Option<Series>> {
|
||||
validate_scalar(schema, left)?;
|
||||
map_grid_scalar(
|
||||
schema,
|
||||
left,
|
||||
ScalarSeriesOperand::Right(right),
|
||||
left.metric.clone(),
|
||||
|left, right, _| Some(function.apply(left, right)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Calls `calculate(left, right, vector_sample)` at each index where both operands exist.
|
||||
fn map_grid_scalar(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Generated by promql-compat cmd/narthex-golden-scalarfn built for amd64: `a b math.Max(a,b) math.Min(a,b)` as hex bits.
|
||||
0 0 0 0
|
||||
0 8000000000000000 0 8000000000000000
|
||||
0 3ff0000000000000 3ff0000000000000 0
|
||||
0 bff0000000000000 0 bff0000000000000
|
||||
0 4004000000000000 4004000000000000 0
|
||||
0 7ff0000000000000 7ff0000000000000 0
|
||||
0 fff0000000000000 0 fff0000000000000
|
||||
0 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
8000000000000000 0 0 8000000000000000
|
||||
8000000000000000 8000000000000000 8000000000000000 8000000000000000
|
||||
8000000000000000 3ff0000000000000 3ff0000000000000 8000000000000000
|
||||
8000000000000000 bff0000000000000 8000000000000000 bff0000000000000
|
||||
8000000000000000 4004000000000000 4004000000000000 8000000000000000
|
||||
8000000000000000 7ff0000000000000 7ff0000000000000 8000000000000000
|
||||
8000000000000000 fff0000000000000 8000000000000000 fff0000000000000
|
||||
8000000000000000 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
3ff0000000000000 0 3ff0000000000000 0
|
||||
3ff0000000000000 8000000000000000 3ff0000000000000 8000000000000000
|
||||
3ff0000000000000 3ff0000000000000 3ff0000000000000 3ff0000000000000
|
||||
3ff0000000000000 bff0000000000000 3ff0000000000000 bff0000000000000
|
||||
3ff0000000000000 4004000000000000 4004000000000000 3ff0000000000000
|
||||
3ff0000000000000 7ff0000000000000 7ff0000000000000 3ff0000000000000
|
||||
3ff0000000000000 fff0000000000000 3ff0000000000000 fff0000000000000
|
||||
3ff0000000000000 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
bff0000000000000 0 0 bff0000000000000
|
||||
bff0000000000000 8000000000000000 8000000000000000 bff0000000000000
|
||||
bff0000000000000 3ff0000000000000 3ff0000000000000 bff0000000000000
|
||||
bff0000000000000 bff0000000000000 bff0000000000000 bff0000000000000
|
||||
bff0000000000000 4004000000000000 4004000000000000 bff0000000000000
|
||||
bff0000000000000 7ff0000000000000 7ff0000000000000 bff0000000000000
|
||||
bff0000000000000 fff0000000000000 bff0000000000000 fff0000000000000
|
||||
bff0000000000000 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
4004000000000000 0 4004000000000000 0
|
||||
4004000000000000 8000000000000000 4004000000000000 8000000000000000
|
||||
4004000000000000 3ff0000000000000 4004000000000000 3ff0000000000000
|
||||
4004000000000000 bff0000000000000 4004000000000000 bff0000000000000
|
||||
4004000000000000 4004000000000000 4004000000000000 4004000000000000
|
||||
4004000000000000 7ff0000000000000 7ff0000000000000 4004000000000000
|
||||
4004000000000000 fff0000000000000 4004000000000000 fff0000000000000
|
||||
4004000000000000 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
7ff0000000000000 0 7ff0000000000000 0
|
||||
7ff0000000000000 8000000000000000 7ff0000000000000 8000000000000000
|
||||
7ff0000000000000 3ff0000000000000 7ff0000000000000 3ff0000000000000
|
||||
7ff0000000000000 bff0000000000000 7ff0000000000000 bff0000000000000
|
||||
7ff0000000000000 4004000000000000 7ff0000000000000 4004000000000000
|
||||
7ff0000000000000 7ff0000000000000 7ff0000000000000 7ff0000000000000
|
||||
7ff0000000000000 fff0000000000000 7ff0000000000000 fff0000000000000
|
||||
7ff0000000000000 7ff8000000000001 7ff0000000000000 7ff8000000000001
|
||||
fff0000000000000 0 0 fff0000000000000
|
||||
fff0000000000000 8000000000000000 8000000000000000 fff0000000000000
|
||||
fff0000000000000 3ff0000000000000 3ff0000000000000 fff0000000000000
|
||||
fff0000000000000 bff0000000000000 bff0000000000000 fff0000000000000
|
||||
fff0000000000000 4004000000000000 4004000000000000 fff0000000000000
|
||||
fff0000000000000 7ff0000000000000 7ff0000000000000 fff0000000000000
|
||||
fff0000000000000 fff0000000000000 fff0000000000000 fff0000000000000
|
||||
fff0000000000000 7ff8000000000001 7ff8000000000001 fff0000000000000
|
||||
7ff8000000000001 0 7ff8000000000001 7ff8000000000001
|
||||
7ff8000000000001 8000000000000000 7ff8000000000001 7ff8000000000001
|
||||
7ff8000000000001 3ff0000000000000 7ff8000000000001 7ff8000000000001
|
||||
7ff8000000000001 bff0000000000000 7ff8000000000001 7ff8000000000001
|
||||
7ff8000000000001 4004000000000000 7ff8000000000001 7ff8000000000001
|
||||
7ff8000000000001 7ff0000000000000 7ff0000000000000 7ff8000000000001
|
||||
7ff8000000000001 fff0000000000000 7ff8000000000001 fff0000000000000
|
||||
7ff8000000000001 7ff8000000000001 7ff8000000000001 7ff8000000000001
|
||||
@@ -551,3 +551,59 @@ fn math_drops_reserved_metadata_and_empty_labels_with_the_name() {
|
||||
assert_eq!(output.metric.name(), None);
|
||||
assert_eq!(names, ["__other__", "host"]);
|
||||
}
|
||||
|
||||
/// `max_of` / `min_of` against Go's `math.Max` / `math.Min`, whose signed-zero, NaN and infinity
|
||||
/// rules differ from `f64::max` / `f64::min`.
|
||||
#[test]
|
||||
fn max_of_and_min_of_follow_go() {
|
||||
let bits = |text: &str| f64::from_bits(u64::from_str_radix(text, 16).unwrap());
|
||||
let same = |a: f64, b: f64| a.to_bits() == b.to_bits() || (a.is_nan() && b.is_nan());
|
||||
let mut checked = 0;
|
||||
for line in include_str!("max_min_cases.txt")
|
||||
.lines()
|
||||
.filter(|line| !line.starts_with('#'))
|
||||
{
|
||||
let values: Vec<f64> = line.split_whitespace().map(bits).collect();
|
||||
let (a, b) = (values[0], values[1]);
|
||||
assert!(
|
||||
same(ScalarFunction::MaxOf.apply(a, b), values[2]),
|
||||
"max_of({a}, {b})"
|
||||
);
|
||||
assert!(
|
||||
same(ScalarFunction::MinOf.apply(a, b), values[3]),
|
||||
"min_of({a}, {b})"
|
||||
);
|
||||
checked += 1;
|
||||
}
|
||||
assert_eq!(checked, 64);
|
||||
}
|
||||
|
||||
/// Time-varying scalars pair by absolute position; a point either one lacks has no result.
|
||||
#[test]
|
||||
fn scalar_functions_pair_scalars_by_position() {
|
||||
let schema = Arc::new(schema(&["scalar"]));
|
||||
let scalar = |start: usize, values: &[Option<f64>]| {
|
||||
Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(None, Vec::new()).unwrap(),
|
||||
TimeAxis::Grid(
|
||||
GridRange::try_new(schema.eval_grid.clone().unwrap(), start, values.len()).unwrap(),
|
||||
),
|
||||
SeriesFields::try_from_vec(vec![floats(values)]).unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
let left = scalar(2, &[Some(1.0), Some(5.0), None, Some(-0.0)]);
|
||||
let right = scalar(3, &[Some(2.0), Some(7.0), Some(0.0), Some(9.0)]);
|
||||
let result = map_scalar_function(&schema, ScalarFunction::MaxOf, &left, &right)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
run_floats(&result, 0),
|
||||
vec![((3, 1), vec![Some(5.0)]), ((5, 1), vec![Some(0.0)])]
|
||||
);
|
||||
assert!(
|
||||
run_floats(&result, 0)[1].1[0].unwrap().is_sign_positive(),
|
||||
"max_of(-0, +0) is +0"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,37 @@ pub enum DateFunction {
|
||||
Year,
|
||||
}
|
||||
|
||||
/// `start()`, `end()`, `range()` and `step()`: constants of a query, which Prometheus folds into
|
||||
/// number literals before evaluating it.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum QueryContextFunction {
|
||||
Start,
|
||||
End,
|
||||
Range,
|
||||
Step,
|
||||
}
|
||||
|
||||
impl QueryContextFunction {
|
||||
/// The value for a query from `start_ms` to `end_ms` every `step_ms`. `step()` is 0 when the
|
||||
/// start and end are equal, as for an instant query.
|
||||
pub fn value(self, start_ms: i64, end_ms: i64, step_ms: i64) -> f64 {
|
||||
match self {
|
||||
Self::Start => start_ms as f64 / 1000.0,
|
||||
Self::End => end_ms as f64 / 1000.0,
|
||||
Self::Range => duration_seconds(end_ms - start_ms),
|
||||
Self::Step if start_ms == end_ms => 0.0,
|
||||
Self::Step => duration_seconds(step_ms),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Go's `time.Duration.Seconds` of `ms` milliseconds: whole seconds plus the remainder over 1e9,
|
||||
/// two roundings rather than one division. The nanosecond count saturates as `time.Time.Sub` does.
|
||||
fn duration_seconds(ms: i64) -> f64 {
|
||||
let nanos = ms.saturating_mul(1_000_000);
|
||||
(nanos / 1_000_000_000) as f64 + (nanos % 1_000_000_000) as f64 / 1e9
|
||||
}
|
||||
|
||||
/// `time()`: the evaluation time in seconds at every point of the schema's grid, unlabelled.
|
||||
pub fn time(schema: &SeriesSchema) -> Result<Series> {
|
||||
eval_time_series(schema, |ms| ms as f64 / 1000.0)
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
# Generated by promql-compat cmd/narthex-golden-scalarfn built for amd64: `ms time.Duration.Seconds()` for a millisecond difference, as hex bits.
|
||||
0 0
|
||||
1 3f50624dd2f1a9fc
|
||||
999 3feff7ced916872b
|
||||
1000 3ff0000000000000
|
||||
1001 3ff004189374bc6a
|
||||
4097 40106353f7ced917
|
||||
86400000 40f5180000000000
|
||||
9007199254740993 42012e0be826d695
|
||||
9223372036854 42012e0be826d4fe
|
||||
9223372036855 42012e0be826d695
|
||||
2340891196754 41e170e5479820c5
|
||||
28653324801615 42012e0be826d695
|
||||
15150070723101 42012e0be826d695
|
||||
5203274071043 41f3623a9570b021
|
||||
6052846691025 41f68c71c6306666
|
||||
19267443321048 42012e0be826d695
|
||||
12341472526366 42012e0be826d695
|
||||
20530526999188 42012e0be826d695
|
||||
34395057096608 42012e0be826d695
|
||||
8401369033625 41ff4c2b7c9a0000
|
||||
31640814836996 42012e0be826d695
|
||||
29341436692007 42012e0be826d695
|
||||
34783771064630 42012e0be826d695
|
||||
35122158268884 42012e0be826d695
|
||||
1479560899851 41d60c13b0f676c9
|
||||
23204167308761 42012e0be826d695
|
||||
24788341754728 42012e0be826d695
|
||||
31429837266203 42012e0be826d695
|
||||
34244401504646 42012e0be826d695
|
||||
13068139990387 42012e0be826d695
|
||||
7761385230625 41fce9d570ea0000
|
||||
9735534642756 42012e0be826d695
|
||||
20240948685375 42012e0be826d695
|
||||
33614386955765 42012e0be826d695
|
||||
4944260193162 41f26b36c612978d
|
||||
14479808172613 42012e0be826d695
|
||||
17797368697448 42012e0be826d695
|
||||
14261095223522 42012e0be826d695
|
||||
13428055133044 42012e0be826d695
|
||||
26352584022491 42012e0be826d695
|
||||
12325408233432 42012e0be826d695
|
||||
17010777739835 42012e0be826d695
|
||||
28430422903295 42012e0be826d695
|
||||
29753883088875 42012e0be826d695
|
||||
25998949474507 42012e0be826d695
|
||||
10226187168843 42012e0be826d695
|
||||
17769199632283 42012e0be826d695
|
||||
4363496320571 41f0415ab80922d1
|
||||
3287173645812 41e87dc941b9fbe7
|
||||
12725827928836 42012e0be826d695
|
||||
24795910633675 42012e0be826d695
|
||||
2828521278844 41e512f9e7db020c
|
||||
4170359431716 41ef125450f6e979
|
||||
3589276087583 41eabe0036f2a7f0
|
||||
28524985356220 42012e0be826d695
|
||||
30320656727859 42012e0be826d695
|
||||
4256148642671 41efb5f5945578d5
|
||||
29566978976822 42012e0be826d695
|
||||
1648135601414 41d88f236c5a7efa
|
||||
4780677690357 41f1cf35a3a5b646
|
||||
3390646811377 41e94325436c1062
|
||||
6912080800569 41f9bfdfba091aa0
|
||||
19744540834685 42012e0be826d695
|
||||
5048451373608 41f2ce9412d9ba5e
|
||||
31511077099905 42012e0be826d695
|
||||
33060246075211 42012e0be826d695
|
||||
29446920826861 42012e0be826d695
|
||||
20868689814545 42012e0be826d695
|
||||
25732868269994 42012e0be826d695
|
||||
26023816056118 42012e0be826d695
|
||||
3312873794438 41e8aece284e0419
|
||||
8928671130029 4200a185acd03b64
|
||||
27201078145192 42012e0be826d695
|
||||
28161007422010 42012e0be826d695
|
||||
23548861302960 42012e0be826d695
|
||||
8403898590605 41ff4e950de9ae14
|
||||
2101319756957 41df4fe6133d3f7d
|
||||
18153789976583 42012e0be826d695
|
||||
16078846218429 42012e0be826d695
|
||||
14439764018086 42012e0be826d695
|
||||
15717223852073 42012e0be826d695
|
||||
7594418227955 41fc4a9a033f47ae
|
||||
1007547111184 41ce06f973978d50
|
||||
7653748532646 41fc832ef34a5604
|
||||
1542530612607 41d6fc498d26d917
|
||||
8959567520889 4200b04135071cac
|
||||
1963454100123 41dd41fba507df3b
|
||||
15423611227189 42012e0be826d695
|
||||
26921592371531 42012e0be826d695
|
||||
31560677483706 42012e0be826d695
|
||||
21024346859206 42012e0be826d695
|
||||
21411506917513 42012e0be826d695
|
||||
14299718455620 42012e0be826d695
|
||||
25966354044973 42012e0be826d695
|
||||
21480240207871 42012e0be826d695
|
||||
13383017194856 42012e0be826d695
|
||||
19694757267735 42012e0be826d695
|
||||
8329763775671 41ff07e1bbfabc6a
|
||||
24204352256265 42012e0be826d695
|
||||
5166480575653 41f33f23cbfa72b0
|
||||
17311660727623 42012e0be826d695
|
||||
26768379971433 42012e0be826d695
|
||||
21452255664239 42012e0be826d695
|
||||
32930407231978 42012e0be826d695
|
||||
15551692227912 42012e0be826d695
|
||||
23123035545994 42012e0be826d695
|
||||
5875644708440 41f5e37392470a3d
|
||||
18292969058316 42012e0be826d695
|
||||
1707825217332 41d972d610553f7d
|
||||
23633727413655 42012e0be826d695
|
||||
24472694155897 42012e0be826d695
|
||||
32056439689975 42012e0be826d695
|
||||
25133237617897 42012e0be826d695
|
||||
10984619967605 42012e0be826d695
|
||||
12399994332458 42012e0be826d695
|
||||
17017307690557 42012e0be826d695
|
||||
24405803592380 42012e0be826d695
|
||||
34039839184523 42012e0be826d695
|
||||
12086900862154 42012e0be826d695
|
||||
4880216990563 41f22e2339e9020c
|
||||
8291016285084 41fee2ede5d15810
|
||||
34263874447617 42012e0be826d695
|
||||
5219901505275 41f3721604146666
|
||||
3325751404254 41e8c75e0d8820c5
|
||||
10069265674283 42012e0be826d695
|
||||
2205986208125 41e06f95b4040000
|
||||
17331608106692 42012e0be826d695
|
||||
13164910887275 42012e0be826d695
|
||||
20165189440141 42012e0be826d695
|
||||
18100958213119 42012e0be826d695
|
||||
33252881487365 42012e0be826d695
|
||||
28493023658516 42012e0be826d695
|
||||
8853845580432 42007dd7b26374bc
|
||||
34838873892001 42012e0be826d695
|
||||
20214329624262 42012e0be826d695
|
||||
31705600540751 42012e0be826d695
|
||||
31189001046116 42012e0be826d695
|
||||
29476027927210 42012e0be826d695
|
||||
26781011366842 42012e0be826d695
|
||||
22699855557780 42012e0be826d695
|
||||
17749079048291 42012e0be826d695
|
||||
30750407110207 42012e0be826d695
|
||||
24417907650311 42012e0be826d695
|
||||
10509573177644 42012e0be826d695
|
||||
1079378703273 41d01580c3d178d5
|
||||
34862833947828 42012e0be826d695
|
||||
24980588397686 42012e0be826d695
|
||||
11209991956240 42012e0be826d695
|
||||
8937655194575 4200a5ce5cd4999a
|
||||
23978885618615 42012e0be826d695
|
||||
30065528340854 42012e0be826d695
|
||||
2628030736846 41e39492221b126f
|
||||
2663938618407 41e3d90f474d0625
|
||||
34895264552379 42012e0be826d695
|
||||
15670995231869 42012e0be826d695
|
||||
4191047303785 41ef39c9d0f91eb8
|
||||
8437263482680 41ff6e66c7aae148
|
||||
3960463773594 41ed81fc33b3020c
|
||||
4309293785322 41f00da9ad9526e9
|
||||
26649392599963 42012e0be826d695
|
||||
4157860955829 41eefa7d8b7a872b
|
||||
22296599249089 42012e0be826d695
|
||||
32695131508279 42012e0be826d695
|
||||
30635397919632 42012e0be826d695
|
||||
15331538117365 42012e0be826d695
|
||||
11063348740606 42012e0be826d695
|
||||
32371941731295 42012e0be826d695
|
||||
13719859399284 42012e0be826d695
|
||||
7293417131828 41fb2b8b6abd3f7d
|
||||
33407534042909 42012e0be826d695
|
||||
31297857606586 42012e0be826d695
|
||||
1097102363540 41d0591d06e28f5c
|
||||
25332039849587 42012e0be826d695
|
||||
20041642732253 42012e0be826d695
|
||||
18752081044817 42012e0be826d695
|
||||
29442119239956 42012e0be826d695
|
||||
28855454932055 42012e0be826d695
|
||||
31958604071351 42012e0be826d695
|
||||
18688407702704 42012e0be826d695
|
||||
17871169582207 42012e0be826d695
|
||||
16003600945447 42012e0be826d695
|
||||
5284509633417 41f3afb37c16ac08
|
||||
11575618223404 42012e0be826d695
|
||||
23263846003261 42012e0be826d695
|
||||
14260376149051 42012e0be826d695
|
||||
20109100243330 42012e0be826d695
|
||||
16359587412236 42012e0be826d695
|
||||
34836697130263 42012e0be826d695
|
||||
23618221322728 42012e0be826d695
|
||||
16214535784284 42012e0be826d695
|
||||
8272436198602 41fed135be69a1cb
|
||||
5401941921460 41f41fb17a175c29
|
||||
7235498080071 41faf44f060122d1
|
||||
14773466706669 42012e0be826d695
|
||||
34843449378732 42012e0be826d695
|
||||
23707829047074 42012e0be826d695
|
||||
4081628494438 41ee6916a9ce0419
|
||||
13573087199008 42012e0be826d695
|
||||
21542290482225 42012e0be826d695
|
||||
16883004474069 42012e0be826d695
|
||||
16172951872856 42012e0be826d695
|
||||
5849767460850 41f5cac5e24d999a
|
||||
12771076879764 42012e0be826d695
|
||||
7080148168638 41fa6027cc8a353f
|
||||
13469889734230 42012e0be826d695
|
||||
9296342191848 42012e0be826d695
|
||||
753418709293 41c67420eaa58106
|
||||
23411833150514 42012e0be826d695
|
||||
29448477422232 42012e0be826d695
|
||||
29413433948272 42012e0be826d695
|
||||
@@ -24,7 +24,7 @@ use datatypes::series::samples::{
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpan, GridSpec, TimeAxis};
|
||||
|
||||
use super::{DateFunction, date_of_eval_time, map_date, time};
|
||||
use super::{DateFunction, QueryContextFunction, date_of_eval_time, map_date, time};
|
||||
use crate::grid_series::merge_same_labelset;
|
||||
use crate::grid_series::reference::{
|
||||
Labels, Points, canonical_bits, golden_cases, labels_of, metric_of, points_by_labels,
|
||||
@@ -289,3 +289,33 @@ fn map_date_reads_a_sparse_axis_by_its_positions() {
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/// `range()` and `step()` are Go `Duration.Seconds` of a millisecond count, which rounds twice
|
||||
/// and so differs from `ms / 1000` in the last bit for most values.
|
||||
#[test]
|
||||
fn query_context_durations_match_go() {
|
||||
let mut checked = 0;
|
||||
for line in include_str!("duration_seconds_cases.txt")
|
||||
.lines()
|
||||
.filter(|line| !line.starts_with('#'))
|
||||
{
|
||||
let (ms, bits) = line.split_once(' ').unwrap();
|
||||
let ms: i64 = ms.parse().unwrap();
|
||||
let expected = u64::from_str_radix(bits, 16).unwrap();
|
||||
assert_eq!(
|
||||
QueryContextFunction::Range.value(0, ms, 1).to_bits(),
|
||||
expected,
|
||||
"range() over {ms} ms"
|
||||
);
|
||||
assert_eq!(
|
||||
QueryContextFunction::Step.value(0, 1, ms).to_bits(),
|
||||
expected,
|
||||
"step() of {ms} ms"
|
||||
);
|
||||
checked += 1;
|
||||
}
|
||||
assert!(checked > 200, "{checked} durations checked");
|
||||
assert_eq!(QueryContextFunction::Step.value(5_000, 5_000, 1_000), 0.0);
|
||||
assert_eq!(QueryContextFunction::Start.value(-1_500, 0, 1), -1.5);
|
||||
assert_eq!(QueryContextFunction::End.value(0, 2_250, 1), 2.25);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user