| 148 | TEST(TDigestTest, DISABLED_HugeVolume) { TestRandom(1U << 30); } |
| 149 | |
| 150 | void TestMerge(const std::vector<std::vector<double>>& values_vector, uint32_t delta, |
| 151 | double error_ratio) { |
| 152 | const std::vector<double> quantiles = {0, 0.01, 0.1, 0.2, 0.3, 0.4, 0.5, |
| 153 | 0.6, 0.7, 0.8, 0.9, 0.99, 1}; |
| 154 | |
| 155 | std::vector<TDigest> tds; |
| 156 | for (const auto& values : values_vector) { |
| 157 | TDigest td(delta); |
| 158 | for (double value : values) { |
| 159 | td.Add(value); |
| 160 | } |
| 161 | ASSERT_OK(td.Validate()); |
| 162 | tds.push_back(std::move(td)); |
| 163 | } |
| 164 | |
| 165 | std::vector<double> values_combined; |
| 166 | for (const auto& values : values_vector) { |
| 167 | values_combined.insert(values_combined.end(), values.begin(), values.end()); |
| 168 | } |
| 169 | const std::vector<double> expected = ExactQuantile(values_combined, quantiles); |
| 170 | |
| 171 | // merge into an empty tdigest |
| 172 | { |
| 173 | TDigest td(delta); |
| 174 | td.Merge(tds); |
| 175 | ASSERT_OK(td.Validate()); |
| 176 | for (size_t i = 0; i < quantiles.size(); ++i) { |
| 177 | const double tolerance = std::max(std::fabs(expected[i]) * error_ratio, 0.1); |
| 178 | EXPECT_NEAR(td.Quantile(quantiles[i]), expected[i], tolerance) << quantiles[i]; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | // merge into a non empty tdigest |
| 183 | { |
| 184 | TDigest td = std::move(tds[0]); |
| 185 | tds.erase(tds.begin(), tds.begin() + 1); |
| 186 | td.Merge(tds); |
| 187 | ASSERT_OK(td.Validate()); |
| 188 | for (size_t i = 0; i < quantiles.size(); ++i) { |
| 189 | const double tolerance = std::max(std::fabs(expected[i]) * error_ratio, 0.1); |
| 190 | EXPECT_NEAR(td.Quantile(quantiles[i]), expected[i], tolerance) << quantiles[i]; |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | // merge tdigests with same distribution |
| 196 | TEST(TDigestTest, MergeUniform) { |