use fmt; use hash; use hash::fnv; use math::random; fn test_eq(ctx: *opaque, entry: *opaque) bool = *(ctx: *u64) == *(entry: *u64); fn test_fnvhash(x: u64) u64 = { let h = fnv::fnv64a(); hash::write(&h, &x: *[8]u8); return fnv::sum64(&h); }; fn test_garbagehash(x: u64) u64 = 0x0123456789abcdef; fn test_table(sz: size, hash_fn: *fn(x: u64) u64, rng: *random::random) void = { fmt::printf("{} ", sz)!; static let array: [1024]bool = [false...]; for (let i = 0z; i < len(array); i += 1) { array[i] = false; }; let tab = new(0, sz); defer finish(&tab); for (let i = 0; i < 100000; i += 1) { const x = random::u64n(rng, len(array): u64); const hash = hash_fn(x); match (get(&tab, hash, &test_eq, &x, sz)) { case let entry: *opaque => assert(array[x: size]); assert(*(entry: *u64) == x); del(&tab, entry, sz); array[x: size] = false; case null => assert(!array[x: size]); const entry = add(&tab, hash, sz); array[x: size] = true; *(entry: *u64) = x; }; }; for (let x = 0u64; x < len(array): u64; x += 1) { const hash = hash_fn(x); get(&tab, hash, &test_eq, &x, sz); }; fmt::println()!; }; @test fn table() void = { let rng = random::init(42); fmt::println("fnvhash:")!; for (let i = 8z; i < 128; i += 8) test_table(i, &test_fnvhash, &rng); fmt::println("garbagehash:")!; for (let i = 8z; i < 128; i += 8) test_table(i, &test_garbagehash, &rng); };