memfile_test.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* vi:set ts=8 sts=4 sw=4 noet:
  2. *
  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. * memfile_test.c: Unittests for memfile.c
  11. * Mostly by Ivan Krasilnikov.
  12. */
  13. #undef NDEBUG
  14. #include <assert.h>
  15. // Must include main.c because it contains much more than just main()
  16. #define NO_VIM_MAIN
  17. #include "main.c"
  18. // This file has to be included because the tested functions are static
  19. #include "memfile.c"
  20. #define index_to_key(i) ((i) ^ 15167)
  21. #define TEST_COUNT 50000
  22. /*
  23. * Test mf_hash_*() functions.
  24. */
  25. static void
  26. test_mf_hash(void)
  27. {
  28. mf_hashtab_T ht;
  29. mf_hashitem_T *item;
  30. blocknr_T key;
  31. long_u i;
  32. long_u num_buckets;
  33. mf_hash_init(&ht);
  34. // insert some items and check invariants
  35. for (i = 0; i < TEST_COUNT; i++)
  36. {
  37. assert(ht.mht_count == i);
  38. // check that number of buckets is a power of 2
  39. num_buckets = ht.mht_mask + 1;
  40. assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0);
  41. // check load factor
  42. assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR));
  43. if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR))
  44. {
  45. // first expansion shouldn't have occurred yet
  46. assert(num_buckets == MHT_INIT_SIZE);
  47. assert(ht.mht_buckets == ht.mht_small_buckets);
  48. }
  49. else
  50. {
  51. assert(num_buckets > MHT_INIT_SIZE);
  52. assert(ht.mht_buckets != ht.mht_small_buckets);
  53. }
  54. key = index_to_key(i);
  55. assert(mf_hash_find(&ht, key) == NULL);
  56. // allocate and add new item
  57. item = LALLOC_CLEAR_ONE(mf_hashitem_T);
  58. assert(item != NULL);
  59. item->mhi_key = key;
  60. mf_hash_add_item(&ht, item);
  61. assert(mf_hash_find(&ht, key) == item);
  62. if (ht.mht_mask + 1 != num_buckets)
  63. {
  64. // hash table was expanded
  65. assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR);
  66. assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR));
  67. }
  68. }
  69. // check presence of inserted items
  70. for (i = 0; i < TEST_COUNT; i++)
  71. {
  72. key = index_to_key(i);
  73. item = mf_hash_find(&ht, key);
  74. assert(item != NULL);
  75. assert(item->mhi_key == key);
  76. }
  77. // delete some items
  78. for (i = 0; i < TEST_COUNT; i++)
  79. {
  80. if (i % 100 < 70)
  81. {
  82. key = index_to_key(i);
  83. item = mf_hash_find(&ht, key);
  84. assert(item != NULL);
  85. assert(item->mhi_key == key);
  86. mf_hash_rem_item(&ht, item);
  87. assert(mf_hash_find(&ht, key) == NULL);
  88. mf_hash_add_item(&ht, item);
  89. assert(mf_hash_find(&ht, key) == item);
  90. mf_hash_rem_item(&ht, item);
  91. assert(mf_hash_find(&ht, key) == NULL);
  92. vim_free(item);
  93. }
  94. }
  95. // check again
  96. for (i = 0; i < TEST_COUNT; i++)
  97. {
  98. key = index_to_key(i);
  99. item = mf_hash_find(&ht, key);
  100. if (i % 100 < 70)
  101. {
  102. assert(item == NULL);
  103. }
  104. else
  105. {
  106. assert(item != NULL);
  107. assert(item->mhi_key == key);
  108. }
  109. }
  110. // free hash table and all remaining items
  111. mf_hash_free_all(&ht);
  112. }
  113. int
  114. main(void)
  115. {
  116. test_mf_hash();
  117. return 0;
  118. }