skip_list.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*!
  2. Temelia - Skip-list implementation source file.
  3. Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/skip_list.h"
  18. #include "include/common.h"
  19. #include <stdlib.h>
  20. struct _skip_list_t
  21. {
  22. /*! key reference */
  23. void *key;
  24. /*! node's level */
  25. int level;
  26. /*! array of pointers to neighbors */
  27. struct _skip_list_t **next;
  28. };
  29. static INLINE int _calculate_level(int max_level);
  30. skip_list_t skip_list_new(int max_level)
  31. {
  32. int i;
  33. skip_list_t skip_list;
  34. _ASSERT(max_level, <=, 0, INVALID_INPUT, NULL);
  35. /*
  36. * The first node in a skip list is used as sentinel; it doesn't store any key.
  37. */
  38. skip_list = (struct _skip_list_t *) _new(sizeof(struct _skip_list_t));
  39. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  40. skip_list->key = NULL;
  41. skip_list->level = max_level;
  42. skip_list->next = (struct _skip_list_t **) _new(max_level
  43. * sizeof(struct _skip_list_t *));
  44. if (skip_list->next == NULL)
  45. {
  46. _delete(skip_list);
  47. temelia_errno = NULL_POINTER;
  48. return NULL;
  49. }
  50. for (i = 0; i < max_level; i++)
  51. skip_list->next[i] = NULL;
  52. return skip_list;
  53. }
  54. void skip_list_node_delete(skip_list_t skip_list)
  55. {
  56. int i;
  57. _ASSERT(skip_list, ==, NULL, NULL_POINTER,);
  58. for (i = 0; i < skip_list->level; i++)
  59. skip_list->next[i] = NULL;
  60. skip_list->level = 0;
  61. skip_list->key = NULL;
  62. _delete(skip_list->next);
  63. _delete(skip_list);
  64. }
  65. void *skip_list_node_get_key(skip_list_t skip_list)
  66. {
  67. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  68. return skip_list->key;
  69. }
  70. void skip_list_node_set_key(skip_list_t skip_list, void *key)
  71. {
  72. _ASSERT(skip_list, ==, NULL, NULL_POINTER,);
  73. skip_list->key = key;
  74. }
  75. int skip_list_node_get_level(skip_list_t skip_list)
  76. {
  77. _ASSERT(skip_list, ==, NULL, NULL_POINTER, -1);
  78. return skip_list->level;
  79. }
  80. void *skip_list_node_get_next(skip_list_t skip_list)
  81. {
  82. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  83. return skip_list->next;
  84. }
  85. void *skip_list_node_get_next_level(skip_list_t skip_list, int level)
  86. {
  87. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  88. _ASSERT(level, <, 0, INVALID_INPUT, NULL);
  89. _ASSERT(level, >=, skip_list->level, INVALID_INPUT, NULL);
  90. return skip_list->next[level];
  91. }
  92. void skip_list_delete(skip_list_t skip_list)
  93. {
  94. skip_list_t it, prev;
  95. _ASSERT(skip_list, ==, NULL, NULL_POINTER,);
  96. it = skip_list;
  97. while (it)
  98. {
  99. prev = it;
  100. it = it->next[0];
  101. skip_list_node_delete(prev);
  102. }
  103. }
  104. skip_list_t skip_list_insert(skip_list_t skip_list, void *key, int compare(
  105. void *x, void *y, void *context), void *context)
  106. {
  107. skip_list_t *prevs, add, it;
  108. int level, i;
  109. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  110. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  111. prevs = (skip_list_t *) _new(skip_list->level * sizeof(skip_list_t));
  112. it = skip_list;
  113. for (level = skip_list->level - 1; level >= 0; level--)
  114. {
  115. while (it->next[level] != NULL && compare(it->next[level]->key, key,
  116. context) < 0)
  117. it = it->next[level];
  118. prevs[level] = it;
  119. }
  120. // Key already exists.
  121. if (it->next[0] && !compare(it->next[0]->key, key, context))
  122. {
  123. _delete(prevs);
  124. /*
  125. * FIXME: return NULL if key already exists in skip-list ?
  126. * Or return the node containing that key ?
  127. */
  128. return NULL;
  129. //return it->next[0];
  130. }
  131. level = _calculate_level(skip_list->level);
  132. add = skip_list_new(level);
  133. _ASSERT(add, ==, NULL, NULL_POINTER, NULL);
  134. add->key = key;
  135. for (i = 0; i < level; i++)
  136. {
  137. add->next[i] = prevs[i]->next[i];
  138. prevs[i]->next[i] = add;
  139. }
  140. _delete(prevs);
  141. return add;
  142. }
  143. skip_list_t skip_list_search(skip_list_t skip_list, void *key, int compare(
  144. void *x, void *y, void *context), void *context)
  145. {
  146. skip_list_t *prevs;
  147. skip_list_t it;
  148. int level;
  149. _ASSERT(skip_list, ==, NULL, NULL_POINTER, NULL);
  150. _ASSERT(compare, ==, NULL, NULL_POINTER, NULL);
  151. prevs = (skip_list_t *) _new(skip_list->level * sizeof(skip_list_t));
  152. it = skip_list;
  153. for (level = skip_list->level - 1; level >= 0; level--)
  154. {
  155. while (it->next[level] != NULL && compare(it->next[level]->key, key,
  156. context) < 0)
  157. it = it->next[level];
  158. prevs[level] = it;
  159. }
  160. // return NULL if key isn't found.
  161. if (it->next[0] == NULL || compare(it->next[0]->key, key, context))
  162. {
  163. _delete(prevs);
  164. return NULL;
  165. }
  166. _delete(prevs);
  167. return it->next[0];
  168. }
  169. int skip_list_remove(skip_list_t skip_list, void *key, int compare(void *x,
  170. void *y, void *context), void *context)
  171. {
  172. skip_list_t *prevs;
  173. skip_list_t it;
  174. int level, i;
  175. _ASSERT(skip_list, ==, NULL, NULL_POINTER, -1);
  176. _ASSERT(compare, ==, NULL, NULL_POINTER, -1);
  177. prevs = (skip_list_t *) _new(skip_list->level * sizeof(skip_list_t));
  178. it = skip_list;
  179. for (level = skip_list->level - 1; level >= 0; level--)
  180. {
  181. while (it->next[level] != NULL && compare(it->next[level]->key, key,
  182. context) < 0)
  183. it = it->next[level];
  184. prevs[level] = it;
  185. }
  186. // return NULL if key isn't found.
  187. if (it->next[0] == NULL || compare(it->next[0]->key, key, context))
  188. {
  189. _delete(prevs);
  190. return 0;
  191. }
  192. it = it->next[0];
  193. for (i = 0; i < it->level; i++)
  194. prevs[i]->next[i] = it->next[i];
  195. _delete(prevs);
  196. skip_list_node_delete(it);
  197. return 1;
  198. }
  199. void skip_list_iterate(skip_list_t skip_list_, void key_handler(void *x,
  200. void *context), void *context)
  201. {
  202. skip_list_t it;
  203. _ASSERT(skip_list_, ==, NULL, NULL_POINTER,);
  204. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  205. for (it = skip_list_->next[0]; it != NULL; key_handler(it->key, context), it
  206. = it->next[0])
  207. ;
  208. }
  209. void skip_list_iterate_level(skip_list_t skip_list_, int level,
  210. void key_handler(void *x, void *context), void *context)
  211. {
  212. skip_list_t it;
  213. _ASSERT(skip_list_, ==, NULL, NULL_POINTER,);
  214. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  215. _ASSERT(level, <, 0, INVALID_INPUT,);
  216. _ASSERT(level, >=, skip_list_->level, INVALID_INPUT,);
  217. it = skip_list_->next[level];
  218. while (it)
  219. {
  220. key_handler(it->key, context);
  221. it = it->next[level];
  222. }
  223. }
  224. static INLINE int _calculate_level(int max_level)
  225. {
  226. int level = 1;
  227. while (_rand() % 2)
  228. ++level;
  229. return level;
  230. }