hashid.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef skynet_hashid_h
  2. #define skynet_hashid_h
  3. #include <assert.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. struct hashid_node {
  7. int id;
  8. struct hashid_node *next;
  9. };
  10. struct hashid {
  11. int hashmod;
  12. int cap;
  13. int count;
  14. struct hashid_node *id;
  15. struct hashid_node **hash;
  16. };
  17. static void
  18. hashid_init(struct hashid *hi, int max) {
  19. int i;
  20. int hashcap;
  21. hashcap = 16;
  22. while (hashcap < max) {
  23. hashcap *= 2;
  24. }
  25. hi->hashmod = hashcap - 1;
  26. hi->cap = max;
  27. hi->count = 0;
  28. hi->id = skynet_malloc(max * sizeof(struct hashid_node));
  29. for (i=0;i<max;i++) {
  30. hi->id[i].id = -1;
  31. hi->id[i].next = NULL;
  32. }
  33. hi->hash = skynet_malloc(hashcap * sizeof(struct hashid_node *));
  34. memset(hi->hash, 0, hashcap * sizeof(struct hashid_node *));
  35. }
  36. static void
  37. hashid_clear(struct hashid *hi) {
  38. skynet_free(hi->id);
  39. skynet_free(hi->hash);
  40. hi->id = NULL;
  41. hi->hash = NULL;
  42. hi->hashmod = 1;
  43. hi->cap = 0;
  44. hi->count = 0;
  45. }
  46. static int
  47. hashid_lookup(struct hashid *hi, int id) {
  48. int h = id & hi->hashmod;
  49. struct hashid_node * c = hi->hash[h];
  50. while(c) {
  51. if (c->id == id)
  52. return c - hi->id;
  53. c = c->next;
  54. }
  55. return -1;
  56. }
  57. static int
  58. hashid_remove(struct hashid *hi, int id) {
  59. int h = id & hi->hashmod;
  60. struct hashid_node * c = hi->hash[h];
  61. if (c == NULL)
  62. return -1;
  63. if (c->id == id) {
  64. hi->hash[h] = c->next;
  65. goto _clear;
  66. }
  67. while(c->next) {
  68. if (c->next->id == id) {
  69. struct hashid_node * temp = c->next;
  70. c->next = temp->next;
  71. c = temp;
  72. goto _clear;
  73. }
  74. c = c->next;
  75. }
  76. return -1;
  77. _clear:
  78. c->id = -1;
  79. c->next = NULL;
  80. --hi->count;
  81. return c - hi->id;
  82. }
  83. static int
  84. hashid_insert(struct hashid * hi, int id) {
  85. struct hashid_node *c = NULL;
  86. int i;
  87. for (i=0;i<hi->cap;i++) {
  88. int index = (i+id) % hi->cap;
  89. if (hi->id[index].id == -1) {
  90. c = &hi->id[index];
  91. break;
  92. }
  93. }
  94. assert(c);
  95. ++hi->count;
  96. c->id = id;
  97. assert(c->next == NULL);
  98. int h = id & hi->hashmod;
  99. if (hi->hash[h]) {
  100. c->next = hi->hash[h];
  101. }
  102. hi->hash[h] = c;
  103. return c - hi->id;
  104. }
  105. static inline int
  106. hashid_full(struct hashid *hi) {
  107. return hi->count == hi->cap;
  108. }
  109. #endif