diff options
Diffstat (limited to 'htab/+test.ha')
-rw-r--r-- | htab/+test.ha | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/htab/+test.ha b/htab/+test.ha new file mode 100644 index 0000000..518e97d --- /dev/null +++ b/htab/+test.ha @@ -0,0 +1,61 @@ +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); +}; |