15 const size_t num_entries,
17 size_t& num_zero_entries,
18 const uint32_t bucket_index_bits,
19 const uint64_t* top_level_keys)
noexcept
21 constexpr size_t NUM_RADIX_BUCKETS = 1UL <<
RADIX_BITS;
22 constexpr uint32_t RADIX_MASK =
static_cast<uint32_t
>(NUM_RADIX_BUCKETS) - 1U;
26 for (
size_t i = 0; i < num_entries; ++i) {
27 bucket_counts[(keys[i] >> shift) & RADIX_MASK]++;
34 for (
size_t i = 0; i < NUM_RADIX_BUCKETS - 1; ++i) {
35 bucket_counts[i + 1] += bucket_counts[i];
39 if ((shift == 0) && (keys == top_level_keys)) {
40 num_zero_entries = bucket_counts[0];
43 for (
size_t i = 1; i < NUM_RADIX_BUCKETS + 1; ++i) {
44 offsets[i] = bucket_counts[i - 1];
46 for (
size_t i = 0; i < NUM_RADIX_BUCKETS + 1; ++i) {
47 offsets_copy[i] = offsets[i];
53 uint64_t* start = &keys[0];
54 for (
size_t i = 0; i < NUM_RADIX_BUCKETS; ++i) {
55 uint64_t* bucket_start = &keys[offsets[i]];
56 const uint64_t* bucket_end = &keys[offsets_copy[i + 1]];
57 while (bucket_start != bucket_end) {
58 for (uint64_t* it = bucket_start; it < bucket_end; ++it) {
59 const size_t value = (*it >> shift) & RADIX_MASK;
63 bucket_start = &keys[offsets[i]];
69 for (
size_t i = 0; i < NUM_RADIX_BUCKETS; ++i) {
70 const size_t bucket_size = offsets_copy[i + 1] - offsets_copy[i];
71 if (bucket_size > 1) {
73 &keys[offsets_copy[i]], bucket_size, shift -
RADIX_BITS, num_zero_entries, bucket_index_bits, keys);
80 const size_t num_entries,
81 const uint32_t bucket_index_bits)
noexcept
83 if (num_entries == 0) {
89 const uint32_t remainder = bucket_index_bits %
RADIX_BITS;
90 const uint32_t padded_bits = (remainder == 0) ? bucket_index_bits : bucket_index_bits - remainder +
RADIX_BITS;
91 const uint32_t initial_shift = padded_bits -
RADIX_BITS;
93 size_t num_zero_entries = 0;
95 point_schedule, num_entries, initial_shift, num_zero_entries, bucket_index_bits, point_schedule);
100 num_zero_entries = 0;
103 return num_zero_entries;