From 423c1fee28ded83b9097294e4a1de16b72537981 Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Sat, 17 Oct 2026 22:58:03 +0800 Subject: [PATCH] refactor(promql): use standard math for native histogram bounds and interpolation Results only need to agree with Prometheus within the relative tolerance promql-compat uses, so Go's bound table and the ports of math.Log2, Exp2, Ldexp and Frexp go; the fixtures are compared within that tolerance. Signed-off-by: Dennis Zhuang --- src/promql/src/histogram_eval.rs | 1 - src/promql/src/histogram_eval/bounds.rs | 167 -------- .../src/histogram_eval/go_math_cases.txt | 404 ------------------ src/promql/src/histogram_eval/native.rs | 191 +-------- src/promql/src/histogram_eval/tests.rs | 43 +- 5 files changed, 65 insertions(+), 741 deletions(-) delete mode 100644 src/promql/src/histogram_eval/bounds.rs delete mode 100644 src/promql/src/histogram_eval/go_math_cases.txt diff --git a/src/promql/src/histogram_eval.rs b/src/promql/src/histogram_eval.rs index c429d052b03..5aa9843774e 100644 --- a/src/promql/src/histogram_eval.rs +++ b/src/promql/src/histogram_eval.rs @@ -17,7 +17,6 @@ //! and `resetHistograms`), and `histogram_count`, `histogram_sum`, `histogram_avg`, //! `histogram_stddev` and `histogram_stdvar` over native histograms. -mod bounds; mod classic; mod native; #[cfg(test)] diff --git a/src/promql/src/histogram_eval/bounds.rs b/src/promql/src/histogram_eval/bounds.rs deleted file mode 100644 index ddc3a69290d..00000000000 --- a/src/promql/src/histogram_eval/bounds.rs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Prometheus `exponentialBounds` (`model/histogram/generic.go`): the bucket bounds in [0.5, 1) -//! of exponential schemas 0 to 8, which `getBoundExponential` scales by a power of two. - -#[rustfmt::skip] -pub(super) const EXPONENTIAL_BOUNDS: [&[f64]; 9] = [ - &[ - 0.5, - ], - &[ - 0.5, 0.7071067811865475, - ], - &[ - 0.5, 0.5946035575013605, 0.7071067811865475, 0.8408964152537144, - ], - &[ - 0.5, 0.5452538663326288, 0.5946035575013605, 0.6484197773255048, - 0.7071067811865475, 0.7711054127039704, 0.8408964152537144, 0.9170040432046711, - ], - &[ - 0.5, 0.5221368912137069, 0.5452538663326288, 0.5693943173783458, - 0.5946035575013605, 0.620928906036742, 0.6484197773255048, 0.6771277734684463, - 0.7071067811865475, 0.7384130729697496, 0.7711054127039704, 0.805245165974627, - 0.8408964152537144, 0.8781260801866495, 0.9170040432046711, 0.9576032806985735, - ], - &[ - 0.5, 0.5109485743270583, 0.5221368912137069, 0.5335702003384117, - 0.5452538663326288, 0.5571933712979462, 0.5693943173783458, 0.5818624293887887, - 0.5946035575013605, 0.6076236799902344, 0.620928906036742, 0.6345254785958666, - 0.6484197773255048, 0.6626183215798706, 0.6771277734684463, 0.6919549409819159, - 0.7071067811865475, 0.7225904034885232, 0.7384130729697496, 0.7545822137967112, - 0.7711054127039704, 0.7879904225539431, 0.805245165974627, 0.8228777390769823, - 0.8408964152537144, 0.8593096490612387, 0.8781260801866495, 0.8973545375015533, - 0.9170040432046711, 0.9370838170551498, 0.9576032806985735, 0.9785720620876999, - ], - &[ - 0.5, 0.5054446430258502, 0.5109485743270583, 0.5165124395106142, - 0.5221368912137069, 0.5278225891802786, 0.5335702003384117, 0.5393803988785598, - 0.5452538663326288, 0.5511912916539204, 0.5571933712979462, 0.5632608093041209, - 0.5693943173783458, 0.5755946149764913, 0.5818624293887887, 0.5881984958251406, - 0.5946035575013605, 0.6010783657263515, 0.6076236799902344, 0.6142402680534349, - 0.620928906036742, 0.6276903785123455, 0.6345254785958666, 0.6414350080393891, - 0.6484197773255048, 0.6554806057623822, 0.6626183215798706, 0.6698337620266515, - 0.6771277734684463, 0.6845012114872953, 0.6919549409819159, 0.6994898362691555, - 0.7071067811865475, 0.7148066691959849, 0.7225904034885232, 0.7304588970903234, - 0.7384130729697496, 0.7464538641456323, 0.7545822137967112, 0.762799075372269, - 0.7711054127039704, 0.7795022001189185, 0.7879904225539431, 0.7965710756711334, - 0.805245165974627, 0.8140137109286738, 0.8228777390769823, 0.8318382901633681, - 0.8408964152537144, 0.8500531768592616, 0.8593096490612387, 0.8686669176368529, - 0.8781260801866495, 0.8876882462632604, 0.8973545375015533, 0.9071260877501991, - 0.9170040432046711, 0.9269895625416926, 0.9370838170551498, 0.9472879907934827, - 0.9576032806985735, 0.9680308967461471, 0.9785720620876999, 0.9892280131939752, - ], - &[ - 0.5, 0.5027149505564014, 0.5054446430258502, 0.5081891574554764, - 0.5109485743270583, 0.5137229745593818, 0.5165124395106142, 0.5193170509806894, - 0.5221368912137069, 0.5249720429003435, 0.5278225891802786, 0.5306886136446309, - 0.5335702003384117, 0.5364674337629877, 0.5393803988785598, 0.5423091811066545, - 0.5452538663326288, 0.5482145409081883, 0.5511912916539204, 0.5541842058618393, - 0.5571933712979462, 0.5602188762048033, 0.5632608093041209, 0.5663192597993595, - 0.5693943173783458, 0.572486072215902, 0.5755946149764913, 0.5787200368168754, - 0.5818624293887887, 0.585021884841625, 0.5881984958251406, 0.5913923554921704, - 0.5946035575013605, 0.5978321960199137, 0.6010783657263515, 0.6043421618132907, - 0.6076236799902344, 0.6109230164863786, 0.6142402680534349, 0.6175755319684665, - 0.620928906036742, 0.6243004885946023, 0.6276903785123455, 0.6310986751971253, - 0.6345254785958666, 0.637970889198196, 0.6414350080393891, 0.6449179367033329, - 0.6484197773255048, 0.6519406325959679, 0.6554806057623822, 0.659039800633032, - 0.6626183215798706, 0.6662162735415805, 0.6698337620266515, 0.6734708931164728, - 0.6771277734684463, 0.6808045103191123, 0.6845012114872953, 0.688217985377265, - 0.6919549409819159, 0.6957121878859629, 0.6994898362691555, 0.7032879969095076, - 0.7071067811865475, 0.7109463010845827, 0.7148066691959849, 0.718687998724491, - 0.7225904034885232, 0.7265139979245261, 0.7304588970903234, 0.7344252166684908, - 0.7384130729697496, 0.7424225829363761, 0.7464538641456323, 0.7505070348132126, - 0.7545822137967112, 0.7586795205991071, 0.762799075372269, 0.7669409989204777, - 0.7711054127039704, 0.7752924388424999, 0.7795022001189185, 0.7837348199827764, - 0.7879904225539431, 0.7922691326262467, 0.7965710756711334, 0.8008963778413465, - 0.805245165974627, 0.8096175675974316, 0.8140137109286738, 0.8184337248834821, - 0.8228777390769823, 0.8273458838280969, 0.8318382901633681, 0.8363550898207981, - 0.8408964152537144, 0.8454623996346523, 0.8500531768592616, 0.8546688815502312, - 0.8593096490612387, 0.8639756154809185, 0.8686669176368529, 0.8733836930995842, - 0.8781260801866495, 0.8828942179666361, 0.8876882462632604, 0.8925083056594671, - 0.8973545375015533, 0.9022270839033115, 0.9071260877501991, 0.9120516927035263, - 0.9170040432046711, 0.9219832844793128, 0.9269895625416926, 0.9320230241988943, - 0.9370838170551498, 0.9421720895161669, 0.9472879907934827, 0.9524316709088368, - 0.9576032806985735, 0.9628029718180622, 0.9680308967461471, 0.9732872087896164, - 0.9785720620876999, 0.9838856116165875, 0.9892280131939752, 0.9945994234836328, - ], - &[ - 0.5, 0.5013556375251013, 0.5027149505564014, 0.5040779490592088, - 0.5054446430258502, 0.5068150424757447, 0.5081891574554764, 0.509566998038869, - 0.5109485743270583, 0.5123338964485679, 0.5137229745593818, 0.5151158188430205, - 0.5165124395106142, 0.5179128468009786, 0.5193170509806894, 0.520725062344158, - 0.5221368912137069, 0.5235525479396449, 0.5249720429003435, 0.526395386502313, - 0.5278225891802786, 0.5292536613972564, 0.5306886136446309, 0.5321274564422321, - 0.5335702003384117, 0.5350168559101208, 0.5364674337629877, 0.5379219445313954, - 0.5393803988785598, 0.5408428074966075, 0.5423091811066545, 0.5437795304588847, - 0.5452538663326288, 0.5467321995364429, 0.5482145409081883, 0.549700901315111, - 0.5511912916539204, 0.5526857228508706, 0.5541842058618393, 0.5556867516724088, - 0.5571933712979462, 0.5587040757836845, 0.5602188762048033, 0.5617377836665098, - 0.5632608093041209, 0.564787964283144, 0.5663192597993595, 0.5678547070789026, - 0.5693943173783458, 0.5709381019847808, 0.572486072215902, 0.5740382394200894, - 0.5755946149764913, 0.5771552102951081, 0.5787200368168754, 0.5802891060137493, - 0.5818624293887887, 0.5834400184762408, 0.585021884841625, 0.5866080400818185, - 0.5881984958251406, 0.5897932637314379, 0.5913923554921704, 0.5929957828304968, - 0.5946035575013605, 0.5962156912915756, 0.5978321960199137, 0.5994530835371903, - 0.6010783657263515, 0.6027080545025619, 0.6043421618132907, 0.6059806996384005, - 0.6076236799902344, 0.6092711149137041, 0.6109230164863786, 0.6125793968185725, - 0.6142402680534349, 0.6159056423670379, 0.6175755319684665, 0.6192499490999082, - 0.620928906036742, 0.622612415087629, 0.6243004885946023, 0.6259931389331581, - 0.6276903785123455, 0.6293922197748583, 0.6310986751971253, 0.6328097572894031, - 0.6345254785958666, 0.6362458516947014, 0.637970889198196, 0.6397006037528346, - 0.6414350080393891, 0.6431741147730128, 0.6449179367033329, 0.6466664866145447, - 0.6484197773255048, 0.6501778216898253, 0.6519406325959679, 0.6537082229673385, - 0.6554806057623822, 0.6572577939746774, 0.659039800633032, 0.6608266388015788, - 0.6626183215798706, 0.6644148621029772, 0.6662162735415805, 0.6680225691020727, - 0.6698337620266515, 0.6716498655934177, 0.6734708931164728, 0.6752968579460171, - 0.6771277734684463, 0.6789636531064505, 0.6808045103191123, 0.6826503586020058, - 0.6845012114872953, 0.6863570825438342, 0.688217985377265, 0.690083933630119, - 0.6919549409819159, 0.6938310211492645, 0.6957121878859629, 0.6975984549830999, - 0.6994898362691555, 0.7013863456101023, 0.7032879969095076, 0.7051948041086352, - 0.7071067811865475, 0.7090239421602076, 0.7109463010845827, 0.7128738720527471, - 0.7148066691959849, 0.7167447066838943, 0.718687998724491, 0.7206365595643126, - 0.7225904034885232, 0.7245495448210174, 0.7265139979245261, 0.7284837772007218, - 0.7304588970903234, 0.7324393720732029, 0.7344252166684908, 0.7364164454346837, - 0.7384130729697496, 0.7404151139112358, 0.7424225829363761, 0.7444354947621984, - 0.7464538641456323, 0.7484777058836176, 0.7505070348132126, 0.7525418658117031, - 0.7545822137967112, 0.7566280937263048, 0.7586795205991071, 0.7607365094544071, - 0.762799075372269, 0.7648672334736434, 0.7669409989204777, 0.7690203869158282, - 0.7711054127039704, 0.7731960915705107, 0.7752924388424999, 0.7773944698885442, - 0.7795022001189185, 0.7816156449856788, 0.7837348199827764, 0.7858597406461707, - 0.7879904225539431, 0.7901268813264122, 0.7922691326262467, 0.7944171921585818, - 0.7965710756711334, 0.7987307989543135, 0.8008963778413465, 0.8030678282083853, - 0.805245165974627, 0.8074284071024302, 0.8096175675974316, 0.8118126635086642, - 0.8140137109286738, 0.8162207259936375, 0.8184337248834821, 0.820652723822003, - 0.8228777390769823, 0.8251087869603088, 0.8273458838280969, 0.8295890460808079, - 0.8318382901633681, 0.8340936325652911, 0.8363550898207981, 0.8386226785089391, - 0.8408964152537144, 0.8431763167241966, 0.8454623996346523, 0.8477546807446661, - 0.8500531768592616, 0.8523579048290255, 0.8546688815502312, 0.8569861239649629, - 0.8593096490612387, 0.8616394738731368, 0.8639756154809185, 0.8663180910111553, - 0.8686669176368529, 0.871022112577578, 0.8733836930995842, 0.8757516765159389, - 0.8781260801866495, 0.8805069215187917, 0.8828942179666361, 0.8852879870317771, - 0.8876882462632604, 0.890095013257712, 0.8925083056594671, 0.8949281411607002, - 0.8973545375015533, 0.8997875124702672, 0.9022270839033115, 0.9046732696855155, - 0.9071260877501991, 0.909585556079304, 0.9120516927035263, 0.9145245157024483, - 0.9170040432046711, 0.9194902933879467, 0.9219832844793128, 0.9244830347552253, - 0.9269895625416926, 0.92950288621441, 0.9320230241988943, 0.9345499949706191, - 0.9370838170551498, 0.93962450902828, 0.9421720895161669, 0.9447265771954693, - 0.9472879907934827, 0.9498563490882775, 0.9524316709088368, 0.9550139751351947, - 0.9576032806985735, 0.9601996065815236, 0.9628029718180622, 0.9654133954938133, - 0.9680308967461471, 0.9706554947643201, 0.9732872087896164, 0.9759260581154889, - 0.9785720620876999, 0.9812252401044634, 0.9838856116165875, 0.9865531961276168, - 0.9892280131939752, 0.9919100824251095, 0.9945994234836328, 0.9972960560854698, - ], -]; diff --git a/src/promql/src/histogram_eval/go_math_cases.txt b/src/promql/src/histogram_eval/go_math_cases.txt deleted file mode 100644 index f225d51aa8d..00000000000 --- a/src/promql/src/histogram_eval/go_math_cases.txt +++ /dev/null @@ -1,404 +0,0 @@ -# Generated by promql-compat cmd/narthex-golden-log2exp2 built for amd64: Go math.Log2 and -# math.Exp2, which Prometheus uses for native histogram bucket interpolation, as -# ` `. Most arguments are ones where the platform -# log2/exp2 differ from Go. -log2 4062d9b2bb9a2a77 401cf232d0a9d4ee -log2 4097055ed082a8e2 40250cbcb4fc0e2a -log2 3b351cb06f8b1b4f c052e666776b22b2 -log2 3ff54e48fa949ad9 3fda7172fff5e488 -log2 3fe71cf463d46014 bfde0a02354d87a0 -log2 3fd971a63b78ce33 bff54ac027a3c7a2 -log2 3fe1ae8e6496ef48 bfeb62ba8b44eced -log2 3fc090819294da9b c007998eb771b372 -log2 3f6a05b848c34bb5 c02098bd88aa33f6 -log2 3ba9bd3d28a2033d c051141a4729fa90 -log2 3fe56caea1b0b215 bfe28597b8ffd8a8 -log2 3ff24b06c4df98cc 3fc8bb9cb6128c9c -log2 3fb233b520432393 c00e8306032af27c -log2 3fe8cede481dfc2f bfd78137e92c127e -log2 4083a90c5dc716a5 4022982cca875fce -log2 3ffb0131917a1d94 3fe82a1444df431c -log2 3fd4af472a91b780 bffa12785553d168 -log2 3fe86def706fda98 bfd8ecc5a538e6c5 -log2 40f6ac7746ebc3ce 403080c12cc29aa2 -log2 45b536a01d2d0b48 40571a0ab166e0c2 -log2 42b7eeedff46587c 40464a5c85e1b894 -log2 3febcf267156203a bfc9ebdebb21e9bf -log2 4274665712e5c9b3 40442cdc8d463be0 -log2 4015f5a747a75da6 4003a77ba502db44 -log2 407659264d3f08e4 4020f6d46a952748 -log2 3c0167d2175cdacc c04f70737e0674e2 -log2 3fe0fdbd021da93c bfed39a5e1b55cd1 -log2 3e400b26e5e86ce8 c03afefeed977c44 -log2 3ff9cce94525b194 3fe60ef00e89ab0c -log2 40373d613b790854 40122772b8f10cb6 -log2 3f120f358ef981aa c02ba6907b9114ca -log2 44775a044cb8beca 405222e8ac4c0460 -log2 3fa0ae8423d69078 c013c25c4f430928 -log2 3fd63f7823860a45 bff863f24bfd1944 -log2 4188ec8e4728ed61 4039a3b411907836 -log2 3ff02cc003871c42 3f900d79bfc7e280 -log2 3fe780592ae4667d bfdc803f6d9ca8da -log2 3ff1b9dd6366ecb2 3fc2eb0abbc32e04 -log2 3ff4d6456e6badc4 3fd8638a57b71ee2 -log2 3ff47ecb35f979ca 3fd6dcb2d983c182 -log2 40a650f5fd5fe402 4026f5c591199cae -log2 40731fab11fc2b52 402083bb8688e904 -log2 3ff4335ea5482ac7 3fd586715785e6f6 -log2 3ff02b3615189049 3f8f01cef9f1a4c0 -log2 4005d018a58414de 3ff7275ad2b29138 -log2 3a3515999797e3ce c056e6857dbfa126 -log2 3fe4667af0840d40 bfe4c88b8402e752 -log2 3ff23cfb94fb9d3d 3fc82da17a368fbc -log2 3ff36b191d34b376 3fd1e0da096a6f08 -log2 41d6fe74310b8d2b 403e85ef535eb744 -log2 44f4c9e22f653b24 4054182c95a3596a -log2 4243bea97ddd4f60 4042a6d5c6b1e22c -log2 41e6255fbe2f20c7 403f780ea9899f5e -log2 4062ffea0c53c242 401cfdda0aee0a4e -log2 3eb72adc7fef9bea c033774a13b79e7c -log2 3fe1553473a4bba4 bfec4e5a4d479436 -log2 3e8e019579337076 c03617c2855238ec -log2 3feb86c7d282ca06 bfcbcee5104571eb -log2 3fd29ed10842466e bffc7fc0aecf7b94 -log2 3e011d709a4b9dcc c03ee71e997645f8 -log2 4031b6a21c6602cf 4010964aea84604c -log2 40069a528673e30c 3ff7f992c4aaff76 -log2 405c3e8a886ac4ec 401b4790b23256f6 -log2 3f97e8dabb2b1f9c c015ae9301aef50a -log2 3e31c7ea106088e0 c03bd905a3f06c9c -log2 3f7a2e54f9545428 c01d288078994e20 -log2 4281f79abe8b23f4 40449569e48c1d70 -log2 4072435aec892dbd 402061b86f4e1c22 -log2 3a4a69ca0a0c9792 c05691b7441b1c0a -log2 3d0266eb4c6db02c c047662ba6dd3f9a -log2 3ff21cb6e4aeb341 3fc6e5c641353068 -log2 3ff2b447490017e6 3fccd658b82dc718 -log2 400880d340d59430 3ff9d6a10333ed84 -log2 446395deba3354f8 4051d2ab5bbc6614 -log2 414c21ce3bf5307e 4035d06babfefd28 -log2 3fd89cd81bc9094e bff60f08e3063e6c -log2 3b712a09bb543986 c051f983c850820e -log2 3fd14fd344a39674 bffe2e58566e8972 -log2 3ff1965d7adaff0f 3fc177c321a39670 -log2 3ff730113c8da565 3fe1211c24f2a3d0 -log2 3ff1aa320cc62bc2 3fc24785650535c0 -log2 3f957df3e07c6a27 c0164c0df514b04e -log2 4063b545060ce27d 401d33eecdfd2dd0 -log2 3ff392448867c7a1 3fd29a5ea13e0bf4 -log2 3f95b562da3742ba c0163d3ea16ded40 -log2 400693b81d39cbf2 3ff7f2d37375bd1e -log2 3fb5a507b927b534 c00c8332ac153c24 -log2 3ff6fb0f9567b805 3fe0b719f7639516 -log2 3ff0861b91d9da57 3fa7cc0da4336e90 -log2 3ff12c6a29fd041b 3fba23ff1bf450d8 -log2 3fc1282feacd9f22 c00731b7b57789b6 -log2 4011d99d3719224e 4001434a55ea52fe -log2 3ff653c755af76de 3fdec459ef0506b8 -log2 3fd1a8923f432de4 bffdb92ec3ac94de -log2 3deb201412f5005c c0401e84f493c656 -log2 3ff2b407f890cce8 3fccd3e79baa94ac -log2 3ff250587edde416 3fc8f14745956554 -log2 41d0e2706c292f95 403e13df8e411c18 -log2 3ff37ce209cdbe55 3fd2354423dee76c -log2 40914e2952474e67 402439edf381fa72 -log2 4004b98db54e53fe 3ff5f8fc61cef240 -log2 3f2bb35e4c11112c c0286a92db5c1eac -log2 3ff2de1e252c6f42 3fce71a0b9139ed4 -log2 3ff9ba49e4d44ec7 3fe5ed9175d46388 -log2 3f75d2eeba04f64f c01e3569409d57ac -log2 3ff35ede53c378fc 3fd1a6a1172febac -log2 4023caa993c4fe82 400a745e0a0fce9e -log2 3f6338323a6f21fd c0217893704d36f6 -log2 42a17c032967ca92 404590623f9407cc -log2 40125fd452d69072 400198d2615151b2 -log2 3ff2701c51b03704 3fca307ec52cf878 -log2 3f259b7716233ff6 c02922135f0e17b0 -log2 3ff607659d47c909 3fdd865a07c3fca6 -log2 3fe92985e63fbb87 bfd63232d107f742 -log2 3fe65995e9a11a35 bfe091d2c90feab9 -log2 3ff049c57c53c512 3f9a5ee2df8ad220 -log2 40c30182793c3ad1 402a7f2b096dcdb8 -log2 3fe389fa5c2a5378 bfe6c662c1652118 -log2 3fe75f4757ce5f95 bfdd0287d404afcc -log2 3ffad491d6669c49 3fe7dd8b595109ee -log2 4053f1074de3e4e4 4019455404295cd8 -log2 3fd4c4e568fdb24a bff9fa64f3d33d88 -log2 4070f58d50e69ae4 40202b0169a9a912 -log2 40628b19fb87512c 401cd9f06ab5edd0 -log2 4004c63b3f519830 3ff60716ec447106 -log2 3fe1693c056a36e3 bfec191fae40dcb2 -log2 406322bc97696354 401d0864042197f8 -log2 3f8220ef0bd858b0 c01b4779cf4a8efc -log2 40f0ba47daec2c00 4030106d0757b0c2 -log2 3fc1d64f953acc87 c006bed8a26a918a -log2 4008658041ac0a7e 3ff9bcd505b2d576 -log2 4022d8d0f0bb999e 4009e3db5f04d412 -log2 3ff90bee40cf6b9c 3fe4b07b2e5bbd6a -log2 3ffa0726bb1b2514 3fe676b1806c0c92 -log2 3f860dadf07037da c01a25f548c11548 -log2 3e6b1bf96ceecd70 c0383d41ceb1dc78 -log2 3ffab2f048e2ecfa 3fe7a388be2cd652 -log2 3f0b1c09e7ecd1b4 c02c7a81dc5747a8 -log2 3d6001845a0a837f c0447fee7ea51cc4 -log2 3fe2d79c98d6fda6 bfe87385e852d799 -log2 3ff0717d4ac61b05 3fa4301bdab4e4f0 -log2 3ff507805b621520 3fd93cb00bfe1556 -log2 4025e1466a85aae1 400b9cc0c60837a6 -log2 3fd3b1ba9c3093ba bffb346acacc2434 -log2 3e8315b69c491e0e c036bee2b06c0ce0 -log2 3b8e98ec17bca87e c051842379006ee2 -log2 3fe680092344c809 bfe042aa8bd46d38 -log2 3d7101b69c702691 c043f4bb68f8a4ce -log2 3f947e082fd2a5c8 c016926bbcf12fb6 -log2 406642e2c6efa0a0 401de7e639d4a886 -log2 3d6be95325f3c4b4 c044193e60c0181f -log2 3e49f2e76d400ce1 c03a4d6a31c27fcb -log2 3c2f06db8e4521ae c04e05b40ffb8825 -log2 436eefd00249816f 404bf9c2941c14fe -log2 44d54ea3ec367566 40539a72fd1bc612 -log2 425ea542150e4a3b 40437803727f47a4 -log2 3fd589b167d89bb5 bff9239f3b3db8f8 -log2 3f7416bc91f70fb7 c01eafccbcebd1a3 -log2 3ced771325e5c09e c0480f3d74b25cb8 -log2 3a2152b71c842fd0 c05738a9f8afc062 -log2 446415ac346c16f5 4051d4fe50369fa4 -log2 446cea52d182b5f2 4051f6a40b5ae3df -log2 420cd3cde21179b3 4040ecb80d62be06 -log2 3b5481244fc9da0c c0526918b9c2e920 -log2 4518f61084e7fb4e 4054a91037750221 -log2 408f137ce43eae6b 4023ea5c337e61e5 -log2 3bd187a0db387bd9 c05077919cf0abce -log2 3c50a163080d8f4f c04cf8dd1a63f44a -log2 43996f4f5206d19c 404d5599033f298e -log2 44d27ab70c262882 40538d4d4ace9f27 -log2 43837191bf1ef3ec 404ca3ff341968d8 -log2 43af5c0783ce93dc 404dfc4429c9635f -log2 3ebef344999e52ec c0330c5199a3ed98 -log2 3f9d0d25a585f195 c0148ed048bfa237 -log2 42e02366ae09abb2 40478196d40b3ad2 -log2 45b86db96aeef2b8 405727126e2c79c0 -log2 442b39ccf9f07e8e 4050f114eace9258 -log2 3c98443af7f8504e c04ab315da47e868 -log2 414855226bc02c44 40359ad538a4426e -log2 40085a145a3d4e99 3ff9b203fde76257 -log2 3ea4ca7b6cae5f8a c0349f43072731ed -log2 440b300b82d6dcb8 405070f3cf10cd21 -log2 458cc4345692df17 4056762a020b9760 -log2 3be7259ff9a8c475 c0501de765dfe4dd -log2 4525b07b2478a4ea 4054dc1736aac9de -log2 3f57db651a4e65bf c022d8e9c6df0380 -log2 4388f87eabfa8da6 404cd23268c6b43d -log2 460d5613b6fecf98 405877f9a48d8fbd -log2 39f4a738aa6f388c c057e86ddef47593 -log2 45f0ac70a167907c 405803cebc731150 -log2 44639d8e20e618ef 4051d2cf8fa4cadb -log2 3f131f2dd07c0ed0 c02b7c575fc2536f -log2 3e497522426af4ec c03a547971c6cb41 -log2 3a01317dcaf2da19 c057b95bb8dc8588 -log2 4077d22ac7b153ef 402125f84bac4f40 -log2 3b320ef236b7ed8e c052f4d367c506da -log2 4199ac42339391f4 403aaea2ecb20431 -log2 3ac2ab8898477f8a c054b1c008ef785f -log2 3b69c6f49d39614b c05213f772a96bad -log2 4049fc3bbd67c773 4016cc69fd069df2 -exp2 4040dc06137f2ddd 420a55e183c906f4 -exp2 c04dd779fd44b39f 3c33ed16e588f4e8 -exp2 40512a7804cea123 44395813df2a6012 -exp2 c04c3396c6b800d6 3c68334fd1397654 -exp2 c04cea8e044b215d 3c51f864470cae7a -exp2 40560d3c3cbec781 4572774d8acd14d2 -exp2 403693486fb7606a 4157d716ec29414e -exp2 40516680a2c24299 4448474511f12dce -exp2 4052aa93af672f38 44995fad16e538f6 -exp2 401150f6547705db 40341963cd27acaa -exp2 404be86564dd0b90 436c290de62dd7b4 -exp2 c050a55f3ec3b34e 3bc559363976f5b3 -exp2 401ed93deaa6c307 406a363f5985840c -exp2 c02735b231d08dfd 3f350a78c138e68c -exp2 4055722a88372b05 454b8c248818ac32 -exp2 4040bab44f41a461 4205fcdcb87bc516 -exp2 c0559e73b1a5fb9e 3a87028edcc3ee80 -exp2 c0346118e7b8edd4 3ea89a27e16e3670 -exp2 c047c38d18a32ee2 3cf6324a1375b23c -exp2 404d37edd6f97533 4395a8e6770c75b4 -exp2 401c8e96106926fb 40619f0a356744f8 -exp2 c046a700175eaf9e 3d19e85fd28a7b9e -exp2 c057dd30154e4f64 39f753c24ed83284 -exp2 40576e77de7f2a4a 45ca774955cf912e -exp2 c0533044f10e93a3 3b22f8ce542e3d1e -exp2 c052194d09b88264 3b6854845745960a -exp2 c05891d483ed3473 39ca616d593f4364 -exp2 c0582672591e73f6 39e519f91e1b6d26 -exp2 4055a573c2a30d0b 455800f888a50eee -exp2 4005d78b23ebec36 401a8af18ed2558c -exp2 c0526348cdaec84f 3b55d63077f0415c -exp2 4053460ff702d872 44c115f5d7f8dc36 -exp2 c0529df245c80d58 3b4722e63bdd63aa -exp2 c051a62e2ecb17c9 3b852992ee815230 -exp2 c04989bb91b806f4 3cbe5b6ca80b7a9a -exp2 4055578cb781c6a8 4544a602c7a686f4 -exp2 c04f07146f78b801 3c0ecbdf8adbaa76 -exp2 c04dc9f8886493f0 3c3570251e2c21fc -exp2 c04b1c0fc05650a7 3c8b7d1e9b1ab4d0 -exp2 c04197a12ab7fc8a 3dbc280dca42a47e -exp2 c0221bcd0e1afec9 3f5ed1683b67f5f2 -exp2 403c48e3971d802e 41b37da643a40e64 -exp2 40329b09e64b1294 4118589b24b42e3e -exp2 4057e5b6f77888df 45e81277a92d3cc4 -exp2 404a44151fc230ef 4337221b32183828 -exp2 4038ba06e6ae6f5a 417a7a1cb8f425c8 -exp2 c03d3f8434b36ee0 3e1af1a614705d1e -exp2 c04bd017a8cc6f41 3c74bd327211c6b2 -exp2 c0075893fdd119a5 3fc0eecc3b8f933c -exp2 c04999ce36c77313 3cbbd39e17e29698 -exp2 c032712320c826b3 3ec78e7b89b4567c -exp2 c05152ea4b426fca 3b9a1286d86b1848 -exp2 c0463ece8d53ea7f 3d26c62aca8d6e0e -exp2 c0463327e906d42e 3d2841db9df8faca -exp2 c04067557f49c762 3de24954f6038d3a -exp2 c04da577aa425646 3c3a1fa8c05f9386 -exp2 404167aa7d73ce98 421c0c9bd7c2d7b0 -exp2 c053220a3274542e 3b26220ccd3bf610 -exp2 40403f3eb2fe1250 41f688fb4519698e -exp2 c045f9673505fc63 3d3094f7bca5b2a4 -exp2 c040e4d847637ed7 3dd288dc10d1b340 -exp2 c03f68e62d48f32c 3df81681c65d7a06 -exp2 c04f9e6a68548599 3bfb23faa67ceddc -exp2 4046c57aa7ce9c6b 42c74f1081089b06 -exp2 4045505f9272244d 4298b9add488fb2a -exp2 40567138b5bf7ec7 458b445cdec2973a -exp2 402d24707bf67a2c 40d7c58b71e76452 -exp2 4058ba00c10ffd05 461dfcd5e717f6c2 -exp2 c0558dec590bf26c 3a8b8551dc53e984 -exp2 40531e29052f5804 44b62e5732dfaefc -exp2 c0345f5835245c1c 3ea8b81dabfb429e -exp2 c0502841f111eb17 3be4b10e84a9bc40 -exp2 400c01437a495b94 4026a318b8221088 -exp2 c0476356301eee5e 3d02afc5119a6ce2 -exp2 c05725390e478a9c 3a25620c80db6282 -exp2 c04e4e1a17b3ea88 3c24f6bbf3793d8c -exp2 c0586d7ebbc1ea5f 39d38cf3145a9e84 -exp2 403588f01559d7a2 41472e82c0a64266 -exp2 c033279fcd67c0b1 3ebcbe9c8d261320 -exp2 c047dad450aa9f3f 3cf3914ee53bdb48 -exp2 40120b4fc0a3f7e1 4036cd245202152c -exp2 4056574a7f28e990 45849739005738c8 -exp2 c0550ed29881c6bf 3aab41065c8e12de -exp2 4056e26984361ae1 45a739f1b83414fe -exp2 4051a4a618d2eea5 4457cbbc781f28d4 -exp2 c043cef24761c122 3d74de3f7d350d5a -exp2 404eb1a9eb6e3525 43c4efedb12d2a9c -exp2 4040ecaad6011899 420cd1bdca31be40 -exp2 c033463bc4057cb7 3eba7555a76628aa -exp2 c0360c35115a50f2 3e8ef5a8cccc3252 -exp2 404649b987c6ccef 42b7d9d770541f72 -exp2 4054a41537267266 4517a682fc96221e -exp2 40532ce3862aac84 44ba045f24e3def6 -exp2 c01d34e60d8ef7c0 3f79f6533fbd9314 -exp2 4032564083a02592 4114357d3d82db18 -exp2 403867f9313a5016 417533c74969a394 -exp2 404c210094f747cc 437321806b00d312 -exp2 c053e888d9c8c80b 3af4a1309b501e46 -exp2 403c9d546ba90209 41b87f63b52ff66e -exp2 c01e9c8ac350a8e9 3f745a36c7f95b7a -exp2 c04f1e79d6dd5011 3c0b21b620c04c74 -exp2 4042c6ec34a4b9cc 42477de48b3744c8 -exp2 c0562d36af0ad0bf 3a639c3a8aed5233 -exp2 40307142757554ad 40f5bdfb32a334da -exp2 c045b83a068dab0f 3d3799a8df0b15ea -exp2 c048bf754664862e 3cd6b1a45ab04982 -exp2 c047493dd3394fb7 3d0585dcf18aa742 -exp2 c03b77eaf42f3616 3e3720c7441da498 -exp2 c049655934e9eb90 3cc27befda49e4d2 -exp2 4054b2337fbde4dd 451b8ed1885fdce6 -exp2 405761e5a40bdda9 45c718dcf4e7df20 -exp2 c040bac24d7d939b 3dd74760093fb12a -exp2 403c9c81eed24f26 41b8717181f5ee30 -exp2 4047549df610eb57 42d94cd2ad38f9e8 -exp2 40158ca962fa50a2 4044ed93a8ba989a -exp2 40511f8fcb76626b 4436852fb7671e5c -exp2 4051aebef7f0abb4 445a8bb26872d0b8 -exp2 c05716827c9ba767 3a2913ae233f10e8 -exp2 c05602f430abea1a 3a6efe127e34c8f2 -exp2 4039cb2a9ae64d7a 418bbc1394e854ee -exp2 404cc98ce1f80ae4 4387d413e2acccc4 -exp2 403d443940a5ddd7 41c33f043d0caaf4 -exp2 4030590b1efb921e 40f45cbd36bbb8bc -exp2 c00cecbbcf39910a 3fb4e29ae791e13c -exp2 404da18e398ac9e1 43a3303290444a8a -exp2 c02ca61738979e54 3f098e6635467cf6 -exp2 40264e6dc3547f6c 40a1cad438f1e7c6 -exp2 c02adf93e41f42a2 3f17a48a09c309bc -exp2 3fdedd87f3b46910 3ff659dee69e00f2 -exp2 4053a29735facb89 44d74573272b946e -exp2 4055611d55ba0022 4546e6f7cc7c4158 -exp2 c040ade4f26b09eb 3dd8f5565b062df6 -exp2 403c863f8b3780c5 41b703734457c16c -exp2 c04bcd8f21bbf206 3c7506885f4efab8 -exp2 c047d969c426d4b4 3cf3b7df5fbba402 -exp2 4053051248694848 44b0e744b6e51652 -exp2 4042513f5aed801d 4238d7b6876d690e -exp2 405232297c19f7be 447b8bd48a9d48d4 -exp2 404031ce3a0782ce 41f4f40be9eec12e -exp2 4043b1ceade5a557 4264f4190f9c4a72 -exp2 c04eb96d64d5a3d6 3c1772815d244300 -exp2 40472bd0374ad3d2 42d448c802925a4a -exp2 c03a6165874c4b9e 3e48950dc1fca25c -exp2 c029d8e56cfa38f2 3f20deae03bd48e8 -exp2 c04848972e06dd07 3ce59951ed2cb5f2 -exp2 4056f121b15b42e8 45ab3d919d0d553c -exp2 40157178c16459a9 40448bdf72ba47a0 -exp2 c04c8df8efb89a1b 3c5dab08827e2694 -exp2 404b64c0c7674dc7 435b9c3ab93414ea -exp2 40552f7d068fcca4 453ac28f0dc5231a -exp2 c0439c33023463e6 3d7b77df8a1e3068 -exp2 c045e79cbb10379b 3d32424885d1eb92 -exp2 c0471f70e6a143c3 3d0afd81c374d1e5 -exp2 4056c3d7bd0b8bc1 45a0ae10e0e2f2bd -exp2 4044ab79e9385126 42843f4f53bc3b98 -exp2 c04b4b44f62dce09 3c8549b029d8664e -exp2 4056869fc9e3e333 459130a7cf7495a1 -exp2 404ad116020be133 4348d2272ffd5006 -exp2 4045f62afe91f763 42ae573e7b79848d -exp2 bfe488227547f64c 3fe4830526318d5e -exp2 c002672edd8548f2 3fc9fc3557502b86 -exp2 c056d0961c564780 3a3abd03d1b54c40 -exp2 c05566233300c8b8 3a952c178996313a -exp2 c02856333e594df1 3f2c79aec1b28c03 -exp2 403f4eb05197864f 41e3cc9f46980448 -exp2 404d150254ac13e8 4391ed8a0fe9a2f4 -exp2 404824fcd702e8cd 42f38c58c90566ed -exp2 c041fb6ed54f43d8 3db066904a46659d -exp2 4047830b5101c8b1 42e044150e5a32a8 -exp2 c038b3662aecdec2 3e63b00cc49aafd3 -exp2 c04b6fb7d74431f0 3c81798af8822cd6 -exp2 c050d7bf9ca2150d 3bb8be205b7974d4 -exp2 405516591a8eed13 453461aa1b9db25c -exp2 4048ceadd9eee528 43087fdf5d78bd1a -exp2 405098c551e440f3 4414ec6216e1f4cf -exp2 c05485a1cf7d4736 3ace1b3dceeeed37 -exp2 c035ace0aa188f9c 3e9409d5edc75e68 -exp2 403383ca0deb9b92 4126dc5b2d263172 -exp2 c052d7a71739ccc2 3b38c4b36918aec3 -exp2 c0227aee989ac54c 3f5b180c94ff9863 -exp2 40481720b353229b 42f2227f60bf2009 -exp2 c052fb83030bc63a 3b30cc05e4b7a448 -exp2 404dac009273df89 43a44e187ad2135d -exp2 c0492d64dc58abcc 3cc906ac1956d283 -exp2 c0234c0c53a9d0c6 3f5469eab68074e5 -exp2 403bff3ef2b78dd4 41afef4a573add59 -exp2 405783e785d81ffc 45d0b0eb18a0c5e6 -exp2 40506b73a3fc44d9 44099d836fa45256 -exp2 c051ba3ec8242190 3b810769aca80765 -exp2 c0036d0eff778dad 3fc7c7fbc7c72c05 -exp2 401b4093f45420d9 405c1c6c7344b277 -exp2 403f6d0fbc1c6ea4 41e57f124a5a114f -exp2 c052984d0cabc324 3b489856867e5ad2 -exp2 c031ddd5175bc871 3ed18d0319c52d65 -exp2 c047cd5f79ae85c2 3cf50bf62456785d -exp2 c03d0814f8846e79 3e1f4eaf3a69f2cd -exp2 c04f93cf727b4d6c 3bfcbeaea4658b32 -exp2 40103e2c8ddc0da4 4030b00fd8a398a8 -exp2 c046dc1e552045b0 3d136e75dd02c0bc -exp2 4053f91334fee51e 44edb012573b1061 diff --git a/src/promql/src/histogram_eval/native.rs b/src/promql/src/histogram_eval/native.rs index e3fd468267a..3b2cc222660 100644 --- a/src/promql/src/histogram_eval/native.rs +++ b/src/promql/src/histogram_eval/native.rs @@ -13,14 +13,11 @@ // limitations under the License. //! Prometheus `HistogramQuantile`, `HistogramFraction` and the `histogramVariance` estimate over -//! one native histogram, with the bucket iteration of `model/histogram` and the Go `math` -//! functions they call, so results match Prometheus on amd64 bit for bit. +//! one native histogram, with the bucket iteration of `model/histogram`. use datafusion::error::{DataFusionError, Result}; use datatypes::series::histogram::{BucketSideView, HistogramView}; -use super::bounds::EXPONENTIAL_BOUNDS; - const CUSTOM_BUCKETS_SCHEMA: i32 = -53; #[derive(Debug, Clone, Copy)] @@ -128,25 +125,17 @@ fn bound(idx: i32, schema: i32, custom_values: &[f64]) -> Result { _ => Err(invalid_layout()), }; } - if schema < 0 { - if schema < -4 { - return Err(invalid_layout()); - } - let exp = i64::from(idx) << -schema; - if exp == 1024 { - return Ok(f64::MAX); - } - return Ok(ldexp(1.0, exp)); + if !(-4..=8).contains(&schema) { + return Err(invalid_layout()); } - let bounds = EXPONENTIAL_BOUNDS - .get(schema as usize) - .ok_or_else(invalid_layout)?; - let frac = bounds[(idx & ((1 << schema) - 1)) as usize]; - let exp = i64::from(idx >> schema) + 1; - if frac == 0.5 && exp == 1025 { + // The upper bound of bucket `idx` is 2^(idx / 2^schema). + let exponent = f64::from(idx) * 2f64.powi(-schema); + if exponent == 1024.0 { + // The last bucket of finite values; its computed bound would overflow to +Inf, which + // Go reserves for the bucket of infinite observations. return Ok(f64::MAX); } - Ok(ldexp(frac, exp)) + Ok(exponent.exp2()) } fn invalid_layout() -> DataFusionError { @@ -237,14 +226,12 @@ pub(super) fn quantile( if custom || (bucket.lower <= 0.0 && bucket.upper >= 0.0) { return Ok(bucket.lower + (bucket.upper - bucket.lower) * fraction); } - let log_lower = log2(bucket.lower.abs()); - let log_upper = log2(bucket.upper.abs()); + let log_lower = bucket.lower.abs().log2(); + let log_upper = bucket.upper.abs().log2(); if bucket.lower > 0.0 { - return Ok(exp2(log_lower + (log_upper - log_lower) * fraction)); + return Ok((log_lower + (log_upper - log_lower) * fraction).exp2()); } - Ok(-exp2( - log_upper + (log_lower - log_upper) * (1.0 - fraction), - )) + Ok(-(log_upper + (log_lower - log_upper) * (1.0 - fraction)).exp2()) } /// Prometheus `HistogramFraction`. @@ -331,9 +318,9 @@ pub(super) fn fraction( /// Go `Bucket.FractionBelow` with exponential interpolation. fn fraction_below_exponential(b: NativeBucket, v: f64) -> f64 { - let log_lower = log2(b.lower.abs()); - let log_upper = log2(b.upper.abs()); - let log_v = log2(v.abs()); + let log_lower = b.lower.abs().log2(); + let log_upper = b.upper.abs().log2(); + let log_v = v.abs().log2(); if v > 0.0 { (log_v - log_lower) / (log_upper - log_lower) } else { @@ -376,148 +363,16 @@ fn kahan_inc(inc: f64, sum: f64, c: f64) -> (f64, f64) { (t, c) } -/// Go `math.Ldexp` for a positive normal `frac`. -fn ldexp(frac: f64, exp: i64) -> f64 { - let bits = frac.to_bits(); - let exp = exp + ((bits >> 52) & 0x7FF) as i64 - 1023; - if exp < -1075 { - return 0.0; - } - if exp > 1023 { - return f64::INFINITY; - } - let (exp, scale) = if exp < -1022 { - (exp + 53, 1.0 / (1u64 << 53) as f64) - } else { - (exp, 1.0) - }; - scale * f64::from_bits((bits & !(0x7FF << 52)) | (((exp + 1023) as u64) << 52)) -} - -/// Go `math.Frexp`. -fn frexp(x: f64) -> (f64, i64) { - if x == 0.0 || x.is_infinite() || x.is_nan() { - return (x, 0); - } - let (x, mut exp) = if x.abs() < f64::MIN_POSITIVE { - (x * (1u64 << 52) as f64, -52) - } else { - (x, 0) - }; - let bits = x.to_bits(); - exp += ((bits >> 52) & 0x7FF) as i64 - 1023 + 1; - (f64::from_bits((bits & !(0x7FF << 52)) | (1022 << 52)), exp) -} - -/// Go `math.Log`, whose amd64 assembly performs the same operations for normal inputs. -// Constants are copied verbatim from Go's `math` package. -#[allow(clippy::excessive_precision)] -fn log(x: f64) -> f64 { - const LN2_HI: f64 = 6.93147180369123816490e-01; - const LN2_LO: f64 = 1.90821492927058770002e-10; - const L1: f64 = 6.666666666666735130e-01; - const L2: f64 = 3.999999999940941908e-01; - const L3: f64 = 2.857142874366239149e-01; - const L4: f64 = 2.222219843214978396e-01; - const L5: f64 = 1.818357216161805012e-01; - const L6: f64 = 1.531383769920937332e-01; - const L7: f64 = 1.479819860511658591e-01; - if x.is_nan() || x == f64::INFINITY { - return x; - } - if x < 0.0 { - return f64::NAN; - } - if x == 0.0 { - return f64::NEG_INFINITY; - } - let (mut f1, mut ki) = frexp(x); - if f1 < std::f64::consts::SQRT_2 / 2.0 { - f1 *= 2.0; - ki -= 1; - } - let f = f1 - 1.0; - let k = ki as f64; - let s = f / (2.0 + f); - let s2 = s * s; - let s4 = s2 * s2; - let t1 = s2 * (L1 + s4 * (L3 + s4 * (L5 + s4 * L7))); - let t2 = s4 * (L2 + s4 * (L4 + s4 * L6)); - let r = t1 + t2; - let hfsq = 0.5 * f * f; - k * LN2_HI - ((hfsq - (s * (hfsq + r) + k * LN2_LO)) - f) -} - -/// Go `math.Log2`. -fn log2(x: f64) -> f64 { - let (frac, exp) = frexp(x); - if frac == 0.5 { - return (exp - 1) as f64; - } - log(frac) * std::f64::consts::LOG2_E + exp as f64 -} - -/// Go `math.Exp2`, which is not assembly on amd64. -// Constants are copied verbatim from Go's `math` package. -#[allow(clippy::excessive_precision)] -fn exp2(x: f64) -> f64 { - const LN2_HI: f64 = 6.93147180369123816490e-01; - const LN2_LO: f64 = 1.90821492927058770002e-10; - const OVERFLOW: f64 = 1.0239999999999999e+03; - const UNDERFLOW: f64 = -1.0740e+03; - const P1: f64 = 1.66666666666666657415e-01; - const P2: f64 = -2.77777777770155933842e-03; - const P3: f64 = 6.61375632143793436117e-05; - const P4: f64 = -1.65339022054652515390e-06; - const P5: f64 = 4.13813679705723846039e-08; - if x.is_nan() || x == f64::INFINITY { - return x; - } - if x == f64::NEG_INFINITY || x < UNDERFLOW { - return 0.0; - } - if x > OVERFLOW { - return f64::INFINITY; - } - let k = if x > 0.0 { - (x + 0.5) as i64 - } else if x < 0.0 { - (x - 0.5) as i64 - } else { - 0 - }; - let t = x - k as f64; - let hi = t * LN2_HI; - let lo = -t * LN2_LO; - let r = hi - lo; - let t = r * r; - let c = r - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); - let y = 1.0 - ((lo - (r * c) / (2.0 - c)) - hi); - ldexp(y, k) -} - #[cfg(test)] mod tests { - /// The bucket interpolation goes through Go's `math.Log2` and `math.Exp2`, which differ from - /// the platform functions in the last bit on some arguments. + /// The last bucket of finite values ends at `f64::MAX`; only the next one, which counts + /// infinite observations, ends at +Inf. #[test] - fn log2_and_exp2_match_go() { - let mut checked = 0; - for line in include_str!("go_math_cases.txt").lines() { - if line.starts_with('#') { - continue; - } - let fields: Vec<&str> = line.split(' ').collect(); - let bits = |field: &str| u64::from_str_radix(field, 16).unwrap(); - let argument = f64::from_bits(bits(fields[1])); - let actual = match fields[0] { - "log2" => super::log2(argument), - "exp2" => super::exp2(argument), - function => panic!("unknown function {function}"), - }; - assert_eq!(actual.to_bits(), bits(fields[2]), "{line}"); - checked += 1; + fn last_finite_bucket_ends_at_max() { + for schema in [-4, 0, 3, 8] { + let last = 1024i32 << schema.max(0) >> (-schema).max(0); + assert_eq!(super::bound(last, schema, &[]).unwrap(), f64::MAX); + assert_eq!(super::bound(last + 1, schema, &[]).unwrap(), f64::INFINITY); } - assert_eq!(checked, 400); } } diff --git a/src/promql/src/histogram_eval/tests.rs b/src/promql/src/histogram_eval/tests.rs index 3f27cc2bba3..8755a81fd04 100644 --- a/src/promql/src/histogram_eval/tests.rs +++ b/src/promql/src/histogram_eval/tests.rs @@ -184,7 +184,30 @@ fn assert_outcome( (labels.clone(), points) }) .collect(); - assert_eq!(actual, expected, "case {:?}", case.spec); + let keys = |series: &BTreeMap| { + series + .iter() + .map(|(labels, points)| (labels.clone(), points.keys().copied().collect())) + .collect::)>>() + }; + assert_eq!(keys(&actual), keys(&expected), "case {:?}", case.spec); + // promql-compat's tolerance for ill-conditioned evaluation covers the variance. + let epsilon = if case.spec[0].contains("stddev") || case.spec[0].contains("stdvar") { + 1e-6 + } else { + 1e-10 + }; + for (labels, points) in &actual { + for (point, &bits) in points { + let got = f64::from_bits(bits); + let want = f64::from_bits(expected[labels][point]); + assert!( + close(got, want, epsilon), + "case {:?}: {labels:?} at {point}: {got} vs {want}", + case.spec + ); + } + } false } (Err(actual), Err(expected)) => { @@ -327,3 +350,21 @@ fn histogram_functions_drop_metadata_labels() { expected.remove("__name__"); assert_eq!(labels_of(&count.metric), expected); } + +/// Prometheus `almost.Equal`, treating results below 1e-10 as equal and any NaN as equal to NaN, +/// as promql-compat compares engines. +fn close(a: f64, b: f64, epsilon: f64) -> bool { + if a.is_nan() || b.is_nan() { + return a.is_nan() && b.is_nan(); + } + if a == b { + return true; + } + let (diff, sum) = ((a - b).abs(), a.abs() + b.abs()); + let equal = if a == 0.0 || b == 0.0 || sum < f64::MIN_POSITIVE { + diff < epsilon * f64::MIN_POSITIVE + } else { + diff / sum.min(f64::MAX) < epsilon + }; + equal || (a.abs() < 1e-10 && b.abs() < 1e-10) +}