From 410be6995e4f0e7b41174f7c0bb4bf828b758871 Mon Sep 17 00:00:00 2001 From: Marc Tiehuis Date: Sat, 2 Sep 2023 15:04:05 +1200 Subject: [PATCH] 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). --- lib/std/hash/cityhash.zig | 26 +++++++++++++++++++------ lib/std/hash/murmur.zig | 36 ++++++++++++++++++++++++++++++++--- lib/std/hash/verify.zig | 2 +- lib/std/hash/wyhash.zig | 20 +++++++++++++++++--- lib/std/hash/xxhash.zig | 40 +++++++++++++++++++++++++++++++++++---- 5 files changed, 107 insertions(+), 17 deletions(-) diff --git a/lib/std/hash/cityhash.zig b/lib/std/hash/cityhash.zig index 464e876b4a..2fab089095 100644 --- a/lib/std/hash/cityhash.zig +++ b/lib/std/hash/cityhash.zig @@ -350,13 +350,27 @@ fn CityHash32hashIgnoreSeed(str: []const u8, seed: u32) u32 { const verify = @import("verify.zig"); test "cityhash32" { - // Note: SMHasher doesn't provide a 32bit version of the algorithm. - // Note: The implementation was verified against the Google Abseil version. - try std.testing.expectEqual(verify.smhasher(CityHash32hashIgnoreSeed), 0x68254F81); + const Test = struct { + fn do() !void { + // SMHasher doesn't provide a 32bit version of the algorithm. + // The implementation was verified against the Google Abseil version. + try std.testing.expectEqual(verify.smhasher(CityHash32hashIgnoreSeed), 0x68254F81); + } + }; + try Test.do(); + @setEvalBranchQuota(75000); + try comptime Test.do(); } test "cityhash64" { - // Note: This is not compliant with the SMHasher implementation of CityHash64! - // Note: The implementation was verified against the Google Abseil version. - try std.testing.expectEqual(verify.smhasher(CityHash64.hashWithSeed), 0x5FABC5C5); + const Test = struct { + fn do() !void { + // This is not compliant with the SMHasher implementation of CityHash64! + // The implementation was verified against the Google Abseil version. + try std.testing.expectEqual(verify.smhasher(CityHash64.hashWithSeed), 0x5FABC5C5); + } + }; + try Test.do(); + @setEvalBranchQuota(75000); + try comptime Test.do(); } diff --git a/lib/std/hash/murmur.zig b/lib/std/hash/murmur.zig index b9b2ddeca2..80496be24f 100644 --- a/lib/std/hash/murmur.zig +++ b/lib/std/hash/murmur.zig @@ -282,7 +282,6 @@ pub const Murmur3_32 = struct { const verify = @import("verify.zig"); test "murmur2_32" { - try testing.expectEqual(verify.smhasher(Murmur2_32.hashWithSeed), 0x27864C1E); var v0: u32 = 0x12345678; var v1: u64 = 0x1234567812345678; var v0le: u32 = v0; @@ -295,8 +294,18 @@ test "murmur2_32" { try testing.expectEqual(Murmur2_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_32.hashUint64(v1)); } +test "murmur2_32 smhasher" { + const Test = struct { + fn do() !void { + try testing.expectEqual(verify.smhasher(Murmur2_32.hashWithSeed), 0x27864C1E); + } + }; + try Test.do(); + @setEvalBranchQuota(30000); + try comptime Test.do(); +} + test "murmur2_64" { - try std.testing.expectEqual(verify.smhasher(Murmur2_64.hashWithSeed), 0x1F0D3804); var v0: u32 = 0x12345678; var v1: u64 = 0x1234567812345678; var v0le: u32 = v0; @@ -309,8 +318,18 @@ test "murmur2_64" { try testing.expectEqual(Murmur2_64.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur2_64.hashUint64(v1)); } +test "mumur2_64 smhasher" { + const Test = struct { + fn do() !void { + try std.testing.expectEqual(verify.smhasher(Murmur2_64.hashWithSeed), 0x1F0D3804); + } + }; + try Test.do(); + @setEvalBranchQuota(30000); + try comptime Test.do(); +} + test "murmur3_32" { - try std.testing.expectEqual(verify.smhasher(Murmur3_32.hashWithSeed), 0xB0F57EE3); var v0: u32 = 0x12345678; var v1: u64 = 0x1234567812345678; var v0le: u32 = v0; @@ -322,3 +341,14 @@ test "murmur3_32" { try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v0le))[0..4]), Murmur3_32.hashUint32(v0)); try testing.expectEqual(Murmur3_32.hash(@as([*]u8, @ptrCast(&v1le))[0..8]), Murmur3_32.hashUint64(v1)); } + +test "mumur3_32 smhasher" { + const Test = struct { + fn do() !void { + try std.testing.expectEqual(verify.smhasher(Murmur3_32.hashWithSeed), 0xB0F57EE3); + } + }; + try Test.do(); + @setEvalBranchQuota(30000); + try comptime Test.do(); +} diff --git a/lib/std/hash/verify.zig b/lib/std/hash/verify.zig index 5d853fee28..1a20d8d1a3 100644 --- a/lib/std/hash/verify.zig +++ b/lib/std/hash/verify.zig @@ -22,7 +22,7 @@ fn initMaybeSeed(comptime Hash: anytype, seed: anytype) Hash { } } -// Returns a verification code, the same as user by SMHasher. +// Returns a verification code, the same as used by SMHasher. // // Hash keys of the form {0}, {0,1}, {0,1,2}... up to N=255, using 256-N as seed. // First four-bytes of the hash, interpreted as little-endian is the verification code. diff --git a/lib/std/hash/wyhash.zig b/lib/std/hash/wyhash.zig index 6ceaba696a..91cdf5007f 100644 --- a/lib/std/hash/wyhash.zig +++ b/lib/std/hash/wyhash.zig @@ -66,7 +66,7 @@ pub const Wyhash = struct { } pub fn final(self: *Wyhash) u64 { - var input = self.buf[0..self.buf_len]; + var input: []const u8 = self.buf[0..self.buf_len]; var newSelf = self.shallowCopy(); // ensure idempotency if (self.total_len <= 16) { @@ -231,11 +231,25 @@ test "test vectors at comptime" { } test "smhasher" { - try expectEqual(verify.smhasher(Wyhash.hash), 0xBD5E840C); + const Test = struct { + fn do() !void { + try expectEqual(verify.smhasher(Wyhash.hash), 0xBD5E840C); + } + }; + try Test.do(); + @setEvalBranchQuota(50000); + try comptime Test.do(); } test "iterative api" { - try verify.iterativeApi(Wyhash); + const Test = struct { + fn do() !void { + try verify.iterativeApi(Wyhash); + } + }; + try Test.do(); + @setEvalBranchQuota(50000); + try comptime Test.do(); } test "iterative maintains last sixteen" { diff --git a/lib/std/hash/xxhash.zig b/lib/std/hash/xxhash.zig index f267f72e6a..1f44183b6c 100644 --- a/lib/std/hash/xxhash.zig +++ b/lib/std/hash/xxhash.zig @@ -457,12 +457,28 @@ test "xxhash64" { try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0xcfe1f278fa89835c); try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0xaaa46907d3047814); try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0xe04a477f19ee145d); +} - try expectEqual(verify.smhasher(H.hash), 0x024B7CF4); +test "xxhash64 smhasher" { + const Test = struct { + fn do() !void { + try expectEqual(verify.smhasher(XxHash64.hash), 0x024B7CF4); + } + }; + try Test.do(); + @setEvalBranchQuota(75000); + comptime try Test.do(); } test "xxhash64 iterative api" { - try verify.iterativeApi(XxHash64); + const Test = struct { + fn do() !void { + try verify.iterativeApi(XxHash64); + } + }; + try Test.do(); + @setEvalBranchQuota(30000); + comptime try Test.do(); } test "xxhash32" { @@ -475,10 +491,26 @@ test "xxhash32" { try testExpect(H, 0, "abcdefghijklmnopqrstuvwxyz", 0x63a14d5f); try testExpect(H, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x9c285e64); try testExpect(H, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0x9c05f475); +} - try expectEqual(verify.smhasher(H.hash), 0xBA88B743); +test "xxhash32 smhasher" { + const Test = struct { + fn do() !void { + try expectEqual(verify.smhasher(XxHash32.hash), 0xBA88B743); + } + }; + try Test.do(); + @setEvalBranchQuota(75000); + comptime try Test.do(); } test "xxhash32 iterative api" { - try verify.iterativeApi(XxHash32); + const Test = struct { + fn do() !void { + try verify.iterativeApi(XxHash32); + } + }; + try Test.do(); + @setEvalBranchQuota(30000); + comptime try Test.do(); }