test-idr.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. #pragma GCC push_options
  2. #pragma GCC optimize("O1")
  3. #include "ktest.h"
  4. #include "ktest_utils.h"
  5. #include <common/idr.h>
  6. /**
  7. * @brief 测试idr的构建,预获取空间是否成功
  8. *
  9. * 以下函数将被测试:
  10. * 1. idr_preload
  11. * 2. DECLARE_IDR
  12. * 3. idr_init
  13. * 4. idr_destroy
  14. *
  15. * 同时还会(间接)测试一些内部函数:
  16. * 1. move_to_free_list
  17. *
  18. * @param arg0
  19. * @param arg1
  20. */
  21. static long ktest_idr_case0(uint64_t arg0, uint64_t arg1)
  22. {
  23. unsigned long bitmap = -1;
  24. assert((int)(bitmap == IDR_FULL));
  25. DECLARE_IDR(k_idr);
  26. assert(k_idr.top == NULL); // 刚被创建,必须是NULL
  27. assert(k_idr.id_free_cnt == 0); // 必须是0
  28. assert(k_idr.free_list == NULL);
  29. k_idr.id_free_cnt = arg1;
  30. idr_init(&k_idr);
  31. assert(k_idr.id_free_cnt == 0);
  32. assert(idr_preload(&k_idr, 0) == 0);
  33. assert(k_idr.id_free_cnt == IDR_FREE_MAX);
  34. for (uint64_t i = 1; i < 64; i++)
  35. {
  36. int id = __lowbit_id(i), chk_id = -1;
  37. for (int j = 0; j < 64; j++)
  38. if ((i >> j) & 1)
  39. {
  40. chk_id = j;
  41. break;
  42. }
  43. assert(id == chk_id);
  44. }
  45. // 销毁
  46. idr_destroy(&k_idr);
  47. assert(k_idr.id_free_cnt == 0);
  48. assert(k_idr.free_list == NULL);
  49. assert(k_idr.top == NULL);
  50. return 0;
  51. }
  52. /**
  53. * @brief 测试id的获取,id的删除,id的全体删除, idr的find函数
  54. *
  55. * @param arg0
  56. * @param arg1
  57. */
  58. static long ktest_idr_case1(uint64_t arg0, uint64_t arg1)
  59. {
  60. DECLARE_IDR(k_idr);
  61. int a[128];
  62. // 获取128个id
  63. for (int i = 0; i < 128; i++)
  64. {
  65. assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
  66. assert(a[i] == i);
  67. }
  68. // 查询128个ptr
  69. for (int i = 0; i < 128; i++)
  70. {
  71. int *ptr = idr_find(&k_idr, a[i]);
  72. assert(ptr == &a[i]);
  73. assert(ptr != NULL);
  74. assert(*ptr == a[i]);
  75. }
  76. // 倒序:删除64个id
  77. for (int i = 127; i >= 64; i--)
  78. {
  79. int *id = idr_remove(&k_idr, a[i]);
  80. assert(id != NULL);
  81. assert(*id == i);
  82. assert(idr_find(&k_idr, a[i]) == NULL);
  83. }
  84. // 正序:删除64个id
  85. for (int i = 0; i <= 63; i++)
  86. {
  87. int *id = idr_remove(&k_idr, a[i]);
  88. assert(id != NULL);
  89. assert(*id == i);
  90. assert(idr_find(&k_idr, a[i]) == NULL);
  91. }
  92. for (int i = 0; i < 128; i++)
  93. {
  94. assert(idr_count(&k_idr, i) == 0);
  95. }
  96. // 重新申请128个id, 值域范围应该仍然是[0,127]
  97. for (int i = 0; i < 128; i++)
  98. {
  99. assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
  100. assert(a[i] == i);
  101. }
  102. for (int i = 0; i < 128; i++)
  103. {
  104. assert(idr_count(&k_idr, i));
  105. }
  106. // 正序:删除32个id
  107. for (int i = 0; i <= 31; i++)
  108. {
  109. int *id = idr_remove(&k_idr, a[i]);
  110. assert(id != NULL);
  111. assert(*id == i);
  112. assert(idr_find(&k_idr, a[i]) == NULL);
  113. }
  114. // 倒序:删除32个id
  115. for (int i = 127; i >= 96; i--)
  116. {
  117. int *id = idr_remove(&k_idr, a[i]);
  118. assert(id != NULL);
  119. assert(*id == i);
  120. assert(idr_find(&k_idr, a[i]) == NULL);
  121. }
  122. // 整体删除
  123. idr_remove_all(&k_idr);
  124. assert(k_idr.top == NULL);
  125. // 获取128个id
  126. for (int i = 0; i < 128; i++)
  127. {
  128. assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
  129. assert(a[i] == i);
  130. }
  131. // 查询128个ptr
  132. for (int i = 0; i < 128; i++)
  133. {
  134. int *ptr = idr_find(&k_idr, a[i]);
  135. assert(ptr == &a[i]);
  136. assert(*ptr == a[i]);
  137. }
  138. // 正序:删除64个id
  139. for (int i = 0; i <= 63; i++)
  140. {
  141. idr_remove(&k_idr, a[i]);
  142. assert(idr_find(&k_idr, a[i]) == NULL);
  143. }
  144. // 倒序:删除64个id
  145. for (int i = 127; i >= 64; i--)
  146. {
  147. idr_remove(&k_idr, a[i]);
  148. assert(idr_find(&k_idr, a[i]) == NULL);
  149. }
  150. // 销毁
  151. idr_destroy(&k_idr);
  152. assert(k_idr.id_free_cnt == 0);
  153. assert(k_idr.free_list == NULL);
  154. return 0;
  155. }
  156. /**
  157. * @brief case1 的大数据测试
  158. *
  159. * @param arg0
  160. * @param arg1
  161. */
  162. static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
  163. {
  164. DECLARE_IDR(k_idr);
  165. // 获取 1000‘000 个ID
  166. const int N = 1e6;
  167. // const int N = 1048576;
  168. const int M = 2e5;
  169. int tmp = 0;
  170. for (int i = 0; i < N; i++)
  171. {
  172. barrier();
  173. assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
  174. barrier();
  175. assert(tmp == i);
  176. barrier();
  177. int *ptr = idr_find(&k_idr, i);
  178. barrier();
  179. assert(ptr != NULL);
  180. assert(*ptr == i);
  181. barrier();
  182. // if (i >= 7255) kdebug("1e6 !!!!!!! : %d", i);
  183. assert(idr_count(&k_idr, i));
  184. barrier();
  185. }
  186. // kdebug("111111");
  187. // 正向: M 个ID
  188. for (int i = 0; i < M; i++)
  189. {
  190. int *ptr = idr_find(&k_idr, i);
  191. assert(ptr != NULL);
  192. assert(*ptr == N - 1);
  193. idr_remove(&k_idr, i);
  194. assert(idr_find(&k_idr, i) == NULL);
  195. }
  196. // kdebug("22222");
  197. // 倒序: N-M 个ID
  198. for (int i = (N)-1; i >= M; i--)
  199. {
  200. int *ptr = idr_find(&k_idr, i);
  201. assert(*ptr == N - 1);
  202. idr_remove(&k_idr, i);
  203. assert(idr_find(&k_idr, i) == NULL);
  204. }
  205. // kdebug("3333333");
  206. // 重新插入数据
  207. for (int i = 0; i < N; i++)
  208. {
  209. assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
  210. assert(tmp == i);
  211. assert(k_idr.top != NULL);
  212. int *ptr = idr_find(&k_idr, i);
  213. assert(ptr != NULL);
  214. assert(*ptr == i);
  215. }
  216. // kdebug("4444444444");
  217. assert(k_idr.top != NULL);
  218. for (int i = 0; i < M; i++)
  219. {
  220. assert(idr_replace(&k_idr, NULL, i) == 0);
  221. }
  222. // kdebug("555555555555555555");
  223. // 销毁
  224. idr_destroy(&k_idr);
  225. assert(k_idr.id_free_cnt == 0);
  226. assert(k_idr.free_list == NULL);
  227. // kdebug("666666666666");
  228. return 0;
  229. }
  230. /**
  231. * @brief case1 的大数据测试
  232. *
  233. * @param arg0
  234. * @param arg1
  235. */
  236. static long ktest_idr_case3(uint64_t arg0, uint64_t arg1)
  237. {
  238. DECLARE_IDR(k_idr);
  239. const int N = 1949;
  240. int tmp;
  241. // 获取ID
  242. for (int i = 0; i < N; i++)
  243. {
  244. assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
  245. assert(tmp == i);
  246. int *ptr = idr_find(&k_idr, i);
  247. assert(ptr != NULL);
  248. assert(*ptr == i);
  249. }
  250. // 查询 nextid
  251. for (int i = 1; i <= N; i++)
  252. {
  253. int nextid;
  254. int *ptr = idr_find_next_getid(&k_idr, i - 1, &nextid);
  255. if (likely(i < N))
  256. {
  257. assert(ptr != NULL);
  258. assert(*ptr == N - 1);
  259. assert(nextid == i);
  260. }
  261. else
  262. {
  263. assert(ptr == NULL);
  264. assert(nextid == -1);
  265. }
  266. }
  267. int sz = N;
  268. // 删掉某一段
  269. for (int i = N / 3, j = 2 * (N / 3), k = 0; i <= j; k++, i++)
  270. {
  271. int *ptr = idr_find(&k_idr, i);
  272. assert(ptr != NULL);
  273. assert(*ptr == N - 1);
  274. idr_remove(&k_idr, i);
  275. assert(idr_find(&k_idr, i) == NULL);
  276. sz--;
  277. assert(k_idr.top != NULL);
  278. }
  279. // 查询 nextid
  280. for (int i = 1; i <= N; i++)
  281. {
  282. int nextid;
  283. int *ptr = idr_find_next_getid(&k_idr, i - 1, &nextid);
  284. if (likely(i < N))
  285. {
  286. int target = i < N / 3 ? i : max(i, 2 * (N / 3) + 1);
  287. assert(ptr != NULL);
  288. assert(*ptr == N - 1);
  289. assert(nextid == target);
  290. }
  291. else
  292. {
  293. assert(ptr == NULL);
  294. assert(nextid == -1);
  295. }
  296. }
  297. // 销毁
  298. idr_destroy(&k_idr);
  299. assert(k_idr.id_free_cnt == 0);
  300. assert(k_idr.free_list == NULL);
  301. return 0;
  302. }
  303. /**
  304. * @brief 更加全面覆盖所有函数 - 小数据测试
  305. *
  306. * @param arg0
  307. * @param arg1
  308. */
  309. static long ktest_idr_case4(uint64_t arg0, uint64_t arg1)
  310. {
  311. DECLARE_IDR(k_idr);
  312. idr_init(&k_idr);
  313. const int N = 91173;
  314. static uint32_t tmp;
  315. for (int i = 1; i <= 20; i++)
  316. {
  317. int M = N / i, T = M / 3, b = 2 * T;
  318. for (int j = 0; j < M; j++)
  319. {
  320. assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
  321. assert(tmp == j);
  322. }
  323. for (int j = b; j >= T; j--)
  324. {
  325. int *ptr = idr_find(&k_idr, j);
  326. assert(ptr != NULL);
  327. assert(*ptr == M - 1);
  328. idr_remove(&k_idr, j);
  329. }
  330. for (int j = b + 1; j < M; j++)
  331. {
  332. int *ptr = idr_find(&k_idr, j);
  333. assert(ptr != NULL);
  334. assert(*ptr == M - 1);
  335. idr_remove(&k_idr, j);
  336. }
  337. for (int j = T - 1; j >= 0; j--)
  338. {
  339. int *ptr = idr_find(&k_idr, j);
  340. assert(ptr != NULL);
  341. assert(*ptr == M - 1);
  342. idr_remove(&k_idr, j);
  343. }
  344. assert(k_idr.top == NULL);
  345. assert(idr_empty(&k_idr));
  346. }
  347. // 销毁
  348. idr_destroy(&k_idr);
  349. assert(k_idr.id_free_cnt == 0);
  350. assert(k_idr.free_list == NULL);
  351. assert(idr_empty(&k_idr));
  352. return 0;
  353. }
  354. /**
  355. * @brief 测试id的获取,id的删除,id的全体删除, idr的find函数
  356. *
  357. * @param arg0
  358. * @param arg1
  359. */
  360. static long ktest_idr_case5(uint64_t arg0, uint64_t arg1)
  361. {
  362. DECLARE_IDR(k_idr);
  363. const int N = 128;
  364. int a[N];
  365. // 获取128个id
  366. for (int i = 0; i < N; i++)
  367. {
  368. assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
  369. assert(a[i] == i);
  370. }
  371. // 把id指向的指针向后移动一个单位
  372. for (int i = 0; i < N; i++)
  373. {
  374. int *ptr;
  375. int flags = idr_replace_get_old(&k_idr, &a[(i + 1) % N], i, (void *)&ptr);
  376. assert(flags == 0); // 0 是成功
  377. assert(ptr != NULL);
  378. assert(*ptr == i);
  379. // 测试是否替换成功
  380. ptr = idr_find(&k_idr, i);
  381. assert(ptr != NULL);
  382. assert(*ptr == (i + 1) % N);
  383. }
  384. // 销毁
  385. idr_destroy(&k_idr);
  386. assert(k_idr.id_free_cnt == 0);
  387. assert(k_idr.free_list == NULL);
  388. // destroy之后,再获取128个id
  389. for (int i = 0; i < N; i++)
  390. {
  391. assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
  392. assert(a[i] == i);
  393. }
  394. // 销毁
  395. idr_destroy(&k_idr);
  396. assert(idr_empty(&k_idr));
  397. assert(k_idr.id_free_cnt == 0);
  398. assert(k_idr.free_list == NULL);
  399. return 0;
  400. }
  401. /**
  402. * @brief 测试ida的插入/删除
  403. *
  404. * @param arg0
  405. * @param arg1
  406. * @return long
  407. */
  408. static long ktest_idr_case6(uint64_t arg0, uint64_t arg1)
  409. {
  410. assert(IDA_BITMAP_LONGS != 0);
  411. assert(IDA_BMP_SIZE != 0);
  412. assert(IDA_FULL != 0);
  413. assert(IDA_BITMAP_BITS != 0);
  414. DECLARE_IDA(k_ida);
  415. ida_init(&k_ida);
  416. io_sfence();
  417. const int N = IDA_FULL * IDR_SIZE + 1;
  418. for (int i = 0; i < N; i++)
  419. {
  420. int p_id;
  421. io_sfence();
  422. assert(ida_alloc(&k_ida, &p_id) == 0);
  423. io_sfence();
  424. assert(p_id == i);
  425. io_sfence();
  426. }
  427. for (int i = 0; i < N; i++)
  428. {
  429. assert(ida_count(&k_ida, i) == 1);
  430. io_sfence();
  431. }
  432. for (int i = N - 1; i >= 0; i--)
  433. {
  434. ida_remove(&k_ida, i);
  435. io_sfence();
  436. assert(ida_count(&k_ida, i) == 0);
  437. io_sfence();
  438. }
  439. assert(k_ida.idr.top == NULL);
  440. for (int i = 0; i < N; i++)
  441. {
  442. int p_id;
  443. io_sfence();
  444. assert(ida_alloc(&k_ida, &p_id) == 0);
  445. io_sfence();
  446. assert(p_id == i);
  447. io_sfence();
  448. }
  449. assert(k_ida.idr.top != NULL);
  450. io_sfence();
  451. ida_destroy(&k_ida);
  452. io_sfence();
  453. assert(k_ida.idr.top == NULL);
  454. io_sfence();
  455. assert(k_ida.free_list == NULL);
  456. io_sfence();
  457. assert(ida_empty(&k_ida));
  458. io_sfence();
  459. // 测试destroy之后能否重新获取ID
  460. for (int i = 0; i < N; i++)
  461. {
  462. int p_id;
  463. io_sfence();
  464. assert(ida_alloc(&k_ida, &p_id) == 0);
  465. io_sfence();
  466. assert(p_id == i);
  467. io_sfence();
  468. }
  469. for (int i = 0; i < N / 3; i++)
  470. {
  471. ida_remove(&k_ida, i);
  472. io_sfence();
  473. assert(ida_count(&k_ida, i) == 0);
  474. io_sfence();
  475. }
  476. for (int i = 2 * N / 3; i < N; i++)
  477. {
  478. ida_remove(&k_ida, i);
  479. io_sfence();
  480. assert(ida_count(&k_ida, i) == 0);
  481. io_sfence();
  482. }
  483. assert(k_ida.idr.top != NULL);
  484. io_sfence();
  485. ida_destroy(&k_ida);
  486. io_sfence();
  487. assert(k_ida.idr.top == NULL);
  488. io_sfence();
  489. assert(k_ida.free_list == NULL);
  490. io_sfence();
  491. assert(ida_empty(&k_ida));
  492. io_sfence();
  493. return 0;
  494. }
  495. static ktest_case_table kt_idr_func_table[] = {
  496. ktest_idr_case0,
  497. ktest_idr_case1,
  498. // ktest_idr_case2, // 为了加快启动速度, 暂时注释掉这个测试
  499. ktest_idr_case3,
  500. ktest_idr_case4,
  501. ktest_idr_case5,
  502. ktest_idr_case6,
  503. };
  504. int ktest_test_idr(void *arg)
  505. {
  506. kTEST("Testing idr...");
  507. unsigned int sz = sizeof(kt_idr_func_table) / sizeof(ktest_case_table);
  508. for (int i = 0; i < sz; ++i)
  509. {
  510. kTEST("Testing case %d", i);
  511. kt_idr_func_table[i](i, i + 1);
  512. }
  513. kTEST("idr Test done.");
  514. return 0;
  515. }
  516. #pragma GCC pop_options