diff options
Diffstat (limited to 'src/memfile_test.c')
-rw-r--r-- | src/memfile_test.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/memfile_test.c b/src/memfile_test.c new file mode 100644 index 0000000..a352619 --- /dev/null +++ b/src/memfile_test.c @@ -0,0 +1,143 @@ +/* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * memfile_test.c: Unittests for memfile.c + * Mostly by Ivan Krasilnikov. + */ + +#undef NDEBUG +#include <assert.h> + +// Must include main.c because it contains much more than just main() +#define NO_VIM_MAIN +#include "main.c" + +// This file has to be included because the tested functions are static +#include "memfile.c" + +#define index_to_key(i) ((i) ^ 15167) +#define TEST_COUNT 50000 + +/* + * Test mf_hash_*() functions. + */ + static void +test_mf_hash(void) +{ + mf_hashtab_T ht; + mf_hashitem_T *item; + blocknr_T key; + long_u i; + long_u num_buckets; + + mf_hash_init(&ht); + + // insert some items and check invariants + for (i = 0; i < TEST_COUNT; i++) + { + assert(ht.mht_count == i); + + // check that number of buckets is a power of 2 + num_buckets = ht.mht_mask + 1; + assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0); + + // check load factor + assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR)); + + if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR)) + { + // first expansion shouldn't have occurred yet + assert(num_buckets == MHT_INIT_SIZE); + assert(ht.mht_buckets == ht.mht_small_buckets); + } + else + { + assert(num_buckets > MHT_INIT_SIZE); + assert(ht.mht_buckets != ht.mht_small_buckets); + } + + key = index_to_key(i); + assert(mf_hash_find(&ht, key) == NULL); + + // allocate and add new item + item = LALLOC_CLEAR_ONE(mf_hashitem_T); + assert(item != NULL); + item->mhi_key = key; + mf_hash_add_item(&ht, item); + + assert(mf_hash_find(&ht, key) == item); + + if (ht.mht_mask + 1 != num_buckets) + { + // hash table was expanded + assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR); + assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR)); + } + } + + // check presence of inserted items + for (i = 0; i < TEST_COUNT; i++) + { + key = index_to_key(i); + item = mf_hash_find(&ht, key); + assert(item != NULL); + assert(item->mhi_key == key); + } + + // delete some items + for (i = 0; i < TEST_COUNT; i++) + { + if (i % 100 < 70) + { + key = index_to_key(i); + item = mf_hash_find(&ht, key); + assert(item != NULL); + assert(item->mhi_key == key); + + mf_hash_rem_item(&ht, item); + assert(mf_hash_find(&ht, key) == NULL); + + mf_hash_add_item(&ht, item); + assert(mf_hash_find(&ht, key) == item); + + mf_hash_rem_item(&ht, item); + assert(mf_hash_find(&ht, key) == NULL); + + vim_free(item); + } + } + + // check again + for (i = 0; i < TEST_COUNT; i++) + { + key = index_to_key(i); + item = mf_hash_find(&ht, key); + + if (i % 100 < 70) + { + assert(item == NULL); + } + else + { + assert(item != NULL); + assert(item->mhi_key == key); + } + } + + // free hash table and all remaining items + mf_hash_free_all(&ht); +} + + int +main(void) +{ + test_mf_hash(); + return 0; +} |