From fcedfddf00b3f994e4f4e40332ac7fc192c63244 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 5 Oct 2025 21:56:51 +0700 Subject: claude is gud --- vere/pkg/noun/hashtable_tests.c | 301 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 vere/pkg/noun/hashtable_tests.c (limited to 'vere/pkg/noun/hashtable_tests.c') diff --git a/vere/pkg/noun/hashtable_tests.c b/vere/pkg/noun/hashtable_tests.c new file mode 100644 index 0000000..9a5a3f8 --- /dev/null +++ b/vere/pkg/noun/hashtable_tests.c @@ -0,0 +1,301 @@ +/// @file + +#include "noun.h" +#define TEST_SIZE 100000 + +// defined in noun/hashtable.c +c3_w _ch_skip_slot(c3_w mug_w, c3_w lef_w); + +/* _setup(): prepare for tests. +*/ +static void +_setup(void) +{ + u3m_init(1 << 27); + u3m_pave(c3y); +} + +/* _test_put_del(): +*/ +static c3_i +_test_put_del() +{ + u3p(u3h_root) har_p = u3h_new(); + c3_i ret_i = 1; + + c3_w i_w; + for ( i_w = 0; i_w < TEST_SIZE; i_w++ ) { + u3_noun key = u3i_word(i_w); + u3_noun val = u3nc(u3_nul, u3k(key)); + u3h_put(har_p, key, val); + u3z(key); + } + // fprintf(stderr, "inserted\r\n"); + + for ( i_w = 0; i_w < TEST_SIZE; i_w++ ) { + u3_noun key = u3i_word(i_w); + u3_weak val = u3h_get(har_p, key); + if ( val == u3_none ) { + fprintf(stderr, "failed insert\r\n"); + ret_i = 0; + } + u3z(key); + u3z(val); + } + // fprintf(stderr, "presence\r\n"); + c3_w del_w[4] = {30, 82, 4921, 535}; + + for ( i_w = 0; i_w < 4; i_w++ ) { + u3_noun key = u3i_word(del_w[i_w]); + u3h_del(har_p, key); + u3z(key); + } + // fprintf(stderr, "deleted\r\n"); + + for ( i_w = 0; i_w < 4; i_w++ ) { + u3_noun key = u3i_word(del_w[i_w]); + u3_weak val = u3h_get(har_p, key); + if ( u3_none != val ) { + fprintf(stderr, "failed delete\r\n"); + ret_i = 0; + break; + } + } + // fprintf(stderr, "presence two\r\n"); + u3h_free(har_p); + // fprintf(stderr, "freed\r\n"); + + return ret_i; +} + +/* _test_bit_manipulation(): +*/ +static c3_i +_test_bit_manipulation() +{ + c3_i ret_i = 1; + + if ( sizeof(u3_noun) != sizeof(u3h_slot) ) { + fprintf(stderr, "bit manipulation: wrong size\r\n"); + ret_i = 0; + } + + u3h_slot a = 0; + + if (u3h_slot_is_null(a) != c3y) { + fprintf(stderr, "bit manipulation: nullity\r\n"); + ret_i = 0; + } + + a = u3h_noun_be_warm(a); + if (u3h_slot_is_warm(a) != c3y) { + fprintf(stderr, "bit manipulation: warmth\r\n"); + ret_i = 0; + } + + if (u3h_slot_is_null(a) != c3n) { + fprintf(stderr, "bit manipulation: nullity 2\r\n"); + ret_i = 0; + } + + a = u3h_noun_be_cold(a); + if (u3h_slot_is_warm(a) != c3n) { + fprintf(stderr, "bit manipulation: coldness\r\n"); + ret_i = 0; + } + + return ret_i; +} + +/* _test_no_cache(): test a hashtable without caching. +*/ +static c3_i +_test_no_cache(void) +{ + c3_i ret_i = 1; + c3_w max_w = 1000; + c3_w i_w; + + u3p(u3h_root) har_p = u3h_new(); + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3h_put(har_p, i_w, i_w + max_w); + } + + for ( i_w = 0; i_w < max_w; i_w++ ) { + if ( (i_w + max_w) != u3h_get(har_p, i_w) ) { + fprintf(stderr, "bit test_no_cache: get failed\r\n"); + ret_i = 0; + } + } + + u3h_free(har_p); + return ret_i; +} + +/* _test_skip_slot(): +*/ +static c3_i +_test_skip_slot(void) +{ + c3_i ret_i = 1; + + // root table + { + c3_w mug_w = 0x17 << 25; + c3_w res_w = _ch_skip_slot(mug_w, 25); + + if ( (0x18 << 25) != res_w ) { + fprintf(stderr, "bit skip_slot (a): failed\r\n"); + ret_i = 0; + } + } + + { + c3_w mug_w = 63 << 25; // 6 bits, all ones + c3_w res_w = _ch_skip_slot(mug_w, 25); + + if ( 0 != res_w ) { + fprintf(stderr, "bit skip_slot (b): failed\r\n"); + ret_i = 0; + } + } + + // child nodes + { + c3_w mug_w = 17 << 20; + c3_w res_w = _ch_skip_slot(mug_w, 20); + + if ( (18 << 20) != res_w ) { + fprintf(stderr, "bit skip_slot (c): failed\r\n"); + ret_i = 0; + } + } + + { + c3_w mug_w = 31 << 20; // 5 bits, all ones + c3_w res_w = _ch_skip_slot(mug_w, 20); + u3_assert((1 << 25) == res_w); + + if ( (1 << 25) != res_w ) { + fprintf(stderr, "bit skip_slot (d): failed\r\n"); + ret_i = 0; + } + } + + return ret_i; +} + +/* _test_cache_trimming(): ensure a caching hashtable removes stale items. +*/ +static c3_i +_test_cache_trimming(void) +{ + c3_i ret_i = 1; + c3_w max_w = 2000000; // big number + //c3_w max_w = 348000; // caused a leak before + c3_w i_w, fil_w = max_w / 10; + + u3p(u3h_root) har_p = u3h_new_cache(fil_w); + u3h_root* har_u = u3to(u3h_root, har_p); + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3_noun cel = u3nc(i_w, i_w); + u3h_put(har_p, cel, cel); + } + + { + // last thing we put in is still there + c3_w las_w = max_w - 1; + u3_noun key = u3nc(las_w, las_w); + u3_noun val = u3h_get(har_p, key); + u3z(key); + + if ( las_w != u3t(val) ) { + fprintf(stderr, "cache_trimming (a): fail\r\n"); + ret_i = 0; + } + + if ( fil_w != har_u->use_w ) { + fprintf(stderr, "cache_trimming (b): fail %d != %d\r\n", + fil_w, har_u->use_w ); + ret_i = 0; + } + + u3z(val); + } + + u3h_free(har_p); + return ret_i; +} + +/* _test_cache_replace_value(): +*/ +static c3_i +_test_cache_replace_value(void) +{ + c3_i ret_i = 1; + c3_w max_w = 100; + c3_w i_w; + + u3p(u3h_root) har_p = u3h_new_cache(max_w); + u3h_root* har_u = u3to(u3h_root, har_p); + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3h_put(har_p, i_w, i_w + max_w); + } + + for ( i_w = 0; i_w < max_w; i_w++ ) { + u3h_put(har_p, i_w, i_w + max_w + 1); + } + + if ( (2 * max_w) != u3h_get(har_p, max_w - 1) ) { + fprintf(stderr, "cache_replace (a): fail\r\n"); + ret_i = 0; + } + if ( max_w != har_u->use_w ) { + fprintf(stderr, "cache_replace (b): fail\r\n"); + fprintf(stderr, "cache_replace (b): fail %d %d\r\n", + max_w, har_u->use_w ); + ret_i = 0; + } + + u3h_free(har_p); + return ret_i; +} + +static c3_i +_test_hashtable(void) +{ + c3_i ret_i = 1; + + ret_i &= _test_bit_manipulation(); + ret_i &= _test_no_cache(); + ret_i &= _test_skip_slot(); + ret_i &= _test_cache_trimming(); + ret_i &= _test_cache_replace_value(); + ret_i &= _test_put_del(); + + return ret_i; +} + +/* main(): run all test cases. +*/ +int +main(int argc, char* argv[]) +{ + _setup(); + + if ( !_test_hashtable() ) { + fprintf(stderr, "test_hashtable: failed\r\n"); + exit(1); + } + + // GC + // + u3m_grab(u3_none); + + fprintf(stderr, "test_hashtable: ok\r\n"); + + return 0; +} -- cgit v1.2.3