| 1 | // Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | // |
| 5 | // this is an implementation of wyhash v4 |
| 6 | // from https://github.com/wangyi-fudan/wyhash |
| 7 | // |
| 8 | // TODO: use u128 once implemented |
| 9 | // currently the C version performs slightly better |
| 10 | // because it uses 128 bit int when available and |
| 11 | // branch prediction hints. the C version will be |
| 12 | // removed once the performance is matched. |
| 13 | // you can test performance by running: |
| 14 | // `v run cmd/tools/bench/wyhash.v` |
| 15 | // try running with and without the `-prod` flag |
| 16 | module hash |
| 17 | |
| 18 | const wyp0 = u64(0x2d358dccaa6c78a5) |
| 19 | const wyp1 = u64(0x8bb84b93962eacc9) |
| 20 | const wyp2 = u64(0x4b33a62ed433d4a3) |
| 21 | const wyp3 = u64(0x4d5a2da51de1aa47) |
| 22 | |
| 23 | // wymum returns a hash by performing multiply and mix on `a` and `b`. |
| 24 | @[ignore_overflow; inline] |
| 25 | pub fn wymum(a u64, b u64) u64 { |
| 26 | /* |
| 27 | mut r := u128(a) |
| 28 | r = r*b |
| 29 | return (r>>64)^r |
| 30 | */ |
| 31 | mask32 := u32(4294967295) |
| 32 | x0 := a & mask32 |
| 33 | x1 := a >> 32 |
| 34 | y0 := b & mask32 |
| 35 | y1 := b >> 32 |
| 36 | w0 := x0 * y0 |
| 37 | t := x1 * y0 + (w0 >> 32) |
| 38 | mut w1 := t & mask32 |
| 39 | w2 := t >> 32 |
| 40 | w1 += x0 * y1 |
| 41 | hi := x1 * y1 + w2 + (w1 >> 32) |
| 42 | lo := a * b |
| 43 | return hi ^ lo |
| 44 | } |
| 45 | |