21#include <cuda_runtime.h>
30namespace fss::cuckoo_hash {
46constexpr int ChBucket(
int t,
int lambda);
52inline constexpr int kDefaultCuckooChoices = 3;
76template <
typename Prp,
typename In>
103 __host__ __device__ LocateResult Locate(int4 sigma, In x,
int k, __uint128_t n,
104 __uint128_t b_size,
int choices = kDefaultCuckooChoices);
113template <
typename Prp,
typename In>
133 int Run(std::span<const In> as,
int m, int4 sigma, __uint128_t n, __uint128_t b_size,
int max_evictions,
134 std::span<std::pair<int, int>> table);
143constexpr double Log2(
double x) {
144 if (x <= 0)
return -1e308;
155 double y = (m - 1.0) / (m + 1.0);
156 double y2 = y * y, sum = 0, term = y;
157 for (
int k = 0; k < 40; ++k) {
158 sum += term / (2 * k + 1);
161 return e + 2.0 * sum / 0.6931471805599453;
164constexpr double Ceil(
double x) {
165 auto i =
static_cast<long long>(x);
166 return (x >
static_cast<double>(i)) ?
static_cast<double>(i + 1) : static_cast<double>(i);
181__host__ __device__
constexpr __uint128_t
CeilDiv(__uint128_t num, __uint128_t den) {
182 return (num - 1) / den + 1;
199__host__ __device__
constexpr __uint128_t
BucketIndexBound(__uint128_t n,
int choices, __uint128_t bucket_size) {
200 return CeilDiv(n * choices, bucket_size);
217__host__ __device__
constexpr __uint128_t
MinBucketSize(__uint128_t n,
int choices, __uint128_t bucket_count) {
218 return CeilDiv(n * choices, bucket_count);
239 __uint128_t bucket_size_min,
int bucket_bits) {
240 return b_size_rt >= bucket_size_min && b_size_rt <= (__uint128_t{1} << bucket_bits);
250 throw std::invalid_argument(
"cuckoo_hash::ChBucket: t must be at least 30");
251 double td =
static_cast<double>(t);
252 double e = (
static_cast<double>(lambda) + 130.0 + detail::Log2(td)) / 123.5;
253 return static_cast<int>(detail::Ceil(e * td));
258template <
typename Prp,
typename In>
260inline __host__ __device__ LocateResult PrpHash<Prp, In>::Locate(
261 int4 sigma, In x,
int k, __uint128_t n, __uint128_t b_size,
int choices) {
262 __uint128_t val =
static_cast<__uint128_t
>(x) + n * k;
263 __uint128_t domain_size = n *
static_cast<__uint128_t
>(choices);
264 __uint128_t y = prp.Permu(sigma, val, domain_size);
271 return {kRejectedBucket, 0};
273 __uint128_t bucket = y / b_size;
277 return {
static_cast<int>(bucket), y % b_size};
280template <
typename Prp,
typename In>
281 requires Permutable<Prp>
282inline int Compact<Prp, In>::Run(std::span<const In> as,
int m, int4 sigma, __uint128_t n,
283 __uint128_t b_size,
int max_evictions, std::span<std::pair<int, int>> table) {
284 PrpHash<Prp, In> hasher{prp};
285 int t =
static_cast<int>(as.size());
288 for (
int i = 0; i < m; ++i) {
292 std::mt19937 rng(42);
294 for (
int omega = 0; omega < t; ++omega) {
296 int cur_k =
static_cast<int>(rng() % 3);
300 auto [bucket, _index] = hasher.Locate(sigma, as[cur_idx], cur_k, n, b_size);
304 if (table[bucket].first == -1) {
306 table[bucket] = {cur_idx, cur_k};
311 int evicted_idx = table[bucket].first;
312 table[bucket] = {cur_idx, cur_k};
315 cur_idx = evicted_idx;
316 cur_k =
static_cast<int>(rng() % 3);
319 if (evictions > max_evictions) {
Small-domain pseudorandom permutation (PRP) interface.
Definition prp.cuh:24
constexpr int kRejectedBucket
Bucket identifier of a rejected candidate.
Definition cuckoo_hash.cuh:62
constexpr __uint128_t MinBucketSize(__uint128_t n, int choices, __uint128_t bucket_count)
Smallest bucket domain size that keeps every located bucket in range.
Definition cuckoo_hash.cuh:217
constexpr bool ValidBucketSize(__uint128_t b_size_rt, __uint128_t bucket_size_min, int bucket_bits)
Test a key's runtime bucket domain size against a configuration.
Definition cuckoo_hash.cuh:238
constexpr __uint128_t CeilDiv(__uint128_t num, __uint128_t den)
Ceiling division of two positive integers, in the wrap-free form.
Definition cuckoo_hash.cuh:181
constexpr __uint128_t BucketIndexBound(__uint128_t n, int choices, __uint128_t bucket_size)
Exclusive upper bound on the bucket index of a located candidate.
Definition cuckoo_hash.cuh:199
constexpr int ChBucket(int t, int lambda)
Estimate the number of buckets for three-choice Cuckoo hashing.
Definition cuckoo_hash.cuh:245
Pseudorandom permutation (PRP) interface.