This can be greatly accelerated. For now we just use a simply binary search. In practice, you should *not* do that.
| 2776 | // This can be greatly accelerated. For now we just use a simply |
| 2777 | // binary search. In practice, you should *not* do that. |
| 2778 | uint32_t find_range_index(uint32_t key) { |
| 2779 | //////////////// |
| 2780 | // This could be implemented with std::lower_bound, but we roll our own |
| 2781 | // because we want to allow further optimizations in the future. |
| 2782 | //////////////// |
| 2783 | uint32_t len = std::size(table); |
| 2784 | uint32_t low = 0; |
| 2785 | uint32_t high = len - 1; |
| 2786 | while (low <= high) { |
| 2787 | uint32_t middle_index = (low + high) >> 1; // cannot overflow |
| 2788 | uint32_t middle_value = table[middle_index][0]; |
| 2789 | if (middle_value < key) { |
| 2790 | low = middle_index + 1; |
| 2791 | } else if (middle_value > key) { |
| 2792 | high = middle_index - 1; |
| 2793 | } else { |
| 2794 | return middle_index; // perfect match |
| 2795 | } |
| 2796 | } |
| 2797 | return low == 0 ? 0 : low - 1; |
| 2798 | } |
| 2799 | |
| 2800 | void ascii_map(char* input, size_t length) { |
| 2801 | auto broadcast = [](uint8_t v) -> uint64_t { |