import { HEADER_SIZE as HEADER_SIZE_STR } from "./string"; // FNV-1a 32-bit as a starting point, see: http://isthe.com/chongo/tech/comp/fnv/ const FNV_OFFSET: u32 = 2166136261; const FNV_PRIME: u32 = 16777619; export function hash(key: T): u32 { var hash: u32 = FNV_OFFSET; if (isString(key)) { for (let i: usize = 0, k: usize = key.length << 1; i < k; ++i) { hash = (hash ^ load(changetype(key) + i, HEADER_SIZE_STR)) * FNV_PRIME; } } else if (isFloat(key)) { if (sizeof() == 4) { // f32 let u = reinterpret(key); hash = (hash ^ ( u & 0xff)) * FNV_PRIME; hash = (hash ^ ((u >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((u >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( u >>> 24 )) * FNV_PRIME; } else if (sizeof() == 8) { // f64 let u = reinterpret(key); let l = u; let h = (u >>> 32); hash = (hash ^ ( l & 0xff)) * FNV_PRIME; hash = (hash ^ ((l >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((l >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( l >>> 24 )) * FNV_PRIME; hash = (hash ^ ( h & 0xff)) * FNV_PRIME; hash = (hash ^ ((h >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((h >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( h >>> 24 )) * FNV_PRIME; } else unreachable(); } else if (sizeof() == 1) { // bool, i8, u8 hash = (hash ^ (key & 0xff)) * FNV_PRIME; } else if (sizeof() == 2) { // i16, u16 let u = key; hash = (hash ^ ( u & 0xff)) * FNV_PRIME; hash = (hash ^ ( u >>> 8 )) * FNV_PRIME; } else if (sizeof() == 4) { // i32, u32 let u = key; hash = (hash ^ ( u & 0xff)) * FNV_PRIME; hash = (hash ^ ((u >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((u >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( u >>> 24 )) * FNV_PRIME; } else if (sizeof() == 8) { // i64, u64 let l = key; let h = (key >>> 32); hash = (hash ^ ( l & 0xff)) * FNV_PRIME; hash = (hash ^ ((l >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((l >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( l >>> 24 )) * FNV_PRIME; hash = (hash ^ ( h & 0xff)) * FNV_PRIME; hash = (hash ^ ((h >>> 8) & 0xff)) * FNV_PRIME; hash = (hash ^ ((h >>> 16) & 0xff)) * FNV_PRIME; hash = (hash ^ ( h >>> 24 )) * FNV_PRIME; } else unreachable(); return hash; }