authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2023-09-02 15:04:05+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2023-09-02 16:58:03+12:00
log410be6995e4f0e7b41174f7c0bb4bf828b758871
tree2b252eb8529bb7cec032e58e621f34157438ef28
parent1c148f161905469b0ad5cf4de801cf287c491174

std/hash: perform iterative + smhasher tests at comptime

Need to confirm how these fare on CI as per previous comments left which stated OOM (on stage-1).

5 files changed, 107 insertions(+), 17 deletions(-)

lib/std/hash/cityhash.zig+20-6
...@@ -350,13 +350,27 @@ fn CityHash32hashIgnoreSeed(str: []const u8, seed: u32) u32 {...@@ -350,13 +350,27 @@ fn CityHash32hashIgnoreSeed(str: []const u8, seed: u32) u32 {
350const verify = @import("verify.zig");350const verify = @import("verify.zig");
351351
352test "cityhash32" {352test "cityhash32" {
353 // Note: SMHasher doesn't provide a 32bit version of the algorithm.353 const Test = struct {
354 // Note: The implementation was verified against the Google Abseil version.354 fn do() !void {
355 try std.testing.expectEqual(verify.smhasher(CityHash32hashIgnoreSeed), 0x68254F81);355 // SMHasher doesn't provide a 32bit version of the algorithm.
356 // The implementation was verified against the Google Abseil version.
357 try std.testing.expectEqual(verify.smhasher(CityHash32hashIgnoreSeed), 0x68254F81);
358 }
359 };
360 try Test.do();
361 @setEvalBranchQuota(75000);
362 try comptime Test.do();
356}363}
357364
358test "cityhash64" {365test "cityhash64" {
359 // Note: This is not compliant with the SMHasher implementation of CityHash64!366 const Test = struct {
360 // Note: The implementation was verified against the Google Abseil version.367 fn do() !void {
361 try std.testing.expectEqual(verify.smhasher(CityHash64.hashWithSeed), 0x5FABC5C5);368 // This is not compliant with the SMHasher implementation of CityHash64!
369 // The implementation was verified against the Google Abseil version.
370 try std.testing.expectEqual(verify.smhasher(CityHash64.hashWithSeed), 0x5FABC5C5);
371 }
372 };
373 try Test.do();
374 @setEvalBranchQuota(75000);
375 try comptime Test.do();
362}376}
lib/std/hash/murmur.zig+33-3
...@@ -282,7 +282,6 @@ pub const Murmur3_32 = struct {...@@ -282,7 +282,6 @@ pub const Murmur3_32 = struct {
282const verify = @import("verify.zig");282const verify = @import("verify.zig");
283283
284test "murmur2_32" {284test "murmur2_32" {
285 try testing.expectEqual(verify.smhasher(Murmur2_32.hashWithSeed), 0x27864C1E);
286 var v0: u32 = 0x12345678;285 var v0: u32 = 0x12345678;
287 var v1: u64 = 0x1234567812345678;286 var v1: u64 = 0x1234567812345678;
288 var v0le: u32 = v0;287 var v0le: u32 = v0;
...@@ -295,8 +294,18 @@ test "murmur2_32" {...@@ -295,8 +294,18 @@ test "murmur2_32" {
295 try testing.expectEqual(Murmur2_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_32.hashUint64(v1));294 try testing.expectEqual(Murmur2_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_32.hashUint64(v1));
296}295}
297296
297test "murmur2_32 smhasher" {
298 const Test = struct {
299 fn do() !void {
300 try testing.expectEqual(verify.smhasher(Murmur2_32.hashWithSeed), 0x27864C1E);
301 }
302 };
303 try Test.do();
304 @setEvalBranchQuota(30000);
305 try comptime Test.do();
306}
307
298test "murmur2_64" {308test "murmur2_64" {
299 try std.testing.expectEqual(verify.smhasher(Murmur2_64.hashWithSeed), 0x1F0D3804);
300 var v0: u32 = 0x12345678;309 var v0: u32 = 0x12345678;
301 var v1: u64 = 0x1234567812345678;310 var v1: u64 = 0x1234567812345678;
302 var v0le: u32 = v0;311 var v0le: u32 = v0;
...@@ -309,8 +318,18 @@ test "murmur2_64" {...@@ -309,8 +318,18 @@ test "murmur2_64" {
309 try testing.expectEqual(Murmur2_64.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_64.hashUint64(v1));318 try testing.expectEqual(Murmur2_64.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_64.hashUint64(v1));
310}319}
311320
321test "mumur2_64 smhasher" {
322 const Test = struct {
323 fn do() !void {
324 try std.testing.expectEqual(verify.smhasher(Murmur2_64.hashWithSeed), 0x1F0D3804);
325 }
326 };
327 try Test.do();
328 @setEvalBranchQuota(30000);
329 try comptime Test.do();
330}
331
312test "murmur3_32" {332test "murmur3_32" {
313 try std.testing.expectEqual(verify.smhasher(Murmur3_32.hashWithSeed), 0xB0F57EE3);
314 var v0: u32 = 0x12345678;333 var v0: u32 = 0x12345678;
315 var v1: u64 = 0x1234567812345678;334 var v1: u64 = 0x1234567812345678;
316 var v0le: u32 = v0;335 var v0le: u32 = v0;
...@@ -322,3 +341,14 @@ test "murmur3_32" {...@@ -322,3 +341,14 @@ test "murmur3_32" {
322 try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v0le))[0..4]), Murmur3_32.hashUint32(v0));341 try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v0le))[0..4]), Murmur3_32.hashUint32(v0));
323 try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur3_32.hashUint64(v1));342 try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur3_32.hashUint64(v1));
324}343}
344
345test "mumur3_32 smhasher" {
346 const Test = struct {
347 fn do() !void {
348 try std.testing.expectEqual(verify.smhasher(Murmur3_32.hashWithSeed), 0xB0F57EE3);
349 }
350 };
351 try Test.do();
352 @setEvalBranchQuota(30000);
353 try comptime Test.do();
354}
lib/std/hash/verify.zig+1-1
...@@ -22,7 +22,7 @@ fn initMaybeSeed(comptime Hash: anytype, seed: anytype) Hash {...@@ -22,7 +22,7 @@ fn initMaybeSeed(comptime Hash: anytype, seed: anytype) Hash {
22 }22 }
23}23}
2424
25// Returns a verification code, the same as user by SMHasher.25// Returns a verification code, the same as used by SMHasher.
26//26//
27// Hash keys of the form {0}, {0,1}, {0,1,2}... up to N=255, using 256-N as seed.27// Hash keys of the form {0}, {0,1}, {0,1,2}... up to N=255, using 256-N as seed.
28// First four-bytes of the hash, interpreted as little-endian is the verification code.28// First four-bytes of the hash, interpreted as little-endian is the verification code.
lib/std/hash/wyhash.zig+17-3
...@@ -66,7 +66,7 @@ pub const Wyhash = struct {...@@ -66,7 +66,7 @@ pub const Wyhash = struct {
66 }66 }
6767
68 pub fn final(self: *Wyhash) u64 {68 pub fn final(self: *Wyhash) u64 {
69 var input = self.buf[0..self.buf_len];69 var input: []const u8 = self.buf[0..self.buf_len];
70 var newSelf = self.shallowCopy(); // ensure idempotency70 var newSelf = self.shallowCopy(); // ensure idempotency
7171
72 if (self.total_len <= 16) {72 if (self.total_len <= 16) {
...@@ -231,11 +231,25 @@ test "test vectors at comptime" {...@@ -231,11 +231,25 @@ test "test vectors at comptime" {
231}231}
232232
233test "smhasher" {233test "smhasher" {
234 try expectEqual(verify.smhasher(Wyhash.hash), 0xBD5E840C);234 const Test = struct {
235 fn do() !void {
236 try expectEqual(verify.smhasher(Wyhash.hash), 0xBD5E840C);
237 }
238 };
239 try Test.do();
240 @setEvalBranchQuota(50000);
241 try comptime Test.do();
235}242}
236243
237test "iterative api" {244test "iterative api" {
238 try verify.iterativeApi(Wyhash);245 const Test = struct {
246 fn do() !void {
247 try verify.iterativeApi(Wyhash);
248 }
249 };
250 try Test.do();
251 @setEvalBranchQuota(50000);
252 try comptime Test.do();
239}253}
240254
241test "iterative maintains last sixteen" {255test "iterative maintains last sixteen" {
lib/std/hash/xxhash.zig+36-4
...@@ -457,12 +457,28 @@ test "xxhash64" {...@@ -457,12 +457,28 @@ test "xxhash64" {
457 try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0xcfe1f278fa89835c);457 try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0xcfe1f278fa89835c);
458 try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0xaaa46907d3047814);458 try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0xaaa46907d3047814);
459 try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0xe04a477f19ee145d);459 try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0xe04a477f19ee145d);
460}
460461
461 try expectEqual(verify.smhasher(H.hash), 0x024B7CF4);462test "xxhash64 smhasher" {
463 const Test = struct {
464 fn do() !void {
465 try expectEqual(verify.smhasher(XxHash64.hash), 0x024B7CF4);
466 }
467 };
468 try Test.do();
469 @setEvalBranchQuota(75000);
470 comptime try Test.do();
462}471}
463472
464test "xxhash64 iterative api" {473test "xxhash64 iterative api" {
465 try verify.iterativeApi(XxHash64);474 const Test = struct {
475 fn do() !void {
476 try verify.iterativeApi(XxHash64);
477 }
478 };
479 try Test.do();
480 @setEvalBranchQuota(30000);
481 comptime try Test.do();
466}482}
467483
468test "xxhash32" {484test "xxhash32" {
...@@ -475,10 +491,26 @@ test "xxhash32" {...@@ -475,10 +491,26 @@ test "xxhash32" {
475 try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0x63a14d5f);491 try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0x63a14d5f);
476 try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x9c285e64);492 try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x9c285e64);
477 try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0x9c05f475);493 try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0x9c05f475);
494}
478495
479 try expectEqual(verify.smhasher(H.hash), 0xBA88B743);496test "xxhash32 smhasher" {
497 const Test = struct {
498 fn do() !void {
499 try expectEqual(verify.smhasher(XxHash32.hash), 0xBA88B743);
500 }
501 };
502 try Test.do();
503 @setEvalBranchQuota(75000);
504 comptime try Test.do();
480}505}
481506
482test "xxhash32 iterative api" {507test "xxhash32 iterative api" {
483 try verify.iterativeApi(XxHash32);508 const Test = struct {
509 fn do() !void {
510 try verify.iterativeApi(XxHash32);
511 }
512 };
513 try Test.do();
514 @setEvalBranchQuota(30000);
515 comptime try Test.do();
484}516}