qr.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include "test/jemalloc_test.h"
  2. #include "jemalloc/internal/qr.h"
  3. /* Number of ring entries, in [2..26]. */
  4. #define NENTRIES 9
  5. /* Split index, in [1..NENTRIES). */
  6. #define SPLIT_INDEX 5
  7. typedef struct ring_s ring_t;
  8. struct ring_s {
  9. qr(ring_t) link;
  10. char id;
  11. };
  12. static void
  13. init_entries(ring_t *entries) {
  14. unsigned i;
  15. for (i = 0; i < NENTRIES; i++) {
  16. qr_new(&entries[i], link);
  17. entries[i].id = 'a' + i;
  18. }
  19. }
  20. static void
  21. test_independent_entries(ring_t *entries) {
  22. ring_t *t;
  23. unsigned i, j;
  24. for (i = 0; i < NENTRIES; i++) {
  25. j = 0;
  26. qr_foreach(t, &entries[i], link) {
  27. j++;
  28. }
  29. expect_u_eq(j, 1,
  30. "Iteration over single-element ring should visit precisely "
  31. "one element");
  32. }
  33. for (i = 0; i < NENTRIES; i++) {
  34. j = 0;
  35. qr_reverse_foreach(t, &entries[i], link) {
  36. j++;
  37. }
  38. expect_u_eq(j, 1,
  39. "Iteration over single-element ring should visit precisely "
  40. "one element");
  41. }
  42. for (i = 0; i < NENTRIES; i++) {
  43. t = qr_next(&entries[i], link);
  44. expect_ptr_eq(t, &entries[i],
  45. "Next element in single-element ring should be same as "
  46. "current element");
  47. }
  48. for (i = 0; i < NENTRIES; i++) {
  49. t = qr_prev(&entries[i], link);
  50. expect_ptr_eq(t, &entries[i],
  51. "Previous element in single-element ring should be same as "
  52. "current element");
  53. }
  54. }
  55. TEST_BEGIN(test_qr_one) {
  56. ring_t entries[NENTRIES];
  57. init_entries(entries);
  58. test_independent_entries(entries);
  59. }
  60. TEST_END
  61. static void
  62. test_entries_ring(ring_t *entries) {
  63. ring_t *t;
  64. unsigned i, j;
  65. for (i = 0; i < NENTRIES; i++) {
  66. j = 0;
  67. qr_foreach(t, &entries[i], link) {
  68. expect_c_eq(t->id, entries[(i+j) % NENTRIES].id,
  69. "Element id mismatch");
  70. j++;
  71. }
  72. }
  73. for (i = 0; i < NENTRIES; i++) {
  74. j = 0;
  75. qr_reverse_foreach(t, &entries[i], link) {
  76. expect_c_eq(t->id, entries[(NENTRIES+i-j-1) %
  77. NENTRIES].id, "Element id mismatch");
  78. j++;
  79. }
  80. }
  81. for (i = 0; i < NENTRIES; i++) {
  82. t = qr_next(&entries[i], link);
  83. expect_c_eq(t->id, entries[(i+1) % NENTRIES].id,
  84. "Element id mismatch");
  85. }
  86. for (i = 0; i < NENTRIES; i++) {
  87. t = qr_prev(&entries[i], link);
  88. expect_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
  89. "Element id mismatch");
  90. }
  91. }
  92. TEST_BEGIN(test_qr_after_insert) {
  93. ring_t entries[NENTRIES];
  94. unsigned i;
  95. init_entries(entries);
  96. for (i = 1; i < NENTRIES; i++) {
  97. qr_after_insert(&entries[i - 1], &entries[i], link);
  98. }
  99. test_entries_ring(entries);
  100. }
  101. TEST_END
  102. TEST_BEGIN(test_qr_remove) {
  103. ring_t entries[NENTRIES];
  104. ring_t *t;
  105. unsigned i, j;
  106. init_entries(entries);
  107. for (i = 1; i < NENTRIES; i++) {
  108. qr_after_insert(&entries[i - 1], &entries[i], link);
  109. }
  110. for (i = 0; i < NENTRIES; i++) {
  111. j = 0;
  112. qr_foreach(t, &entries[i], link) {
  113. expect_c_eq(t->id, entries[i+j].id,
  114. "Element id mismatch");
  115. j++;
  116. }
  117. j = 0;
  118. qr_reverse_foreach(t, &entries[i], link) {
  119. expect_c_eq(t->id, entries[NENTRIES - 1 - j].id,
  120. "Element id mismatch");
  121. j++;
  122. }
  123. qr_remove(&entries[i], link);
  124. }
  125. test_independent_entries(entries);
  126. }
  127. TEST_END
  128. TEST_BEGIN(test_qr_before_insert) {
  129. ring_t entries[NENTRIES];
  130. ring_t *t;
  131. unsigned i, j;
  132. init_entries(entries);
  133. for (i = 1; i < NENTRIES; i++) {
  134. qr_before_insert(&entries[i - 1], &entries[i], link);
  135. }
  136. for (i = 0; i < NENTRIES; i++) {
  137. j = 0;
  138. qr_foreach(t, &entries[i], link) {
  139. expect_c_eq(t->id, entries[(NENTRIES+i-j) %
  140. NENTRIES].id, "Element id mismatch");
  141. j++;
  142. }
  143. }
  144. for (i = 0; i < NENTRIES; i++) {
  145. j = 0;
  146. qr_reverse_foreach(t, &entries[i], link) {
  147. expect_c_eq(t->id, entries[(i+j+1) % NENTRIES].id,
  148. "Element id mismatch");
  149. j++;
  150. }
  151. }
  152. for (i = 0; i < NENTRIES; i++) {
  153. t = qr_next(&entries[i], link);
  154. expect_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
  155. "Element id mismatch");
  156. }
  157. for (i = 0; i < NENTRIES; i++) {
  158. t = qr_prev(&entries[i], link);
  159. expect_c_eq(t->id, entries[(i+1) % NENTRIES].id,
  160. "Element id mismatch");
  161. }
  162. }
  163. TEST_END
  164. static void
  165. test_split_entries(ring_t *entries) {
  166. ring_t *t;
  167. unsigned i, j;
  168. for (i = 0; i < NENTRIES; i++) {
  169. j = 0;
  170. qr_foreach(t, &entries[i], link) {
  171. if (i < SPLIT_INDEX) {
  172. expect_c_eq(t->id,
  173. entries[(i+j) % SPLIT_INDEX].id,
  174. "Element id mismatch");
  175. } else {
  176. expect_c_eq(t->id, entries[(i+j-SPLIT_INDEX) %
  177. (NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id,
  178. "Element id mismatch");
  179. }
  180. j++;
  181. }
  182. }
  183. }
  184. TEST_BEGIN(test_qr_meld_split) {
  185. ring_t entries[NENTRIES];
  186. unsigned i;
  187. init_entries(entries);
  188. for (i = 1; i < NENTRIES; i++) {
  189. qr_after_insert(&entries[i - 1], &entries[i], link);
  190. }
  191. qr_split(&entries[0], &entries[SPLIT_INDEX], link);
  192. test_split_entries(entries);
  193. qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
  194. test_entries_ring(entries);
  195. qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
  196. test_split_entries(entries);
  197. qr_split(&entries[0], &entries[SPLIT_INDEX], link);
  198. test_entries_ring(entries);
  199. qr_split(&entries[0], &entries[0], link);
  200. test_entries_ring(entries);
  201. qr_meld(&entries[0], &entries[0], link);
  202. test_entries_ring(entries);
  203. }
  204. TEST_END
  205. int
  206. main(void) {
  207. return test(
  208. test_qr_one,
  209. test_qr_after_insert,
  210. test_qr_remove,
  211. test_qr_before_insert,
  212. test_qr_meld_split);
  213. }