authorgravatar for andersfr@gmail.comandersfr <andersfr@gmail.com> 2019-07-06 22:41:38+02:00
committergravatar for andersfr@gmail.comandersfr <andersfr@gmail.com> 2019-07-13 13:59:15+02:00
log0619b525b9100e95ab293792bcaa3c565e08a979
treed203054de69bf35e6f715a00de144186954db4f2
parentdfbe65e8cd62625c5ef783aee01056bac678ecf1

Better testing and bugfix in hashUint* functions


1 files changed, 37 insertions(+), 14 deletions(-)

std/hash/murmur.zig+37-14
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const testing = std.testing;
34
4const default_seed: u32 = 0xc70f6907;5const default_seed: u32 = 0xc70f6907;
56
...@@ -68,10 +69,10 @@ pub const Murmur2_32 = struct {...@@ -68,10 +69,10 @@ pub const Murmur2_32 = struct {
6869
69 pub fn hashUint64WithSeed(v: u64, seed: u32) u32 {70 pub fn hashUint64WithSeed(v: u64, seed: u32) u32 {
70 const m: u32 = 0x5bd1e995;71 const m: u32 = 0x5bd1e995;
71 const len: u32 = 4;72 const len: u32 = 8;
72 var h1: u32 = seed ^ len;73 var h1: u32 = seed ^ len;
73 var k1: u32 = undefined;74 var k1: u32 = undefined;
74 k1 = @intCast(u32, v) *% m;75 k1 = @intCast(u32, v & 0xffffffff) *% m;
75 k1 ^= k1 >> 24;76 k1 ^= k1 >> 24;
76 k1 *%= m;77 k1 *%= m;
77 h1 *%= m;78 h1 *%= m;
...@@ -133,10 +134,7 @@ pub const Murmur2_64 = struct {...@@ -133,10 +134,7 @@ pub const Murmur2_64 = struct {
133 const m: u64 = 0xc6a4a7935bd1e995;134 const m: u64 = 0xc6a4a7935bd1e995;
134 const len: u64 = 4;135 const len: u64 = 4;
135 var h1: u64 = seed ^ (len *% m);136 var h1: u64 = seed ^ (len *% m);
136 var k1: u64 = undefined;137 var k1: u64 = v;
137 k1 = v *% m;
138 k1 ^= k1 >> 47;
139 k1 *%= m;
140 h1 ^= k1;138 h1 ^= k1;
141 h1 *%= m;139 h1 *%= m;
142 h1 ^= h1 >> 47;140 h1 ^= h1 >> 47;
...@@ -154,12 +152,7 @@ pub const Murmur2_64 = struct {...@@ -154,12 +152,7 @@ pub const Murmur2_64 = struct {
154 const len: u64 = 8;152 const len: u64 = 8;
155 var h1: u64 = seed ^ (len *% m);153 var h1: u64 = seed ^ (len *% m);
156 var k1: u64 = undefined;154 var k1: u64 = undefined;
157 k1 = @intCast(u32, v) *% m;155 k1 = v *% m;
158 k1 ^= k1 >> 47;
159 k1 *%= m;
160 h1 ^= k1;
161 h1 *%= m;
162 k1 = @intCast(u32, v >> 32) *% m;
163 k1 ^= k1 >> 47;156 k1 ^= k1 >> 47;
164 k1 *%= m;157 k1 *%= m;
165 h1 ^= k1;158 h1 ^= k1;
...@@ -262,7 +255,7 @@ pub const Murmur3_32 = struct {...@@ -262,7 +255,7 @@ pub const Murmur3_32 = struct {
262 const len: u32 = 8;255 const len: u32 = 8;
263 var h1: u32 = seed;256 var h1: u32 = seed;
264 var k1: u32 = undefined;257 var k1: u32 = undefined;
265 k1 = @intCast(u32, v) *% c1;258 k1 = @intCast(u32, v & 0xffffffff) *% c1;
266 k1 = rotl32(k1, 15);259 k1 = rotl32(k1, 15);
267 k1 *%= c2;260 k1 *%= c2;
268 h1 ^= k1;261 h1 ^= k1;
...@@ -310,13 +303,43 @@ fn SMHasherTest(comptime hash_fn: var, comptime hashbits: u32) u32 {...@@ -310,13 +303,43 @@ fn SMHasherTest(comptime hash_fn: var, comptime hashbits: u32) u32 {
310}303}
311304
312test "murmur2_32" {305test "murmur2_32" {
313 std.testing.expectEqual(SMHasherTest(Murmur2_32.hashWithSeed, 32), 0x27864C1E);306 testing.expectEqual(SMHasherTest(Murmur2_32.hashWithSeed, 32), 0x27864C1E);
307 var v0: u32 = 0x12345678;
308 var v1: u64 = 0x1234567812345678;
309 var v0le: u32 = v0;
310 var v1le: u64 = v1;
311 if (builtin.endian == builtin.Endian.Big) {
312 v0le = @byteSwap(u32, v0le);
313 v1le = @byteSwap(u64, v1le);
314 }
315 testing.expectEqual(Murmur2_32.hash(@ptrCast([*]u8, &v0le)[0..4]), Murmur2_32.hashUint32(v0));
316 testing.expectEqual(Murmur2_32.hash(@ptrCast([*]u8, &v1le)[0..8]), Murmur2_32.hashUint64(v1));
314}317}
315318
316test "murmur2_64" {319test "murmur2_64" {
317 std.testing.expectEqual(SMHasherTest(Murmur2_64.hashWithSeed, 64), 0x1F0D3804);320 std.testing.expectEqual(SMHasherTest(Murmur2_64.hashWithSeed, 64), 0x1F0D3804);
321 var v0: u32 = 0x12345678;
322 var v1: u64 = 0x1234567812345678;
323 var v0le: u32 = v0;
324 var v1le: u64 = v1;
325 if (builtin.endian == builtin.Endian.Big) {
326 v0le = @byteSwap(u32, v0le);
327 v1le = @byteSwap(u64, v1le);
328 }
329 testing.expectEqual(Murmur2_64.hash(@ptrCast([*]u8, &v0le)[0..4]), Murmur2_64.hashUint32(v0));
330 testing.expectEqual(Murmur2_64.hash(@ptrCast([*]u8, &v1le)[0..8]), Murmur2_64.hashUint64(v1));
318}331}
319332
320test "murmur3_32" {333test "murmur3_32" {
321 std.testing.expectEqual(SMHasherTest(Murmur3_32.hashWithSeed, 32), 0xB0F57EE3);334 std.testing.expectEqual(SMHasherTest(Murmur3_32.hashWithSeed, 32), 0xB0F57EE3);
335 var v0: u32 = 0x12345678;
336 var v1: u64 = 0x1234567812345678;
337 var v0le: u32 = v0;
338 var v1le: u64 = v1;
339 if (builtin.endian == builtin.Endian.Big) {
340 v0le = @byteSwap(u32, v0le);
341 v1le = @byteSwap(u64, v1le);
342 }
343 testing.expectEqual(Murmur3_32.hash(@ptrCast([*]u8, &v0le)[0..4]), Murmur3_32.hashUint32(v0));
344 testing.expectEqual(Murmur3_32.hash(@ptrCast([*]u8, &v1le)[0..8]), Murmur3_32.hashUint64(v1));
322}345}