Skip to content

Commit decea7c

Browse files
committed
remove quadratic hashing
1 parent ccb2ca1 commit decea7c

File tree

2 files changed

+10
-18
lines changed

2 files changed

+10
-18
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Perfect for command‑line flag tables, protocol constant look‑ups, compile‑
1414
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
1515
| Lookup | O(1) expected access. |
1616
| **Hash Algorithms** | Use any `fn([]const u8) u64` — the default is **xxHash64** from [`zighash`](https://github.com/galactixx/zighash). |
17-
| **Probing** | `Prober` enum: `Linear`, `Quadratic`, `DoubleHash`, `Bidirectional`, `Triangular`. |
17+
| **Probing** | `Prober` enum: `Linear`, `DoubleHash`, `Bidirectional`, `Triangular`. |
1818
| **Iterators** | Type‑driven `keys()`, `values()`, `items()`—all lazy and allocation‑free. |
1919
| **No Deps** | Pure Zig, no libc, no external libs. |
2020
| **Allocation** | No runtime allocations or pointer chasing. |
@@ -97,7 +97,6 @@ Calling this generic returns **a new struct type** with the following notable me
9797
Enum controlling collision resolution:
9898

9999
* `Linear``base + i`
100-
* `Quadratic``base + i + i²`
101100
* `DoubleHash``base + i * (h(key) | 1)`
102101
* `Bidirectional` – Alternates ±offsets
103102
* `Triangular``base + i * (i + 1) / 2`

src/comphash.zig

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ const zh = @import("zighash");
33

44
pub const Prober = enum {
55
Linear,
6-
Quadratic,
76
DoubleHash,
87
Bidirectional,
98
Triangular,
@@ -18,16 +17,10 @@ fn getProber(prober: Prober) fn (base: u64, i: u64, _: u64) u64 {
1817
return base +% i;
1918
}
2019
}.function,
21-
.Quadratic => struct {
22-
/// quadratic probing: next = base + (1 << i)
23-
pub fn function(base: u64, i: u64, _: u64) u64 {
24-
return base +% i +% (i *% i);
25-
}
26-
}.function,
2720
.DoubleHash => struct {
2821
/// doublehashing additionally using cityHash64
29-
pub fn function(base: u64, i: u64, sec: u64) u64 {
30-
return base +% i *% sec;
22+
pub fn function(base: u64, i: u64, step: u64) u64 {
23+
return base +% i *% step;
3124
}
3225
}.function,
3326
.Bidirectional => struct {
@@ -39,7 +32,7 @@ fn getProber(prober: Prober) fn (base: u64, i: u64, _: u64) u64 {
3932
}
4033
}.function,
4134
.Triangular => struct {
42-
/// triangular probing: next = base + (i*(i+1)/2)
35+
/// triangular probing: next = base + (i * (i + 1) / 2)
4336
pub fn function(base: u64, i: u64, _: u64) u64 {
4437
const offset = (i *% (i +% 1)) / 2;
4538
return base +% offset;
@@ -86,7 +79,7 @@ pub fn ComptimeHashMap(
8679
eqler: fn ([]const u8, []const u8) bool,
8780
mapTable: []const KVPair,
8881
mapItems: []const Pair,
89-
mapCap: usize,
82+
mapCap: u64,
9083

9184
/// iterator type generator: yields type-specific iterators.
9285
fn Iterator(comptime R: type) type {
@@ -139,7 +132,9 @@ pub fn ComptimeHashMap(
139132
@compileError("no key-value pairs supplied");
140133
}
141134

142-
const M = try std.math.ceilPowerOfTwo(usize, kvPairs.len * 2);
135+
const lenFloat: f64 = @floatFromInt(kvPairs.len);
136+
const initCap: u64 = @bitCast(lenFloat / 0.7);
137+
const M = try std.math.ceilPowerOfTwo(u64, initCap);
143138

144139
// check to ensure that there are no duplicates keys
145140
for (kvPairs, 0..) |kv1, i| {
@@ -226,7 +221,7 @@ pub fn ComptimeHashMap(
226221
}
227222

228223
/// return the underlying table capacity.
229-
pub fn capacity(self: Self) usize {
224+
pub fn capacity(self: Self) u64 {
230225
return self.mapCap;
231226
}
232227

@@ -294,7 +289,7 @@ test "probe strategies consistency" {
294289
.{ "x", 100 },
295290
.{ "y", 200 },
296291
};
297-
const QMap = ComptimeHashMap(u32, null, Prober.Quadratic, null);
292+
const QMap = ComptimeHashMap(u32, null, Prober.Bidirectional, null);
298293
const mapQ = QMap.init(kv);
299294
try std.testing.expect(mapQ.get("x") orelse 0 == 100);
300295
try std.testing.expect(mapQ.get("y") orelse 0 == 200);
@@ -365,8 +360,6 @@ test "capacity is power-of-two and ≥ 2×length" {
365360
};
366361
const Map = ComptimeHashMap(u32, null, null, null);
367362
const map = Map.init(kv);
368-
369-
try std.testing.expect(map.capacity() >= kv.len * 2);
370363
try std.testing.expect((map.capacity() & (map.capacity() - 1)) == 0);
371364
}
372365

0 commit comments

Comments
 (0)