15 const size_t num_entries,
17 size_t& num_zero_entries,
18 const uint32_t total_bits,
19 const uint64_t* start_pointer)
noexcept
21 constexpr size_t num_bits = 8;
22 constexpr size_t num_buckets = 1UL << num_bits;
23 constexpr uint32_t mask =
static_cast<uint32_t
>(num_buckets) - 1U;
26 for (
size_t i = 0; i < num_entries; ++i) {
27 bucket_counts[(keys[i] >> shift) & mask]++;
34 for (
size_t i = 0; i < num_buckets - 1; ++i) {
35 bucket_counts[i + 1] += bucket_counts[i];
37 if ((shift == 0) && (keys == start_pointer)) {
38 num_zero_entries = bucket_counts[0];
40 for (
size_t i = 1; i < num_buckets + 1; ++i) {
41 offsets[i] = bucket_counts[i - 1];
43 for (
size_t i = 0; i < num_buckets + 1; ++i) {
44 offsets_copy[i] = offsets[i];
46 uint64_t* start = &keys[0];
48 for (
size_t i = 0; i < num_buckets; ++i) {
49 uint64_t* bucket_start = &keys[offsets[i]];
50 const uint64_t* bucket_end = &keys[offsets_copy[i + 1]];
51 while (bucket_start != bucket_end) {
52 for (uint64_t* it = bucket_start; it < bucket_end; ++it) {
53 const size_t value = (*it >> shift) & mask;
57 bucket_start = &keys[offsets[i]];
61 for (
size_t i = 0; i < num_buckets; ++i) {
62 if (offsets_copy[i + 1] - offsets_copy[i] > 1) {
64 offsets_copy[i + 1] - offsets_copy[i],
75 const size_t num_entries,
76 const uint32_t num_bits)
noexcept
78 if (num_entries == 0) {
81 const uint32_t bits_per_round = 8;
82 const uint32_t base = num_bits & 7;
83 const uint32_t total_bits = (base == 0) ? num_bits : num_bits - base + 8;
84 const uint32_t shift = total_bits - bits_per_round;
85 size_t num_zero_entries = 0;
91 if (num_entries > 0) {
92 if ((wnaf_entries[0] & 0xffffffff) != 0) {
96 return num_zero_entries;