| 942 | } |
| 943 | |
| 944 | fl::size find_unoccupied_index_using_bitset( |
| 945 | const Key &key, const fl::bitset<1024> &occupied_set) const { |
| 946 | const fl::size cap = _buckets.size(); |
| 947 | const fl::size mask = cap - 1; |
| 948 | const fl::size h = _hash(key) & mask; |
| 949 | |
| 950 | if (cap <= kLinearProbingOnlySize) { |
| 951 | // linear probing |
| 952 | for (fl::size i = 0; i < cap; ++i) { |
| 953 | const fl::size idx = (h + i) & mask; |
| 954 | bool occupied = occupied_set.test(idx); |
| 955 | if (occupied) { |
| 956 | continue; |
| 957 | } |
| 958 | return idx; |
| 959 | } |
| 960 | } else { |
| 961 | // quadratic probing up to 8 tries |
| 962 | fl::size i = 0; |
| 963 | for (; i < kQuadraticProbingTries; ++i) { |
| 964 | const fl::size idx = (h + i + i * i) & mask; |
| 965 | bool occupied = occupied_set.test(idx); |
| 966 | if (occupied) { |
| 967 | continue; |
| 968 | } |
| 969 | return idx; |
| 970 | } |
| 971 | // fallback to linear for the rest |
| 972 | for (; i < cap; ++i) { |
| 973 | const fl::size idx = (h + i) & mask; |
| 974 | bool occupied = occupied_set.test(idx); |
| 975 | if (occupied) { |
| 976 | continue; |
| 977 | } |
| 978 | return idx; |
| 979 | } |
| 980 | } |
| 981 | return npos(); |
| 982 | } |
| 983 | |
| 984 | void rehash_internal(fl::size new_cap) { |
| 985 | new_cap = next_power_of_two(new_cap); |
no test coverage detected