| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| | 3 | const testing = std.testing; |
| 3 | | 4 | |
| 4 | const default_seed: u32 = 0xc70f6907; | 5 | const default_seed: u32 = 0xc70f6907; |
| 5 | | 6 | |
| ... | @@ -68,10 +69,10 @@ pub const Murmur2_32 = struct { | ... | @@ -68,10 +69,10 @@ pub const Murmur2_32 = struct { |
| 68 | | 69 | |
| 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 | } |
| 311 | | 304 | |
| 312 | test "murmur2_32" { | 305 | test "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 | } |
| 315 | | 318 | |
| 316 | test "murmur2_64" { | 319 | test "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 | } |
| 319 | | 332 | |
| 320 | test "murmur3_32" { | 333 | test "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 | } |