hashtable.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) Copyright 2019
  4. * Roman Kapl, SYSGO, rka@sysgo.com
  5. */
  6. #include <common.h>
  7. #include <command.h>
  8. #include <log.h>
  9. #include <search.h>
  10. #include <stdio.h>
  11. #include <test/env.h>
  12. #include <test/ut.h>
  13. #define SIZE 32
  14. #define ITERATIONS 10000
  15. static int htab_fill(struct unit_test_state *uts,
  16. struct hsearch_data *htab, size_t size)
  17. {
  18. size_t i;
  19. struct env_entry item;
  20. struct env_entry *ritem;
  21. char key[20];
  22. for (i = 0; i < size; i++) {
  23. sprintf(key, "%d", (int)i);
  24. item.callback = NULL;
  25. item.data = key;
  26. item.flags = 0;
  27. item.key = key;
  28. ut_asserteq(1, hsearch_r(item, ENV_ENTER, &ritem, htab, 0));
  29. }
  30. return 0;
  31. }
  32. static int htab_check_fill(struct unit_test_state *uts,
  33. struct hsearch_data *htab, size_t size)
  34. {
  35. size_t i;
  36. struct env_entry item;
  37. struct env_entry *ritem;
  38. char key[20];
  39. for (i = 0; i < size; i++) {
  40. sprintf(key, "%d", (int)i);
  41. item.callback = NULL;
  42. item.flags = 0;
  43. item.data = key;
  44. item.key = key;
  45. hsearch_r(item, ENV_FIND, &ritem, htab, 0);
  46. ut_assert(ritem);
  47. ut_asserteq_str(key, ritem->key);
  48. ut_asserteq_str(key, ritem->data);
  49. }
  50. return 0;
  51. }
  52. static int htab_create_delete(struct unit_test_state *uts,
  53. struct hsearch_data *htab, size_t iterations)
  54. {
  55. size_t i;
  56. struct env_entry item;
  57. struct env_entry *ritem;
  58. char key[20];
  59. for (i = 0; i < iterations; i++) {
  60. sprintf(key, "cd-%d", (int)i);
  61. item.callback = NULL;
  62. item.flags = 0;
  63. item.data = key;
  64. item.key = key;
  65. hsearch_r(item, ENV_ENTER, &ritem, htab, 0);
  66. ritem = NULL;
  67. hsearch_r(item, ENV_FIND, &ritem, htab, 0);
  68. ut_assert(ritem);
  69. ut_asserteq_str(key, ritem->key);
  70. ut_asserteq_str(key, ritem->data);
  71. ut_asserteq(0, hdelete_r(key, htab, 0));
  72. }
  73. return 0;
  74. }
  75. /* Completely fill up the hash table */
  76. static int env_test_htab_fill(struct unit_test_state *uts)
  77. {
  78. struct hsearch_data htab;
  79. memset(&htab, 0, sizeof(htab));
  80. ut_asserteq(1, hcreate_r(SIZE, &htab));
  81. ut_assertok(htab_fill(uts, &htab, SIZE));
  82. ut_assertok(htab_check_fill(uts, &htab, SIZE));
  83. ut_asserteq(SIZE, htab.filled);
  84. hdestroy_r(&htab);
  85. return 0;
  86. }
  87. ENV_TEST(env_test_htab_fill, 0);
  88. /* Fill the hashtable up halfway an repeateadly delete/create elements
  89. * and check for corruption
  90. */
  91. static int env_test_htab_deletes(struct unit_test_state *uts)
  92. {
  93. struct hsearch_data htab;
  94. memset(&htab, 0, sizeof(htab));
  95. ut_asserteq(1, hcreate_r(SIZE, &htab));
  96. ut_assertok(htab_fill(uts, &htab, SIZE / 2));
  97. ut_assertok(htab_create_delete(uts, &htab, ITERATIONS));
  98. ut_assertok(htab_check_fill(uts, &htab, SIZE / 2));
  99. ut_asserteq(SIZE / 2, htab.filled);
  100. hdestroy_r(&htab);
  101. return 0;
  102. }
  103. ENV_TEST(env_test_htab_deletes, 0);