blob: a35261946942be8717f014b3c2294d6b3718006e [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaarb3c52842011-03-22 20:52:37 +01002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * memfile_test.c: Unittests for memfile.c
12 * Mostly by Ivan Krasilnikov.
13 */
14
15#undef NDEBUG
16#include <assert.h>
17
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010018// Must include main.c because it contains much more than just main()
Bram Moolenaarb3c52842011-03-22 20:52:37 +010019#define NO_VIM_MAIN
20#include "main.c"
21
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010022// This file has to be included because the tested functions are static
Bram Moolenaarb3c52842011-03-22 20:52:37 +010023#include "memfile.c"
24
25#define index_to_key(i) ((i) ^ 15167)
26#define TEST_COUNT 50000
27
Bram Moolenaarb3c52842011-03-22 20:52:37 +010028/*
29 * Test mf_hash_*() functions.
30 */
31 static void
Bram Moolenaar52ea13d2016-01-30 18:51:09 +010032test_mf_hash(void)
Bram Moolenaarb3c52842011-03-22 20:52:37 +010033{
34 mf_hashtab_T ht;
35 mf_hashitem_T *item;
36 blocknr_T key;
37 long_u i;
38 long_u num_buckets;
39
40 mf_hash_init(&ht);
41
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010042 // insert some items and check invariants
Bram Moolenaarb3c52842011-03-22 20:52:37 +010043 for (i = 0; i < TEST_COUNT; i++)
44 {
45 assert(ht.mht_count == i);
46
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010047 // check that number of buckets is a power of 2
Bram Moolenaarb3c52842011-03-22 20:52:37 +010048 num_buckets = ht.mht_mask + 1;
49 assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0);
50
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010051 // check load factor
Bram Moolenaarb3c52842011-03-22 20:52:37 +010052 assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR));
53
54 if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR))
55 {
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010056 // first expansion shouldn't have occurred yet
Bram Moolenaarb3c52842011-03-22 20:52:37 +010057 assert(num_buckets == MHT_INIT_SIZE);
58 assert(ht.mht_buckets == ht.mht_small_buckets);
59 }
60 else
61 {
62 assert(num_buckets > MHT_INIT_SIZE);
63 assert(ht.mht_buckets != ht.mht_small_buckets);
64 }
65
66 key = index_to_key(i);
67 assert(mf_hash_find(&ht, key) == NULL);
68
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010069 // allocate and add new item
Bram Moolenaara37833d2019-06-04 22:29:10 +020070 item = LALLOC_CLEAR_ONE(mf_hashitem_T);
Bram Moolenaarb3c52842011-03-22 20:52:37 +010071 assert(item != NULL);
72 item->mhi_key = key;
73 mf_hash_add_item(&ht, item);
74
75 assert(mf_hash_find(&ht, key) == item);
76
77 if (ht.mht_mask + 1 != num_buckets)
78 {
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010079 // hash table was expanded
Bram Moolenaarb3c52842011-03-22 20:52:37 +010080 assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR);
81 assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR));
82 }
83 }
84
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010085 // check presence of inserted items
Bram Moolenaarb3c52842011-03-22 20:52:37 +010086 for (i = 0; i < TEST_COUNT; i++)
87 {
88 key = index_to_key(i);
89 item = mf_hash_find(&ht, key);
90 assert(item != NULL);
91 assert(item->mhi_key == key);
92 }
93
Bram Moolenaar4ba37b52019-12-04 21:57:43 +010094 // delete some items
Bram Moolenaarb3c52842011-03-22 20:52:37 +010095 for (i = 0; i < TEST_COUNT; i++)
96 {
97 if (i % 100 < 70)
98 {
99 key = index_to_key(i);
100 item = mf_hash_find(&ht, key);
101 assert(item != NULL);
102 assert(item->mhi_key == key);
103
104 mf_hash_rem_item(&ht, item);
105 assert(mf_hash_find(&ht, key) == NULL);
106
107 mf_hash_add_item(&ht, item);
108 assert(mf_hash_find(&ht, key) == item);
109
110 mf_hash_rem_item(&ht, item);
111 assert(mf_hash_find(&ht, key) == NULL);
112
113 vim_free(item);
114 }
115 }
116
Bram Moolenaar4ba37b52019-12-04 21:57:43 +0100117 // check again
Bram Moolenaarb3c52842011-03-22 20:52:37 +0100118 for (i = 0; i < TEST_COUNT; i++)
119 {
120 key = index_to_key(i);
121 item = mf_hash_find(&ht, key);
122
123 if (i % 100 < 70)
124 {
125 assert(item == NULL);
126 }
127 else
128 {
129 assert(item != NULL);
130 assert(item->mhi_key == key);
131 }
132 }
133
Bram Moolenaar4ba37b52019-12-04 21:57:43 +0100134 // free hash table and all remaining items
Bram Moolenaarb3c52842011-03-22 20:52:37 +0100135 mf_hash_free_all(&ht);
136}
137
138 int
Bram Moolenaar52ea13d2016-01-30 18:51:09 +0100139main(void)
Bram Moolenaarb3c52842011-03-22 20:52:37 +0100140{
141 test_mf_hash();
142 return 0;
143}