Guest User

Untitled

a guest
May 20th, 2018
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.71 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <uv.h>
  4. #include <dispatch/dispatch.h>
  5.  
  6. #define DICTIONARY_MAX_BUCKETS 128
  7.  
  8. typedef void (*hh_dictionary_cb_t)(int id, void *data, void *ctx);
  9.  
  10. typedef struct hh_dictionary_bucket_entry_s {
  11. int id;
  12. void *data;
  13. struct hh_dictionary_bucket_entry_s *next;
  14. void *ctx;
  15. } hh_dictionary_bucket_entry_t;
  16.  
  17. typedef struct hh_dictionary_bucket_s {
  18. hh_dictionary_bucket_entry_t *entry;
  19. } hh_dictionary_bucket_t;
  20.  
  21. typedef struct hh_dictionary_s {
  22. hh_dictionary_bucket_t **buckets;
  23.  
  24. int size;
  25. uv_rwlock_t *mutex;
  26. } hh_dictionary_t;
  27.  
  28. typedef struct hh_dictionary_iter_ctx_s {
  29. int id;
  30. void *data;
  31. char dispatch_group;
  32. hh_dictionary_cb_t cb;
  33. } hh_dictionary_iter_ctx_t;
  34.  
  35. hh_dictionary_t *hh_dictionary_create() {
  36. hh_dictionary_t *dict = malloc(sizeof(hh_dictionary_t));
  37.  
  38. dict->size = 0;
  39. dict->buckets = calloc(DICTIONARY_MAX_BUCKETS, sizeof(hh_dictionary_bucket_t));
  40. dict->mutex = malloc(sizeof(uv_rwlock_t));
  41.  
  42. uv_rwlock_init(dict->mutex);
  43.  
  44. return dict;
  45. }
  46.  
  47. void hh_dictionary_dispose(hh_dictionary_t *dict) {
  48.  
  49. }
  50.  
  51. void hh_dictionary_add(int id, void *data, hh_dictionary_t *dict) {
  52. uv_rwlock_wrlock(dict->mutex);
  53.  
  54. if (dict->buckets[id % DICTIONARY_MAX_BUCKETS] == NULL) {
  55. dict->buckets[id % DICTIONARY_MAX_BUCKETS] = malloc(sizeof(hh_dictionary_bucket_t));
  56. dict->buckets[id % DICTIONARY_MAX_BUCKETS]->entry = NULL;
  57. }
  58.  
  59. hh_dictionary_bucket_t *bucket = dict->buckets[id % DICTIONARY_MAX_BUCKETS];
  60. hh_dictionary_bucket_entry_t *new_entry = malloc(sizeof(hh_dictionary_bucket_entry_t));
  61.  
  62. new_entry->id = id;
  63. new_entry->data = data;
  64. new_entry->next = NULL;
  65.  
  66. if (bucket->entry == NULL || bucket->entry->id == 0) {
  67. dict->size++;
  68. bucket->entry = new_entry;
  69. } else {
  70. hh_dictionary_bucket_entry_t *entry = bucket->entry;
  71.  
  72. while (entry->next != NULL) {
  73. entry = entry->next;
  74. }
  75. dict->size++;
  76. entry->next = new_entry;
  77. }
  78.  
  79. uv_rwlock_wrunlock(dict->mutex);
  80. }
  81.  
  82. void *hh_dictionary_get(int id, hh_dictionary_t *dict) {
  83. uv_rwlock_rdlock(dict->mutex);
  84.  
  85. hh_dictionary_bucket_t *bucket = dict->buckets[id % DICTIONARY_MAX_BUCKETS];
  86.  
  87. if (bucket == NULL) {
  88. uv_rwlock_rdunlock(dict->mutex);
  89. return NULL;
  90. }
  91.  
  92. hh_dictionary_bucket_entry_t *entry = bucket->entry;
  93.  
  94. if (entry->id == id) {
  95. uv_rwlock_rdunlock(dict->mutex);
  96.  
  97. return entry->data;
  98. }
  99.  
  100. while (entry->next != NULL) {
  101. entry = entry->next;
  102.  
  103. if (entry->id == id) {
  104. uv_rwlock_rdunlock(dict->mutex);
  105. return entry->data;
  106. }
  107. }
  108.  
  109. uv_rwlock_rdunlock(dict->mutex);
  110. return NULL;
  111. }
  112.  
  113. void *hh_dictionary_remove(int id, hh_dictionary_t *dict) {
  114. uv_rwlock_wrlock(dict->mutex);
  115.  
  116. hh_dictionary_bucket_t *bucket = dict->buckets[id % DICTIONARY_MAX_BUCKETS];
  117.  
  118. if (bucket == NULL) {
  119. uv_rwlock_wrunlock(dict->mutex);
  120. return NULL;
  121. }
  122.  
  123. hh_dictionary_bucket_entry_t *entry = bucket->entry;
  124.  
  125. while (entry->next != NULL) {
  126. if (entry->next->id == id) {
  127. hh_dictionary_bucket_entry_t *remove = entry->next;
  128.  
  129. entry->next = remove->next;
  130. void *data = remove->data;
  131.  
  132. free(remove);
  133.  
  134. dict->size--;
  135.  
  136. uv_rwlock_wrunlock(dict->mutex);
  137. return data;
  138. }
  139.  
  140. entry = entry->next;
  141. }
  142.  
  143. uv_rwlock_wrunlock(dict->mutex);
  144. return NULL;
  145. }
  146.  
  147. void exec_callback(hh_dictionary_iter_ctx_t *ctx) {
  148. ctx->cb(ctx->id, ctx->data, NULL);
  149.  
  150. free(ctx);
  151. }
  152.  
  153. void init_callback(int id, void *data, void *ctx) {
  154. hh_dictionary_iter_ctx_t *iter = malloc(sizeof(hh_dictionary_iter_ctx_t));
  155.  
  156. memcpy(iter, ctx, sizeof(hh_dictionary_iter_ctx_t));
  157. iter->id = id;
  158. iter->data = data;
  159.  
  160. hh_dispatch(iter->dispatch_group, (hh_dispatch_cb_t) &exec_callback, iter);
  161. }
  162.  
  163. void hh_dictionary_iterate(hh_dictionary_cb_t cb, void *ctx, hh_dictionary_t *dict) {
  164. uv_rwlock_rdlock(dict->mutex);
  165.  
  166. for (int d = 0; d < DICTIONARY_MAX_BUCKETS; d++) {
  167. if (dict->buckets[d] != NULL) {
  168. hh_dictionary_bucket_entry_t *entry = dict->buckets[d]->entry;
  169.  
  170. while (entry != NULL) {
  171. cb(entry->id, entry->data, ctx);
  172.  
  173. entry = entry->next;
  174. }
  175. }
  176. }
  177.  
  178. uv_rwlock_rdunlock(dict->mutex);
  179. }
  180.  
  181. void hh_dictionary_iterate_async(hh_dictionary_cb_t cb, char dispatch_group, hh_dictionary_t *dict) {
  182. hh_dictionary_iter_ctx_t *ctx = malloc(sizeof(hh_dictionary_iter_ctx_t));
  183.  
  184. ctx->cb = cb;
  185. ctx->dispatch_group = dispatch_group;
  186.  
  187. printf("ctx id %i %s %i %i\n", ctx->id, (char *) ctx->data, (int) ctx->cb, (int) ctx);
  188. hh_dictionary_iterate(&init_callback, ctx, dict);
  189. free(ctx);
  190. }
Add Comment
Please, Sign In to add comment