structstd.hash.cityhash.CityHash32[src]

Functions

Functionhash[src]

pub fn hash(str: []const u8) u32

Parameters

str: []const u8

Source Code

Source code
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;
}

Source Code

Source code
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;
    }
}