| 470 | |
| 471 | template <typename Summary> |
| 472 | inline float QuerySummaryValue(Summary const& summary, double rank) { |
| 473 | auto entries = summary.Entries(); |
| 474 | CHECK_GE(entries.size(), 1); |
| 475 | if (entries.size() == 1) { |
| 476 | return entries.front().value; |
| 477 | } |
| 478 | |
| 479 | auto rank2 = static_cast<double>(2.0) * rank; |
| 480 | std::size_t query_cursor = 0; |
| 481 | while (query_cursor < entries.size() - 2 && |
| 482 | rank2 >= |
| 483 | static_cast<double>(entries[query_cursor + 1].rmin + entries[query_cursor + 1].rmax)) { |
| 484 | ++query_cursor; |
| 485 | } |
| 486 | auto left = entries[query_cursor]; |
| 487 | auto right = entries[query_cursor + 1]; |
| 488 | auto threshold = static_cast<double>(left.RMinNext() + right.RMaxPrev()); |
| 489 | return rank2 < threshold ? left.value : right.value; |
| 490 | } |
| 491 | |
| 492 | inline double RankErrorForValue(ReferenceColumn const& col, double target_rank, float queried) { |
| 493 | auto lo_it = std::lower_bound(col.values.cbegin(), col.values.cend(), queried); |
no test coverage detected