test_min_heap.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #define pr_fmt(fmt) "min_heap_test: " fmt
  3. /*
  4. * Test cases for the min max heap.
  5. */
  6. #include <linux/log2.h>
  7. #include <linux/min_heap.h>
  8. #include <linux/module.h>
  9. #include <linux/printk.h>
  10. #include <linux/random.h>
  11. DEFINE_MIN_HEAP(int, min_heap_test);
  12. static __init bool less_than(const void *lhs, const void *rhs, void __always_unused *args)
  13. {
  14. return *(int *)lhs < *(int *)rhs;
  15. }
  16. static __init bool greater_than(const void *lhs, const void *rhs, void __always_unused *args)
  17. {
  18. return *(int *)lhs > *(int *)rhs;
  19. }
  20. static __init void swap_ints(void *lhs, void *rhs, void __always_unused *args)
  21. {
  22. int temp = *(int *)lhs;
  23. *(int *)lhs = *(int *)rhs;
  24. *(int *)rhs = temp;
  25. }
  26. static __init int pop_verify_heap(bool min_heap,
  27. struct min_heap_test *heap,
  28. const struct min_heap_callbacks *funcs)
  29. {
  30. int *values = heap->data;
  31. int err = 0;
  32. int last;
  33. last = values[0];
  34. min_heap_pop(heap, funcs, NULL);
  35. while (heap->nr > 0) {
  36. if (min_heap) {
  37. if (last > values[0]) {
  38. pr_err("error: expected %d <= %d\n", last,
  39. values[0]);
  40. err++;
  41. }
  42. } else {
  43. if (last < values[0]) {
  44. pr_err("error: expected %d >= %d\n", last,
  45. values[0]);
  46. err++;
  47. }
  48. }
  49. last = values[0];
  50. min_heap_pop(heap, funcs, NULL);
  51. }
  52. return err;
  53. }
  54. static __init int test_heapify_all(bool min_heap)
  55. {
  56. int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
  57. -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
  58. struct min_heap_test heap = {
  59. .data = values,
  60. .nr = ARRAY_SIZE(values),
  61. .size = ARRAY_SIZE(values),
  62. };
  63. struct min_heap_callbacks funcs = {
  64. .less = min_heap ? less_than : greater_than,
  65. .swp = swap_ints,
  66. };
  67. int i, err;
  68. /* Test with known set of values. */
  69. min_heapify_all(&heap, &funcs, NULL);
  70. err = pop_verify_heap(min_heap, &heap, &funcs);
  71. /* Test with randomly generated values. */
  72. heap.nr = ARRAY_SIZE(values);
  73. for (i = 0; i < heap.nr; i++)
  74. values[i] = get_random_u32();
  75. min_heapify_all(&heap, &funcs, NULL);
  76. err += pop_verify_heap(min_heap, &heap, &funcs);
  77. return err;
  78. }
  79. static __init int test_heap_push(bool min_heap)
  80. {
  81. const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
  82. -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
  83. int values[ARRAY_SIZE(data)];
  84. struct min_heap_test heap = {
  85. .data = values,
  86. .nr = 0,
  87. .size = ARRAY_SIZE(values),
  88. };
  89. struct min_heap_callbacks funcs = {
  90. .less = min_heap ? less_than : greater_than,
  91. .swp = swap_ints,
  92. };
  93. int i, temp, err;
  94. /* Test with known set of values copied from data. */
  95. for (i = 0; i < ARRAY_SIZE(data); i++)
  96. min_heap_push(&heap, &data[i], &funcs, NULL);
  97. err = pop_verify_heap(min_heap, &heap, &funcs);
  98. /* Test with randomly generated values. */
  99. while (heap.nr < heap.size) {
  100. temp = get_random_u32();
  101. min_heap_push(&heap, &temp, &funcs, NULL);
  102. }
  103. err += pop_verify_heap(min_heap, &heap, &funcs);
  104. return err;
  105. }
  106. static __init int test_heap_pop_push(bool min_heap)
  107. {
  108. const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
  109. -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
  110. int values[ARRAY_SIZE(data)];
  111. struct min_heap_test heap = {
  112. .data = values,
  113. .nr = 0,
  114. .size = ARRAY_SIZE(values),
  115. };
  116. struct min_heap_callbacks funcs = {
  117. .less = min_heap ? less_than : greater_than,
  118. .swp = swap_ints,
  119. };
  120. int i, temp, err;
  121. /* Fill values with data to pop and replace. */
  122. temp = min_heap ? 0x80000000 : 0x7FFFFFFF;
  123. for (i = 0; i < ARRAY_SIZE(data); i++)
  124. min_heap_push(&heap, &temp, &funcs, NULL);
  125. /* Test with known set of values copied from data. */
  126. for (i = 0; i < ARRAY_SIZE(data); i++)
  127. min_heap_pop_push(&heap, &data[i], &funcs, NULL);
  128. err = pop_verify_heap(min_heap, &heap, &funcs);
  129. heap.nr = 0;
  130. for (i = 0; i < ARRAY_SIZE(data); i++)
  131. min_heap_push(&heap, &temp, &funcs, NULL);
  132. /* Test with randomly generated values. */
  133. for (i = 0; i < ARRAY_SIZE(data); i++) {
  134. temp = get_random_u32();
  135. min_heap_pop_push(&heap, &temp, &funcs, NULL);
  136. }
  137. err += pop_verify_heap(min_heap, &heap, &funcs);
  138. return err;
  139. }
  140. static __init int test_heap_del(bool min_heap)
  141. {
  142. int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
  143. -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
  144. struct min_heap_test heap;
  145. min_heap_init(&heap, values, ARRAY_SIZE(values));
  146. heap.nr = ARRAY_SIZE(values);
  147. struct min_heap_callbacks funcs = {
  148. .less = min_heap ? less_than : greater_than,
  149. .swp = swap_ints,
  150. };
  151. int i, err;
  152. /* Test with known set of values. */
  153. min_heapify_all(&heap, &funcs, NULL);
  154. for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
  155. min_heap_del(&heap, get_random_u32() % heap.nr, &funcs, NULL);
  156. err = pop_verify_heap(min_heap, &heap, &funcs);
  157. /* Test with randomly generated values. */
  158. heap.nr = ARRAY_SIZE(values);
  159. for (i = 0; i < heap.nr; i++)
  160. values[i] = get_random_u32();
  161. min_heapify_all(&heap, &funcs, NULL);
  162. for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
  163. min_heap_del(&heap, get_random_u32() % heap.nr, &funcs, NULL);
  164. err += pop_verify_heap(min_heap, &heap, &funcs);
  165. return err;
  166. }
  167. static int __init test_min_heap_init(void)
  168. {
  169. int err = 0;
  170. err += test_heapify_all(true);
  171. err += test_heapify_all(false);
  172. err += test_heap_push(true);
  173. err += test_heap_push(false);
  174. err += test_heap_pop_push(true);
  175. err += test_heap_pop_push(false);
  176. err += test_heap_del(true);
  177. err += test_heap_del(false);
  178. if (err) {
  179. pr_err("test failed with %d errors\n", err);
  180. return -EINVAL;
  181. }
  182. pr_info("test passed\n");
  183. return 0;
  184. }
  185. module_init(test_min_heap_init);
  186. static void __exit test_min_heap_exit(void)
  187. {
  188. /* do nothing */
  189. }
  190. module_exit(test_min_heap_exit);
  191. MODULE_DESCRIPTION("Test cases for the min max heap");
  192. MODULE_LICENSE("GPL");