hash-match.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c) 2022-2023, smartmx <smartmx@qq.com>
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-04-03 smartmx the first version
  9. * 2023-03-02 smartmx hash_match_group function will return the pointer to index
  10. *
  11. */
  12. #include "hash-match.h"
  13. /**
  14. * check all calculated hash code in the group, compare with hash_code.
  15. *
  16. * @param start the hash match group start address.
  17. * @param end the hash match group end address.
  18. * @param hash_code the hash code which is need be checked.
  19. *
  20. * @return None.
  21. */
  22. void hash_match_check(const hash_match_t *start, const hash_match_t *end, uint32_t hash_code, uint32_t hash_key_len)
  23. {
  24. const hash_match_t *check_start = (const hash_match_t *)start;
  25. HASH_MATCH_PRINTF("check hash_code:'%08x'\n", hash_code);
  26. while (1)
  27. {
  28. if (end <= check_start)
  29. {
  30. break;
  31. }
  32. if (*(check_start->hash_code) == hash_code)
  33. {
  34. HASH_MATCH_PRINTF("hash_code is duplicated with hash_key:\n");
  35. HASH_MATCH_PRINTF("1st:");
  36. for (uint32_t i = 0; i < check_start->hash_key_len; i++)
  37. {
  38. HASH_MATCH_PRINTF(" %02x", check_start->hash_key_src[i]);
  39. }
  40. HASH_MATCH_PRINTF("\n");
  41. HASH_MATCH_PRINTF("2nd:");
  42. for (uint32_t i = 0; i < end->hash_key_len; i++)
  43. {
  44. HASH_MATCH_PRINTF(" %02x", end->hash_key_src[i]);
  45. }
  46. HASH_MATCH_PRINTF("\n");
  47. if (check_start->hash_key_len == hash_key_len)
  48. {
  49. HASH_MATCH_PRINTF("hash_code and hash_key_len %d are all duplicated, you must fix it!\n", hash_key_len);
  50. break;
  51. }
  52. }
  53. check_start++;
  54. }
  55. }
  56. /**
  57. * init a hash code group.
  58. *
  59. * @param start the hash match group start address.
  60. * @param end the hash match group end address.
  61. *
  62. * @return None.
  63. */
  64. void hash_match_group_init(const hash_match_t *start, const hash_match_t *end)
  65. {
  66. const hash_match_t *init_start = (const hash_match_t *)start;
  67. while (1)
  68. {
  69. if (end <= init_start)
  70. {
  71. break;
  72. }
  73. *(init_start->hash_code) = hash_match_caculate(init_start->hash_key_src, init_start->hash_key_len);
  74. #if HASH_MATCH_INIT_CHECK
  75. hash_match_check(start, init_start, *(init_start->hash_code), init_start->hash_key_len);
  76. #endif
  77. init_start++;
  78. }
  79. }
  80. /**
  81. * check all calculated hash code in the group, compare with hash_code.
  82. *
  83. * @param start the hash match group start address.
  84. * @param end the hash match group end address.
  85. * @param src the hash key source pointer.
  86. * @param len the length of hash key source.
  87. * @param (void*) parameter when calling handler.
  88. *
  89. * @return None.
  90. */
  91. void *hash_match_group(const hash_match_t *start, const hash_match_t *end, const void *src, uint32_t len, void *param)
  92. {
  93. const hash_match_t *find_start = (const hash_match_t *)start;
  94. uint32_t hash_code;
  95. hash_code = hash_match_caculate(src, len);
  96. while (1)
  97. {
  98. if (end <= find_start)
  99. {
  100. break;
  101. }
  102. if ((*(find_start->hash_code) == hash_code) && (len == find_start->hash_key_len))
  103. {
  104. #if HASH_MATCH_COMPARE_KEY
  105. if (hash_match_memcmp(src, find_start->hash_key_src, len) == HASH_MATCH_MEMCMP_SAME)
  106. {
  107. #endif
  108. if (find_start->handler != NULL)
  109. {
  110. find_start->handler(param);
  111. }
  112. return (void *)find_start;
  113. #if HASH_MATCH_COMPARE_KEY
  114. }
  115. #endif
  116. }
  117. find_start++;
  118. }
  119. return NULL;
  120. }
  121. /**
  122. * list all hash key info in a hash code group.
  123. *
  124. * @param start the hash match group start address.
  125. * @param end the hash match group end address.
  126. *
  127. * @return None.
  128. */
  129. void hash_match_group_list(const hash_match_t *start, const hash_match_t *end)
  130. {
  131. const hash_match_t *list_start = (const hash_match_t *)start;
  132. uint32_t len;
  133. while (1)
  134. {
  135. if (end <= list_start)
  136. {
  137. break;
  138. }
  139. len = 0;
  140. HASH_MATCH_PRINTF("hash match key:%02x", list_start->hash_key_src[len]);
  141. len++;
  142. while (len < list_start->hash_key_len)
  143. {
  144. HASH_MATCH_PRINTF(" %02x", list_start->hash_key_src[len]);
  145. len++;
  146. }
  147. HASH_MATCH_PRINTF("\nhash match key len:%d\n", list_start->hash_key_len);
  148. HASH_MATCH_PRINTF("hash match hash code:%08x\n", *(list_start->hash_code));
  149. #if HASH_MATCH_SAVE_DESC
  150. HASH_MATCH_PRINTF("hash match description: %s\n", list_start->hash_desc);
  151. #endif
  152. list_start++;
  153. }
  154. }