struct CityHash32 [src]

Alias for std.hash.cityhash.CityHash32

Members

Source

pub const CityHash32 = struct { const Self = @This(); // Magic numbers for 32-bit hashing. Copied from Murmur3. const c1: u32 = 0xcc9e2d51; const c2: u32 = 0x1b873593; // A 32-bit to 32-bit integer hash copied from Murmur3. fn fmix(h: u32) u32 { var h1: u32 = h; h1 ^= h1 >> 16; h1 *%= 0x85ebca6b; h1 ^= h1 >> 13; h1 *%= 0xc2b2ae35; h1 ^= h1 >> 16; return h1; } // Rotate right helper fn rotr32(x: u32, comptime r: u32) u32 { return (x >> r) | (x << (32 - r)); } // Helper from Murmur3 for combining two 32-bit values. fn mur(a: u32, h: u32) u32 { var a1: u32 = a; var h1: u32 = h; a1 *%= c1; a1 = rotr32(a1, 17); a1 *%= c2; h1 ^= a1; h1 = rotr32(h1, 19); return h1 *% 5 +% 0xe6546b64; } fn hash32Len0To4(str: []const u8) u32 { const len: u32 = @as(u32, @truncate(str.len)); var b: u32 = 0; var c: u32 = 9; for (str) |v| { b = b *% c1 +% @as(u32, @bitCast(@as(i32, @intCast(@as(i8, @bitCast(v)))))); c ^= b; } return fmix(mur(b, mur(len, c))); } fn hash32Len5To12(str: []const u8) u32 { var a: u32 = @as(u32, @truncate(str.len)); var b: u32 = a *% 5; var c: u32 = 9; const d: u32 = b; a +%= fetch32(str.ptr, 0); b +%= fetch32(str.ptr, str.len - 4); c +%= fetch32(str.ptr, (str.len >> 1) & 4); return fmix(mur(c, mur(b, mur(a, d)))); } fn hash32Len13To24(str: []const u8) u32 { const len: u32 = @as(u32, @truncate(str.len)); const a: u32 = fetch32(str.ptr, (str.len >> 1) - 4); const b: u32 = fetch32(str.ptr, 4); const c: u32 = fetch32(str.ptr, str.len - 8); const d: u32 = fetch32(str.ptr, str.len >> 1); const e: u32 = fetch32(str.ptr, 0); const f: u32 = fetch32(str.ptr, str.len - 4); return fmix(mur(f, mur(e, mur(d, mur(c, mur(b, mur(a, len))))))); } pub fn hash(str: []const u8) u32 { if (str.len <= 24) { if (str.len <= 4) { return hash32Len0To4(str); } else { if (str.len <= 12) return hash32Len5To12(str); return hash32Len13To24(str); } } const len: u32 = @as(u32, @truncate(str.len)); var h: u32 = len; var g: u32 = c1 *% len; var f: u32 = g; const a0: u32 = rotr32(fetch32(str.ptr, str.len - 4) *% c1, 17) *% c2; const a1: u32 = rotr32(fetch32(str.ptr, str.len - 8) *% c1, 17) *% c2; const a2: u32 = rotr32(fetch32(str.ptr, str.len - 16) *% c1, 17) *% c2; const a3: u32 = rotr32(fetch32(str.ptr, str.len - 12) *% c1, 17) *% c2; const a4: u32 = rotr32(fetch32(str.ptr, str.len - 20) *% c1, 17) *% c2; h ^= a0; h = rotr32(h, 19); h = h *% 5 +% 0xe6546b64; h ^= a2; h = rotr32(h, 19); h = h *% 5 +% 0xe6546b64; g ^= a1; g = rotr32(g, 19); g = g *% 5 +% 0xe6546b64; g ^= a3; g = rotr32(g, 19); g = g *% 5 +% 0xe6546b64; f +%= a4; f = rotr32(f, 19); f = f *% 5 +% 0xe6546b64; var iters = (str.len - 1) / 20; var ptr = str.ptr; while (iters != 0) : (iters -= 1) { const b0: u32 = rotr32(fetch32(ptr, 0) *% c1, 17) *% c2; const b1: u32 = fetch32(ptr, 4); const b2: u32 = rotr32(fetch32(ptr, 8) *% c1, 17) *% c2; const b3: u32 = rotr32(fetch32(ptr, 12) *% c1, 17) *% c2; const b4: u32 = fetch32(ptr, 16); h ^= b0; h = rotr32(h, 18); h = h *% 5 +% 0xe6546b64; f +%= b1; f = rotr32(f, 19); f = f *% c1; g +%= b2; g = rotr32(g, 18); g = g *% 5 +% 0xe6546b64; h ^= b3 +% b1; h = rotr32(h, 19); h = h *% 5 +% 0xe6546b64; g ^= b4; g = @byteSwap(g) *% 5; h +%= b4 *% 5; h = @byteSwap(h); f +%= b0; const t: u32 = h; h = f; f = g; g = t; ptr = offsetPtr(ptr, 20); } g = rotr32(g, 11) *% c1; g = rotr32(g, 17) *% c1; f = rotr32(f, 11) *% c1; f = rotr32(f, 17) *% c1; h = rotr32(h +% g, 19); h = h *% 5 +% 0xe6546b64; h = rotr32(h, 17) *% c1; h = rotr32(h +% f, 19); h = h *% 5 +% 0xe6546b64; h = rotr32(h, 17) *% c1; return h; } }