memfile_test.c 3.2 KB

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