| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you 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. | |
| */ | |
| #include <catch2/catch.hpp> | |
| #include <cmath> | |
| #include <sstream> | |
| #include <fstream> | |
| #include <quantiles_sketch.hpp> | |
| #include <serde.hpp> | |
| #include <test_allocator.hpp> | |
| namespace datasketches { | |
| #ifdef TEST_BINARY_INPUT_PATH | |
| static std::string testBinaryInputPath = TEST_BINARY_INPUT_PATH; | |
| #else | |
| static std::string testBinaryInputPath = "test/"; | |
| #endif | |
| // these tests are for compatibility with old versions of Java's | |
| // Quantiles sketch, which is only for doubles. | |
| // | |
| // typical usage would be just quantiles_sketch<double>, but here we use test_allocator | |
| using quantiles_double_sketch = quantiles_sketch<double, std::less<double>, test_allocator<double>>; | |
| static void quantiles_decode_and_check(uint16_t k, uint64_t n, const std::string& version, | |
| double expected_median) { | |
| const double median_rank = 0.5; | |
| std::ostringstream filestr; | |
| filestr << "Qk" << k << "_n" << n << "_v" << version << ".sk"; | |
| // as stream | |
| std::ifstream is; | |
| is.exceptions(std::ios::failbit | std::ios::badbit); | |
| std::string filename = testBinaryInputPath + filestr.str(); | |
| is.open(filename, std::ios::binary); | |
| auto sketch_stream = quantiles_double_sketch::deserialize(is, serde<double>(), std::less<double>(), 0); | |
| is.close(); | |
| REQUIRE(sketch_stream.get_quantile(median_rank) == expected_median); | |
| // as bytes | |
| std::ifstream infile(filename, std::ios::binary); | |
| std::vector<char> bytes( | |
| (std::istreambuf_iterator<char>(infile)), | |
| (std::istreambuf_iterator<char>())); | |
| infile.close(); | |
| auto sketch_bytes = quantiles_double_sketch::deserialize(bytes.data(), bytes.size(), serde<double>(), | |
| std::less<double>(), 0); | |
| REQUIRE(sketch_bytes.get_quantile(median_rank) == expected_median); | |
| } | |
| TEST_CASE("quantiles compatibility", "[quantiles_compatibility]") { | |
| // setup | |
| test_allocator_total_bytes = 0; | |
| SECTION("Qk128_n50_v0.3.0.sk") { | |
| // file: Qk128_n50_v0.3.0.sk | |
| // median: 25 | |
| quantiles_decode_and_check(128, 50, "0.3.0", 25); | |
| } | |
| SECTION("Qk128_n1000_v0.3.0.sk") { | |
| // file: Qk128_n1000_v0.3.0.sk | |
| // median: ~500 | |
| quantiles_decode_and_check(128, 1000, "0.3.0", 497); | |
| } | |
| SECTION("Qk128_n50_v0.6.0.sk") { | |
| // file: Qk128_n50_v0.6.0.sk | |
| // median: 25 | |
| quantiles_decode_and_check(128, 50, "0.6.0", 25); | |
| } | |
| SECTION("Qk128_n1000_v0.6.0.sk") { | |
| // file: Qk128_n1000_v0.6.0.sk | |
| // median: ~500 | |
| quantiles_decode_and_check(128, 1000, "0.6.0", 497); | |
| } | |
| SECTION("Qk128_n50_v0.8.0.sk") { | |
| // file: Qk128_n50_v0.8.0.sk | |
| // median: 25 | |
| quantiles_decode_and_check(128, 50, "0.8.0", 25); | |
| } | |
| SECTION("Qk128_n1000_v0.8.0.sk") { | |
| // file: Qk128_n1000_v0.8.0.sk | |
| // median: ~500 | |
| quantiles_decode_and_check(128, 1000, "0.8.0", 497); | |
| } | |
| SECTION("Qk128_n50_v0.8.3.sk") { | |
| // file: Qk128_n50_v0.8.3.sk | |
| // median: 25 | |
| quantiles_decode_and_check(128, 50, "0.8.3", 25); | |
| } | |
| SECTION("Qk128_n1000_v0.8.3.sk") { | |
| // file: Qk128_n1000_v0.8.3.sk | |
| // median: ~500 | |
| quantiles_decode_and_check(128, 1000, "0.8.3", 497); | |
| } | |
| // cleanup | |
| if (test_allocator_total_bytes != 0) { | |
| REQUIRE(test_allocator_total_bytes == 0); | |
| } | |
| } | |
| } /* namespace datasketches */ |