erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

417 řádky
12 KiB

před 5 roky
  1. //
  2. // Created by fox on 2017/10/10.
  3. // Skip Lists: A Probabilistic Alternative to Balanced Trees
  4. // indexable skip list
  5. // duplicated score and node
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <limits.h>
  9. #include <string.h>
  10. #include "skiplist.h"
  11. #include <time.h>
  12. // from 0 to n
  13. #define SKIPLIST_MAX_LEVEL 15
  14. #define LEVEL_SIZE (SKIPLIST_MAX_LEVEL+1)
  15. #define RAND_UNIFORM(x) (int)((double)rand() / RAND_MAX * (x))
  16. /* Create a skiplist node with the specified number of levels. */
  17. snode *skiplistCreateNode(int level, int score, vtype value) {
  18. snode *zn =
  19. (snode *)icalloc(sizeof(*zn)+level*sizeof(struct skiplistLevel));
  20. zn->score = score;
  21. zn->value = value;
  22. return zn;
  23. }
  24. skiplist *skiplist_init(void)
  25. {
  26. time_t t;
  27. srand((unsigned)(time(&t)));
  28. snode *header = skiplistCreateNode(LEVEL_SIZE, INT_MAX, INT_MAX);
  29. for (int i = 0; i < LEVEL_SIZE; ++i) {
  30. header->level[i].span = 1;
  31. }
  32. skiplist *list = (skiplist *)imalloc(sizeof(skiplist));
  33. list->header = header;
  34. list->level = 0;
  35. list->size = 0;
  36. return list;
  37. }
  38. static int rand_level()
  39. {
  40. int level = 0;
  41. while (rand() < RAND_MAX / 2 && level < SKIPLIST_MAX_LEVEL)
  42. // while (arc4random() < INT_MAX && level < SKIPLIST_MAX_LEVEL)
  43. level++;
  44. return level;
  45. }
  46. // insert score,node into a skiplist, return 0
  47. int skiplist_insert(skiplist *list, int score, vtype value)
  48. {
  49. snode **update = (snode **)imalloc(sizeof(snode*) * (list->level + 1));
  50. unsigned int *fore_width = (unsigned int *)imalloc(sizeof(unsigned int) * (list->level + 1));
  51. snode *x = list->header;
  52. int i;
  53. for (i = list->level; i >= 0; i--) {
  54. fore_width[i] = 0;
  55. while (x->level[i].forward && x->level[i].forward->score <= score) {
  56. fore_width[i] += x->level[i].span;
  57. x = x->level[i].forward;
  58. }
  59. update[i] = x;
  60. }
  61. // assert(x->score <= score);
  62. int level = rand_level();
  63. list->size = list->size+1;
  64. x = skiplistCreateNode(level+1, score, value);
  65. // the lowest layer is one by one
  66. x->level[0].forward = update[0]->level[0].forward;
  67. x->level[0].span = 1;
  68. update[0]->level[0].forward = x;
  69. unsigned int temp_width;
  70. for (i = 1; i <= (list->level < level ? list->level : level); i++) {
  71. temp_width = fore_width[i-1] + update[i-1]->level[i-1].span;
  72. x->level[i].forward = update[i]->level[i].forward;
  73. x->level[i].span = update[i]->level[i].span + 1 - temp_width;
  74. update[i]->level[i].forward = x;
  75. update[i]->level[i].span = temp_width;
  76. }
  77. if (level > list->level) {
  78. // complete the new level
  79. temp_width = fore_width[list->level] + update[list->level]->level[list->level].span;
  80. for (i = list->level+1; i <= level; i++) {
  81. list->header->level[i].span = temp_width;
  82. list->header->level[i].forward = x;
  83. x->level[i].forward = NULL;
  84. x->level[i].span = list->size + 1 - temp_width;
  85. }
  86. list->level = level;
  87. }
  88. else {
  89. // complete the unreached level
  90. for (; i <= list->level; ++i) {
  91. update[i]->level[i].span++;
  92. }
  93. }
  94. ifree(update);
  95. ifree(fore_width);
  96. return 0;
  97. }
  98. int skiplist_update(skiplist *list, int score, vtype value, int old_score)
  99. {
  100. skiplist_delete(list, old_score, value);
  101. return skiplist_insert(list, score, value);
  102. }
  103. // search score in skiplist.
  104. // set the struct with index and first node if exists, otherwise set index 0
  105. void skiplist_search(skiplist *list, int score, skiplist_search_ret *ret)
  106. {
  107. snode *x = list->header;
  108. int temp_width = 1;
  109. for (int i = list->level; i >= 0; i--) {
  110. while (x->level[i].forward && x->level[i].forward->score < score) {
  111. temp_width += x->level[i].span;
  112. x = x->level[i].forward;
  113. }
  114. }
  115. x = x->level[0].forward;
  116. ret->index = temp_width;
  117. ret->node = x;
  118. }
  119. // first index of score
  120. int skiplist_index_of_score(skiplist *list, int score)
  121. {
  122. snode *x = list->header;
  123. int temp_width = 1;
  124. for (int i = list->level; i >= 0; i--) {
  125. while (x->level[i].forward && x->level[i].forward->score < score) {
  126. temp_width += x->level[i].span;
  127. x = x->level[i].forward;
  128. }
  129. }
  130. x = x->level[0].forward;
  131. // check if existed score
  132. if (x && x->score == score) {
  133. return temp_width;
  134. }
  135. return 0;
  136. }
  137. // search skiplist by index. Return the node if exists, otherwise NULL
  138. snode *skiplist_at(skiplist *list, int index)
  139. {
  140. snode *x = list->header;
  141. for (int i = list->level; i >= 0; i--) {
  142. while (x->level[i].forward) {
  143. if (x->level[i].span == index) {
  144. return x->level[i].forward;
  145. }
  146. if (x->level[i].span < index) {
  147. index -= x->level[i].span;
  148. x = x->level[i].forward;
  149. }
  150. else {
  151. break;
  152. }
  153. }
  154. }
  155. return NULL;
  156. }
  157. static void skiplist_node_free(snode *x)
  158. {
  159. if (x) {
  160. ifree(x);
  161. }
  162. }
  163. // delete by score,node. Return 0 if success, 1 if fail.
  164. int skiplist_delete(skiplist *list, int score, vtype value)
  165. {
  166. int i;
  167. snode **update = (snode **)imalloc(sizeof(snode*) * (list->level + 1));
  168. snode *x = list->header;
  169. // find every level before the specified node
  170. for (i = list->level; i >= 0; --i) {
  171. while (1) {
  172. if (!(x->level[i].forward) || x->level[i].forward->score > score) {
  173. update[i] = x;
  174. break;
  175. }
  176. if (x->level[i].forward->score < score) {
  177. x = x->level[i].forward;
  178. continue;
  179. }
  180. // find the first node with same score
  181. int j;
  182. update[i] = x;
  183. for (j = i-1; j >= 0; --j) {
  184. while (x->level[j].forward->score < score)
  185. x = x->level[j].forward;
  186. update[j] = x;
  187. }
  188. x = x->level[0].forward;
  189. snode *x_start_search = x;
  190. // find the first node with same score and node
  191. while (x && x->value != value && x->score == score) {
  192. x = x->level[0].forward;
  193. }
  194. if (x && x->score == score) {
  195. // now x is the node to find
  196. // find nodes for every level before the node to find
  197. if (x == x_start_search) {
  198. // done
  199. i = 0;
  200. break;
  201. }
  202. // j is used to judge if change the x_start_search
  203. j = 0;
  204. snode *iter;
  205. for (; i >= 0; --i)
  206. {
  207. if (j) {
  208. update[i] = x_start_search;
  209. iter = x_start_search->level[0].forward;
  210. } else{
  211. iter = x_start_search;
  212. }
  213. while (iter != x) {
  214. if (iter == update[i]->level[i].forward) {
  215. j = 1;
  216. x_start_search = iter;
  217. iter = iter->level[0].forward;
  218. update[i] = update[i]->level[i].forward;
  219. continue;
  220. }
  221. iter = iter->level[0].forward;
  222. }
  223. }
  224. i = 0;
  225. break;
  226. }
  227. else {
  228. // not found the node
  229. ifree(update);
  230. return 1;
  231. }
  232. }
  233. }
  234. if (x->score != score) {
  235. // not found the node
  236. ifree(update);
  237. return 1;
  238. }
  239. for (i = 0; i <= list->level && update[i]->level[i].forward == x; i++) {
  240. update[i]->level[i].forward = x->level[i].forward;
  241. update[i]->level[i].span += x->level[i].span - 1;
  242. }
  243. for (; i <= list->level; i++) {
  244. --(update[i]->level[i].span);
  245. }
  246. skiplist_node_free(x);
  247. while (list->level > 0 && list->header->level[list->level].forward == NULL)
  248. list->level--;
  249. list->size--;
  250. ifree(update);
  251. return 0;
  252. }
  253. // ifree the skiplist
  254. void skiplist_free(skiplist *list)
  255. {
  256. snode *current_node = list->header->level[0].forward;
  257. while(current_node != NULL) {
  258. snode *next_node = current_node->level[0].forward;
  259. skiplist_node_free(current_node);
  260. current_node = next_node;
  261. }
  262. ifree(list);
  263. }
  264. // print the skip list, just for test.
  265. static void skiplist_dump(skiplist *list)
  266. {
  267. int *width = (int *)imalloc(sizeof(int) * (list->level + 1) * list->size);
  268. memset(width, 0, sizeof(int) * (list->level + 1) * list->size);
  269. snode **tempn = (snode **)imalloc(sizeof(snode*) * (list->level + 1));
  270. int i = 0, j;
  271. snode *x = list->header->level[0].forward;
  272. for (j = 0; j <= list->level; ++j) {
  273. tempn[j] = list->header->level[j].forward;
  274. }
  275. while (tempn[0] != NULL) {
  276. for (j = 1; j <= list->level; ++j) {
  277. if (tempn[j] == tempn[0]) {
  278. width[list->size * j + i] = tempn[j]->level[j].span;
  279. tempn[j] = tempn[j]->level[j].forward;
  280. } else {
  281. break;
  282. }
  283. }
  284. tempn[0] = tempn[0]->level[0].forward;
  285. ++i;
  286. }
  287. for (j = list->level; j > 0; --j) {
  288. for (i = 0; i < list->size; ++i) {
  289. if (width[j * list->size + i] == 0)
  290. printf(" ");
  291. else
  292. printf("%d ", width[j * list->size + i]);
  293. }
  294. printf("\n");
  295. }
  296. while (x != NULL) {
  297. printf("%d:%d->", x->score, x->value);
  298. x = x->level[0].forward;
  299. }
  300. printf("NIL\n");
  301. ifree(width);
  302. ifree(tempn);
  303. }
  304. void test_skiplist(void) {
  305. time_t t;
  306. srand((unsigned)(time(&t)));
  307. int arr[][2] = { {3, 1}, {3,2}, {6,6}, {9,9}, {3, 3}, {1, 1}, {4, 4}, {8, 8}, {7, 7}, {5,5}}, i;
  308. // int arr[] = { 3, 6, 9}, i;
  309. skiplist_search_ret tempx;
  310. skiplist *list = skiplist_init();
  311. printf("search empty:--------------------\n");
  312. skiplist_search(list, 5, &tempx);
  313. if (tempx.index > 0) {
  314. printf("error, found not existed item!\n");
  315. }
  316. printf("delete empty:--------------------\n");
  317. skiplist_delete(list, 5, 2);
  318. printf("Insert:--------------------\n");
  319. for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
  320. skiplist_insert(list, arr[i][0], arr[i][1]);
  321. }
  322. skiplist_dump(list);
  323. printf("search empty:--------------------\n");
  324. skiplist_search(list, 5, &tempx);
  325. printf("index = %d\n", tempx.index);
  326. printf("Search by index:-----------\n");
  327. int indexes[] = { 11, 3, 10 };
  328. for (i = 0; i < sizeof(indexes) / sizeof(indexes[0]); i++) {
  329. snode *tempnode = skiplist_at(list, indexes[i]);
  330. if (tempnode) {
  331. printf("index = %d, score = %d, value = %d\n", indexes[i], tempnode->score, tempnode->value);
  332. } else {
  333. printf("no index = %d\n", indexes[i]);
  334. }
  335. }
  336. printf("Delete:--------------------\n");
  337. skiplist_delete(list, 3, 2);
  338. skiplist_delete(list, 3, 1);
  339. skiplist_delete(list, 6, 6);
  340. skiplist_dump(list);
  341. clock_t start, finish;
  342. start = clock();
  343. for (i = 0; i < 30*1000; ++i) {
  344. if (rand() < RAND_MAX / 5 * 3) {
  345. skiplist_insert(list, RAND_UNIFORM(100), RAND_UNIFORM(20));
  346. }
  347. else {
  348. skiplist_delete(list, RAND_UNIFORM(100), RAND_UNIFORM(20));
  349. }
  350. }
  351. finish = clock();
  352. double duration = (double)(finish - start) / CLOCKS_PER_SEC;
  353. printf( "%f seconds\n", duration );
  354. printf("Search:--------------------\n");
  355. int keys[] = { 0, 3, 7, 100, 11 };
  356. for (i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
  357. printf("index = %d, score = %d\n", skiplist_index_of_score(list, keys[i]), keys[i]);
  358. }
  359. skiplist_free(list);
  360. };