testhash.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * Copyright (c) 2018-2019 SignalWire, Inc
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. #include "libks/ks.h"
  23. #include "tap.h"
  24. int test1(void)
  25. {
  26. ks_pool_t *pool;
  27. ks_hash_t *hash;
  28. int i, sum1 = 0, sum2 = 0;
  29. ks_pool_open(&pool);
  30. ks_hash_create(&hash, KS_HASH_MODE_DEFAULT, KS_HASH_FREE_BOTH | KS_HASH_FLAG_RWLOCK, pool);
  31. for (i = 1; i < 1001; i++) {
  32. char *key = ks_pprintf(pool, "KEY %d", i);
  33. char *val = ks_pprintf(pool, "%d", i);
  34. ks_hash_insert(hash, key, val);
  35. sum1 += i;
  36. }
  37. ks_hash_iterator_t *itt;
  38. ks_hash_write_lock(hash);
  39. for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; ) {
  40. const void *key;
  41. void *val;
  42. ks_hash_this(itt, &key, NULL, &val);
  43. printf("%s=%s\n", (char *)key, (char *)val);
  44. sum2 += atoi(val);
  45. itt = ks_hash_next(&itt);
  46. ks_hash_remove(hash, (char *)key);
  47. }
  48. ks_hash_write_unlock(hash);
  49. ks_hash_destroy(&hash);
  50. ks_pool_close(&pool);
  51. return (sum1 == sum2);
  52. }
  53. #define MAX 100
  54. static void *test2_thread(ks_thread_t *thread, void *data)
  55. {
  56. ks_hash_iterator_t *itt;
  57. ks_hash_t *hash = (ks_hash_t *) data;
  58. while(!ks_thread_stop_requested(thread)) {
  59. for (itt = ks_hash_first(hash, KS_READLOCKED); itt; itt = ks_hash_next(&itt)) {
  60. const void *key;
  61. void *val;
  62. ks_hash_this(itt, &key, NULL, &val);
  63. printf("%u ITT %s=%s\n", (int)ks_thread_self_id(), (char *)key, (char *)val);
  64. }
  65. ks_sleep(100000);
  66. }
  67. return NULL;
  68. }
  69. int test2(void)
  70. {
  71. ks_thread_t *threads[MAX];
  72. int ttl = 5;
  73. int runs = 5;
  74. ks_pool_t *pool;
  75. ks_hash_t *hash;
  76. int i;
  77. ks_hash_iterator_t *itt;
  78. ks_pool_open(&pool);
  79. ks_hash_create(&hash, KS_HASH_MODE_DEFAULT, KS_HASH_FREE_BOTH | KS_HASH_FLAG_RWLOCK, pool);
  80. for (i = 0; i < ttl; i++) {
  81. ks_thread_create(&threads[i], test2_thread, hash, pool);
  82. }
  83. for(i = 0; i < runs; i++) {
  84. int x = rand() % 5;
  85. int j;
  86. for (j = 0; j < 100; j++) {
  87. char *key = ks_pprintf(pool, "KEY %d", j);
  88. char *val = ks_pprintf(pool, "%d", j);
  89. ks_hash_insert(hash, key, val);
  90. }
  91. ks_sleep(x * 1000000);
  92. ks_hash_write_lock(hash);
  93. for (itt = ks_hash_first(hash, KS_UNLOCKED); itt; ) {
  94. const void *key;
  95. void *val;
  96. ks_hash_this(itt, &key, NULL, &val);
  97. printf("DEL %s=%s\n", (char *)key, (char *)val);
  98. itt = ks_hash_next(&itt);
  99. ks_hash_remove(hash, (char *)key);
  100. }
  101. ks_hash_write_unlock(hash);
  102. }
  103. for (i = 0; i < ttl; i++) {
  104. ks_thread_destroy(&threads[i]);
  105. }
  106. ks_hash_destroy(&hash);
  107. ks_pool_close(&pool);
  108. return 1;
  109. }
  110. #define TEST3_SIZE 20
  111. int test3(void)
  112. {
  113. ks_pool_t *pool;
  114. ks_hash_t *hash;
  115. ks_byte_t data[TEST3_SIZE] = { 52, 116, 29, 120, 56, 135, 31, 196, 165, 219, 102, 169, 217, 228, 24, 163, 203, 93, 98, 71 };
  116. ks_byte_t data2[TEST3_SIZE] = { 248, 96, 216, 171, 94, 116, 77, 48, 114, 0, 49, 61, 93, 229, 224, 10, 6, 8, 112, 248 };
  117. ks_byte_t data3[TEST3_SIZE] = { 171, 58, 43, 4, 49, 222, 42, 253, 18, 122, 230, 51, 180, 66, 154, 130, 114, 117, 172, 193 };
  118. char *A, *B, *C;
  119. ks_pool_open(&pool);
  120. ks_hash_create(&hash, KS_HASH_MODE_ARBITRARY, KS_HASH_FLAG_NOLOCK, pool);
  121. ks_hash_set_keysize(hash, TEST3_SIZE);
  122. ks_hash_insert(hash, data, "FOO");
  123. ks_hash_insert(hash, data2, "BAR");
  124. ks_hash_insert(hash, data3, "BAZ");
  125. A = (char *)ks_hash_search(hash, data, KS_UNLOCKED);
  126. B = (char *)ks_hash_search(hash, data2, KS_UNLOCKED);
  127. C = (char *)ks_hash_search(hash, data3, KS_UNLOCKED);
  128. printf("RESULT [%s][%s][%s]\n", A, B, C);
  129. ks_hash_destroy(&hash);
  130. ks_pool_close(&pool);
  131. return !strcmp(A, "FOO") && !strcmp(B, "BAR") && !strcmp(C, "BAZ");
  132. }
  133. int main(int argc, char **argv)
  134. {
  135. ks_init();
  136. ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG);
  137. plan(3);
  138. ok(test1());
  139. ok(test2());
  140. ok(test3());
  141. ks_shutdown();
  142. done_testing();
  143. }