tiny.simd.Cuckoo2x2Plan
Defined in cuckoo2x2.
API (7)
Actions
Public operations.
Fields and members
Public fields and members.
Source
Source: lib/simd/src/cuckoo2x2.zig:125
zig
pub const Cuckoo2x2Plan = struct { key_count: usize, bucket_counts: [configuration_count]usize, max_bucket_count: usize, entries_len: usize, scratch_len: usize, const Self = @This(); pub fn inspect(key_count: usize) Cuckoo2x2BuildError!Self { if (key_count > std.math.maxInt(u32)) return error.CapacityExceeded; const quarter = key_count / 4; const base = if (quarter <= 1) @as(usize, 1) else std.math.ceilPowerOfTwo(usize, quarter) catch return error.CapacityExceeded; var bucket_counts: [configuration_count]usize = undefined; inline for (0..configuration_count) |index| { const multiplier = @as(usize, 1) << index; const candidate = std.math.mul(usize, base, multiplier) catch return error.CapacityExceeded; const num_buckets = @max(candidate, minimum_bucket_count); if (num_buckets > std.math.maxInt(u32)) return error.CapacityExceeded; bucket_counts[index] = num_buckets; } const max_bucket_count = bucket_counts[configuration_count - 1]; const bucket_key_count = std.math.mul(usize, max_bucket_count, 2) catch return error.CapacityExceeded; const byte_count = std.math.add(usize, key_count, max_bucket_count) catch return error.CapacityExceeded; const byte_words = std.math.divCeil(usize, byte_count, @sizeOf(u32)) catch unreachable; const hash_and_keys = std.math.add(usize, key_count, bucket_key_count) catch return error.CapacityExceeded; const scratch_len = std.math.add(usize, hash_and_keys, byte_words) catch return error.CapacityExceeded; return .{ .key_count = key_count, .bucket_counts = bucket_counts, .max_bucket_count = max_bucket_count, .entries_len = max_bucket_count, .scratch_len = scratch_len, }; } pub fn build( self: Self, scratch: []u32, entries: []u32, keys: []const u32, ) Cuckoo2x2BuildError!Cuckoo2x2Data { if (keys.len != self.key_count) return error.PlanMismatch; if (scratch.len < self.scratch_len) return error.ScratchTooSmall; if (entries.len < self.entries_len) return error.EntriesTooSmall; const parts = self.sections(scratch); const engine = random.AesCtrEngine.initDeterministic(); const distinct_hash = hash_mod.WeakTwoMul.initSeed(&engine, 0); hash_mod.hashArray(tag.ScalableTag(u32), distinct_hash, keys, parts.hashes); std.mem.sort(u32, parts.hashes, {}, std.sort.asc(u32)); const sorted_hashes = parts.hashes; if (sorted_hashes.len > 1) { const previous_hashes = sorted_hashes[0 .. sorted_hashes.len - 1]; for (sorted_hashes[1..], previous_hashes) |current, previous| { if (current == previous) return error.DuplicateKey; } } for (self.bucket_counts, 0..) |num_buckets, config_idx| { for (0..max_attempts) |attempt_idx| { const hash_key: u32 = @truncate(engine.generate(attempt_idx, 0)); const config = Cuckoo2x2Config.init(num_buckets, hash_key); const hash1 = hash_mod.WeakTwoMul.initKey(hash_key); @memset(parts.counts[0..num_buckets], 0); @memset(entries[0..num_buckets], 0); hash_mod.hashArray(tag.ScalableTag(u32), hash1, keys, parts.hashes); if (!cuckooAssign( config, parts.hashes, parts.choices, parts.counts[0..num_buckets], parts.bucket_keys[0 .. num_buckets * 2], )) continue; populateEntries( config, parts.hashes, parts.choices, parts.counts[0..num_buckets], entries[0..num_buckets], ); var num_primary: u32 = 0; for (parts.choices) |choice| num_primary += @intFromBool(choice == 0); return .{ .config = config, .entries = entries[0..num_buckets], .config_idx = config_idx, .attempt_idx = attempt_idx, .num_primary = num_primary, .num_secondary = @as(u32, @intCast(keys.len)) - num_primary, }; } } return error.BuildFailed; } fn sections(self: Self, scratch: []u32) ScratchSections { const hashes = scratch[0..self.key_count]; const bucket_keys_begin = self.key_count; const bucket_keys_end = bucket_keys_begin + self.max_bucket_count * 2; const bucket_keys = scratch[bucket_keys_begin..bucket_keys_end]; const bytes = std.mem.sliceAsBytes(scratch[bucket_keys_end..self.scratch_len]); const choices = bytes[0..self.key_count]; const counts = bytes[self.key_count .. self.key_count + self.max_bucket_count]; return .{ .hashes = hashes, .bucket_keys = bucket_keys, .choices = choices, .counts = counts, }; }};Source: lib/simd/src/root.zig:615
zig
pub const Cuckoo2x2Plan = cuckoo2x2.Cuckoo2x2Plan;Complete caller list for Cuckoo2x2Plan.inspect
8 direct callers.
tiny.simd.cuckoo2x2.buildCuckoo2x2[function] atlib/simd/src/cuckoo2x2.zig:254tiny.simd.cuckoo2x2.cuckoo2x2EntriesLen[function] atlib/simd/src/cuckoo2x2.zig:250tiny.simd.cuckoo2x2.cuckoo2x2ScratchLen[function] atlib/simd/src/cuckoo2x2.zig:246lib.simd.src.cuckoo2x2.test_Highway_Cuckoo2x2_builds_and_queries_upstream_sizes[function] — test source atlib/simd/src/cuckoo2x2.zig:447in nearest public ownertiny.simd.cuckoo2x2lib.simd.src.cuckoo2x2.test_Highway_Cuckoo2x2_plans_enforce_capacities_and_distinct_keys[function] — test source atlib/simd/src/cuckoo2x2.zig:466in nearest public ownertiny.simd.cuckoo2x2lib.simd.src.cuckoo2x2.test_Highway_Cuckoo2x2_represents_the_empty_set[function] — test source atlib/simd/src/cuckoo2x2.zig:487in nearest public ownertiny.simd.cuckoo2x2lib.simd.src.cuckoo2x2.test_Highway_Cuckoo2x2_scalar_and_vector_membership_agree[function] — test source atlib/simd/src/cuckoo2x2.zig:371in nearest public ownertiny.simd.cuckoo2x2lib.simd.src.cuckoo2x2.test_Highway_Cuckoo2x2_single-worker_builder_oracle_matches_exactly[function] — test source atlib/simd/src/cuckoo2x2.zig:395in nearest public ownertiny.simd.cuckoo2x2
Audit
| Definitions | 3 |
|---|---|
| Public names | 6 |
| Members | 5 |
| Version | 26.7.0 |
| Revision | daab053ee433 |