smartlist.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file smartlist.c
  7. *
  8. * \brief Higher-level functions for the "smartlist" resizeable array
  9. * abstraction.
  10. *
  11. * The functions declared here use higher-level functionality than those in
  12. * smartlist_core.c, and handle things like smartlists of different types,
  13. * sorting, searching, heap-structured smartlists, and other convenience
  14. * functions.
  15. **/
  16. #include "lib/container/smartlist.h"
  17. #include "lib/err/torerr.h"
  18. #include "lib/malloc/malloc.h"
  19. #include "lib/defs/digest_sizes.h"
  20. #include "lib/ctime/di_ops.h"
  21. #include "lib/string/compat_ctype.h"
  22. #include "lib/string/compat_string.h"
  23. #include "lib/string/util_string.h"
  24. #include "lib/string/printf.h"
  25. #include "lib/log/util_bug.h"
  26. #include <stdlib.h>
  27. #include <string.h>
  28. /** Append the string produced by tor_asprintf(<b>pattern</b>, <b>...</b>)
  29. * to <b>sl</b>. */
  30. void
  31. smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern, ...)
  32. {
  33. va_list ap;
  34. va_start(ap, pattern);
  35. smartlist_add_vasprintf(sl, pattern, ap);
  36. va_end(ap);
  37. }
  38. /** va_list-based backend of smartlist_add_asprintf. */
  39. void
  40. smartlist_add_vasprintf(struct smartlist_t *sl, const char *pattern,
  41. va_list args)
  42. {
  43. char *str = NULL;
  44. tor_vasprintf(&str, pattern, args);
  45. tor_assert(str != NULL);
  46. smartlist_add(sl, str);
  47. }
  48. /** Reverse the order of the items in <b>sl</b>. */
  49. void
  50. smartlist_reverse(smartlist_t *sl)
  51. {
  52. int i, j;
  53. void *tmp;
  54. tor_assert(sl);
  55. for (i = 0, j = sl->num_used-1; i < j; ++i, --j) {
  56. tmp = sl->list[i];
  57. sl->list[i] = sl->list[j];
  58. sl->list[j] = tmp;
  59. }
  60. }
  61. /** If there are any strings in sl equal to element, remove and free them.
  62. * Does not preserve order. */
  63. void
  64. smartlist_string_remove(smartlist_t *sl, const char *element)
  65. {
  66. int i;
  67. tor_assert(sl);
  68. tor_assert(element);
  69. for (i = 0; i < sl->num_used; ++i) {
  70. if (!strcmp(element, sl->list[i])) {
  71. tor_free(sl->list[i]);
  72. sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
  73. i--; /* so we process the new i'th element */
  74. sl->list[sl->num_used] = NULL;
  75. }
  76. }
  77. }
  78. /** Return true iff <b>sl</b> has some element E such that
  79. * !strcmp(E,<b>element</b>)
  80. */
  81. int
  82. smartlist_contains_string(const smartlist_t *sl, const char *element)
  83. {
  84. int i;
  85. if (!sl) return 0;
  86. for (i=0; i < sl->num_used; i++)
  87. if (strcmp((const char*)sl->list[i],element)==0)
  88. return 1;
  89. return 0;
  90. }
  91. /** If <b>element</b> is equal to an element of <b>sl</b>, return that
  92. * element's index. Otherwise, return -1. */
  93. int
  94. smartlist_string_pos(const smartlist_t *sl, const char *element)
  95. {
  96. int i;
  97. if (!sl) return -1;
  98. for (i=0; i < sl->num_used; i++)
  99. if (strcmp((const char*)sl->list[i],element)==0)
  100. return i;
  101. return -1;
  102. }
  103. /** If <b>element</b> is the same pointer as an element of <b>sl</b>, return
  104. * that element's index. Otherwise, return -1. */
  105. int
  106. smartlist_pos(const smartlist_t *sl, const void *element)
  107. {
  108. int i;
  109. if (!sl) return -1;
  110. for (i=0; i < sl->num_used; i++)
  111. if (element == sl->list[i])
  112. return i;
  113. return -1;
  114. }
  115. /** Return true iff <b>sl</b> has some element E such that
  116. * !strcasecmp(E,<b>element</b>)
  117. */
  118. int
  119. smartlist_contains_string_case(const smartlist_t *sl, const char *element)
  120. {
  121. int i;
  122. if (!sl) return 0;
  123. for (i=0; i < sl->num_used; i++)
  124. if (strcasecmp((const char*)sl->list[i],element)==0)
  125. return 1;
  126. return 0;
  127. }
  128. /** Return true iff <b>sl</b> has some element E such that E is equal
  129. * to the decimal encoding of <b>num</b>.
  130. */
  131. int
  132. smartlist_contains_int_as_string(const smartlist_t *sl, int num)
  133. {
  134. char buf[32]; /* long enough for 64-bit int, and then some. */
  135. tor_snprintf(buf,sizeof(buf),"%d", num);
  136. return smartlist_contains_string(sl, buf);
  137. }
  138. /** Return true iff the two lists contain the same strings in the same
  139. * order, or if they are both NULL. */
  140. int
  141. smartlist_strings_eq(const smartlist_t *sl1, const smartlist_t *sl2)
  142. {
  143. if (sl1 == NULL)
  144. return sl2 == NULL;
  145. if (sl2 == NULL)
  146. return 0;
  147. if (smartlist_len(sl1) != smartlist_len(sl2))
  148. return 0;
  149. SMARTLIST_FOREACH(sl1, const char *, cp1, {
  150. const char *cp2 = smartlist_get(sl2, cp1_sl_idx);
  151. if (strcmp(cp1, cp2))
  152. return 0;
  153. });
  154. return 1;
  155. }
  156. /** Return true iff the two lists contain the same int pointer values in
  157. * the same order, or if they are both NULL. */
  158. int
  159. smartlist_ints_eq(const smartlist_t *sl1, const smartlist_t *sl2)
  160. {
  161. if (sl1 == NULL)
  162. return sl2 == NULL;
  163. if (sl2 == NULL)
  164. return 0;
  165. if (smartlist_len(sl1) != smartlist_len(sl2))
  166. return 0;
  167. SMARTLIST_FOREACH(sl1, int *, cp1, {
  168. int *cp2 = smartlist_get(sl2, cp1_sl_idx);
  169. if (*cp1 != *cp2)
  170. return 0;
  171. });
  172. return 1;
  173. }
  174. /** Return true iff <b>sl</b> has some element E such that
  175. * tor_memeq(E,<b>element</b>,DIGEST_LEN)
  176. */
  177. int
  178. smartlist_contains_digest(const smartlist_t *sl, const char *element)
  179. {
  180. int i;
  181. if (!sl) return 0;
  182. for (i=0; i < sl->num_used; i++)
  183. if (tor_memeq((const char*)sl->list[i],element,DIGEST_LEN))
  184. return 1;
  185. return 0;
  186. }
  187. /** Return true iff some element E of sl2 has smartlist_contains(sl1,E).
  188. */
  189. int
  190. smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)
  191. {
  192. int i;
  193. for (i=0; i < sl2->num_used; i++)
  194. if (smartlist_contains(sl1, sl2->list[i]))
  195. return 1;
  196. return 0;
  197. }
  198. /** Remove every element E of sl1 such that !smartlist_contains(sl2,E).
  199. * Does not preserve the order of sl1.
  200. */
  201. void
  202. smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2)
  203. {
  204. int i;
  205. for (i=0; i < sl1->num_used; i++)
  206. if (!smartlist_contains(sl2, sl1->list[i])) {
  207. sl1->list[i] = sl1->list[--sl1->num_used]; /* swap with the end */
  208. i--; /* so we process the new i'th element */
  209. sl1->list[sl1->num_used] = NULL;
  210. }
  211. }
  212. /** Remove every element E of sl1 such that smartlist_contains(sl2,E).
  213. * Does not preserve the order of sl1.
  214. */
  215. void
  216. smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2)
  217. {
  218. int i;
  219. for (i=0; i < sl2->num_used; i++)
  220. smartlist_remove(sl1, sl2->list[i]);
  221. }
  222. /** Allocate and return a new string containing the concatenation of
  223. * the elements of <b>sl</b>, in order, separated by <b>join</b>. If
  224. * <b>terminate</b> is true, also terminate the string with <b>join</b>.
  225. * If <b>len_out</b> is not NULL, set <b>len_out</b> to the length of
  226. * the returned string. Requires that every element of <b>sl</b> is
  227. * NUL-terminated string.
  228. */
  229. char *
  230. smartlist_join_strings(smartlist_t *sl, const char *join,
  231. int terminate, size_t *len_out)
  232. {
  233. return smartlist_join_strings2(sl,join,strlen(join),terminate,len_out);
  234. }
  235. /** As smartlist_join_strings, but instead of separating/terminated with a
  236. * NUL-terminated string <b>join</b>, uses the <b>join_len</b>-byte sequence
  237. * at <b>join</b>. (Useful for generating a sequence of NUL-terminated
  238. * strings.)
  239. */
  240. char *
  241. smartlist_join_strings2(smartlist_t *sl, const char *join,
  242. size_t join_len, int terminate, size_t *len_out)
  243. {
  244. int i;
  245. size_t n = 0;
  246. char *r = NULL, *dst, *src;
  247. tor_assert(sl);
  248. tor_assert(join);
  249. if (terminate)
  250. n = join_len;
  251. for (i = 0; i < sl->num_used; ++i) {
  252. n += strlen(sl->list[i]);
  253. if (i+1 < sl->num_used) /* avoid double-counting the last one */
  254. n += join_len;
  255. }
  256. dst = r = tor_malloc(n+1);
  257. for (i = 0; i < sl->num_used; ) {
  258. for (src = sl->list[i]; *src; )
  259. *dst++ = *src++;
  260. if (++i < sl->num_used) {
  261. memcpy(dst, join, join_len);
  262. dst += join_len;
  263. }
  264. }
  265. if (terminate) {
  266. memcpy(dst, join, join_len);
  267. dst += join_len;
  268. }
  269. *dst = '\0';
  270. if (len_out)
  271. *len_out = dst-r;
  272. return r;
  273. }
  274. /** Sort the members of <b>sl</b> into an order defined by
  275. * the ordering function <b>compare</b>, which returns less then 0 if a
  276. * precedes b, greater than 0 if b precedes a, and 0 if a 'equals' b.
  277. */
  278. void
  279. smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b))
  280. {
  281. if (!sl->num_used)
  282. return;
  283. qsort(sl->list, sl->num_used, sizeof(void*),
  284. (int (*)(const void *,const void*))compare);
  285. }
  286. /** Given a smartlist <b>sl</b> sorted with the function <b>compare</b>,
  287. * return the most frequent member in the list. Break ties in favor of
  288. * later elements. If the list is empty, return NULL. If count_out is
  289. * non-null, set it to the count of the most frequent member.
  290. */
  291. void *
  292. smartlist_get_most_frequent_(const smartlist_t *sl,
  293. int (*compare)(const void **a, const void **b),
  294. int *count_out)
  295. {
  296. const void *most_frequent = NULL;
  297. int most_frequent_count = 0;
  298. const void *cur = NULL;
  299. int i, count=0;
  300. if (!sl->num_used) {
  301. if (count_out)
  302. *count_out = 0;
  303. return NULL;
  304. }
  305. for (i = 0; i < sl->num_used; ++i) {
  306. const void *item = sl->list[i];
  307. if (cur && 0 == compare(&cur, &item)) {
  308. ++count;
  309. } else {
  310. if (cur && count >= most_frequent_count) {
  311. most_frequent = cur;
  312. most_frequent_count = count;
  313. }
  314. cur = item;
  315. count = 1;
  316. }
  317. }
  318. if (cur && count >= most_frequent_count) {
  319. most_frequent = cur;
  320. most_frequent_count = count;
  321. }
  322. if (count_out)
  323. *count_out = most_frequent_count;
  324. return (void*)most_frequent;
  325. }
  326. /** Given a sorted smartlist <b>sl</b> and the comparison function used to
  327. * sort it, remove all duplicate members. If free_fn is provided, calls
  328. * free_fn on each duplicate. Otherwise, just removes them. Preserves order.
  329. */
  330. void
  331. smartlist_uniq(smartlist_t *sl,
  332. int (*compare)(const void **a, const void **b),
  333. void (*free_fn)(void *a))
  334. {
  335. int i;
  336. for (i=1; i < sl->num_used; ++i) {
  337. if (compare((const void **)&(sl->list[i-1]),
  338. (const void **)&(sl->list[i])) == 0) {
  339. if (free_fn)
  340. free_fn(sl->list[i]);
  341. smartlist_del_keeporder(sl, i--);
  342. }
  343. }
  344. }
  345. /** Assuming the members of <b>sl</b> are in order, return a pointer to the
  346. * member that matches <b>key</b>. Ordering and matching are defined by a
  347. * <b>compare</b> function that returns 0 on a match; less than 0 if key is
  348. * less than member, and greater than 0 if key is greater then member.
  349. */
  350. void *
  351. smartlist_bsearch(smartlist_t *sl, const void *key,
  352. int (*compare)(const void *key, const void **member))
  353. {
  354. int found, idx;
  355. idx = smartlist_bsearch_idx(sl, key, compare, &found);
  356. return found ? smartlist_get(sl, idx) : NULL;
  357. }
  358. /** Assuming the members of <b>sl</b> are in order, return the index of the
  359. * member that matches <b>key</b>. If no member matches, return the index of
  360. * the first member greater than <b>key</b>, or smartlist_len(sl) if no member
  361. * is greater than <b>key</b>. Set <b>found_out</b> to true on a match, to
  362. * false otherwise. Ordering and matching are defined by a <b>compare</b>
  363. * function that returns 0 on a match; less than 0 if key is less than member,
  364. * and greater than 0 if key is greater then member.
  365. */
  366. int
  367. smartlist_bsearch_idx(const smartlist_t *sl, const void *key,
  368. int (*compare)(const void *key, const void **member),
  369. int *found_out)
  370. {
  371. int hi, lo, cmp, mid, len, diff;
  372. tor_assert(sl);
  373. tor_assert(compare);
  374. tor_assert(found_out);
  375. len = smartlist_len(sl);
  376. /* Check for the trivial case of a zero-length list */
  377. if (len == 0) {
  378. *found_out = 0;
  379. /* We already know smartlist_len(sl) is 0 in this case */
  380. return 0;
  381. }
  382. /* Okay, we have a real search to do */
  383. tor_assert(len > 0);
  384. lo = 0;
  385. hi = len - 1;
  386. /*
  387. * These invariants are always true:
  388. *
  389. * For all i such that 0 <= i < lo, sl[i] < key
  390. * For all i such that hi < i <= len, sl[i] > key
  391. */
  392. while (lo <= hi) {
  393. diff = hi - lo;
  394. /*
  395. * We want mid = (lo + hi) / 2, but that could lead to overflow, so
  396. * instead diff = hi - lo (non-negative because of loop condition), and
  397. * then hi = lo + diff, mid = (lo + lo + diff) / 2 = lo + (diff / 2).
  398. */
  399. mid = lo + (diff / 2);
  400. cmp = compare(key, (const void**) &(sl->list[mid]));
  401. if (cmp == 0) {
  402. /* sl[mid] == key; we found it */
  403. *found_out = 1;
  404. return mid;
  405. } else if (cmp > 0) {
  406. /*
  407. * key > sl[mid] and an index i such that sl[i] == key must
  408. * have i > mid if it exists.
  409. */
  410. /*
  411. * Since lo <= mid <= hi, hi can only decrease on each iteration (by
  412. * being set to mid - 1) and hi is initially len - 1, mid < len should
  413. * always hold, and this is not symmetric with the left end of list
  414. * mid > 0 test below. A key greater than the right end of the list
  415. * should eventually lead to lo == hi == mid == len - 1, and then
  416. * we set lo to len below and fall out to the same exit we hit for
  417. * a key in the middle of the list but not matching. Thus, we just
  418. * assert for consistency here rather than handle a mid == len case.
  419. */
  420. tor_assert(mid < len);
  421. /* Move lo to the element immediately after sl[mid] */
  422. lo = mid + 1;
  423. } else {
  424. /* This should always be true in this case */
  425. tor_assert(cmp < 0);
  426. /*
  427. * key < sl[mid] and an index i such that sl[i] == key must
  428. * have i < mid if it exists.
  429. */
  430. if (mid > 0) {
  431. /* Normal case, move hi to the element immediately before sl[mid] */
  432. hi = mid - 1;
  433. } else {
  434. /* These should always be true in this case */
  435. tor_assert(mid == lo);
  436. tor_assert(mid == 0);
  437. /*
  438. * We were at the beginning of the list and concluded that every
  439. * element e compares e > key.
  440. */
  441. *found_out = 0;
  442. return 0;
  443. }
  444. }
  445. }
  446. /*
  447. * lo > hi; we have no element matching key but we have elements falling
  448. * on both sides of it. The lo index points to the first element > key.
  449. */
  450. tor_assert(lo == hi + 1); /* All other cases should have been handled */
  451. tor_assert(lo >= 0);
  452. tor_assert(lo <= len);
  453. tor_assert(hi >= 0);
  454. tor_assert(hi <= len);
  455. if (lo < len) {
  456. cmp = compare(key, (const void **) &(sl->list[lo]));
  457. tor_assert(cmp < 0);
  458. } else {
  459. cmp = compare(key, (const void **) &(sl->list[len-1]));
  460. tor_assert(cmp > 0);
  461. }
  462. *found_out = 0;
  463. return lo;
  464. }
  465. /** Helper: compare two const char **s. */
  466. static int
  467. compare_string_ptrs_(const void **_a, const void **_b)
  468. {
  469. return strcmp((const char*)*_a, (const char*)*_b);
  470. }
  471. /** Sort a smartlist <b>sl</b> containing strings into lexically ascending
  472. * order. */
  473. void
  474. smartlist_sort_strings(smartlist_t *sl)
  475. {
  476. smartlist_sort(sl, compare_string_ptrs_);
  477. }
  478. /** Return the most frequent string in the sorted list <b>sl</b> */
  479. const char *
  480. smartlist_get_most_frequent_string(smartlist_t *sl)
  481. {
  482. return smartlist_get_most_frequent(sl, compare_string_ptrs_);
  483. }
  484. /** Return the most frequent string in the sorted list <b>sl</b>.
  485. * If <b>count_out</b> is provided, set <b>count_out</b> to the
  486. * number of times that string appears.
  487. */
  488. const char *
  489. smartlist_get_most_frequent_string_(smartlist_t *sl, int *count_out)
  490. {
  491. return smartlist_get_most_frequent_(sl, compare_string_ptrs_, count_out);
  492. }
  493. /** Remove duplicate strings from a sorted list, and free them with tor_free().
  494. */
  495. void
  496. smartlist_uniq_strings(smartlist_t *sl)
  497. {
  498. smartlist_uniq(sl, compare_string_ptrs_, tor_free_);
  499. }
  500. /** Helper: compare two pointers. */
  501. static int
  502. compare_ptrs_(const void **_a, const void **_b)
  503. {
  504. const void *a = *_a, *b = *_b;
  505. if (a<b)
  506. return -1;
  507. else if (a==b)
  508. return 0;
  509. else
  510. return 1;
  511. }
  512. /** Sort <b>sl</b> in ascending order of the pointers it contains. */
  513. void
  514. smartlist_sort_pointers(smartlist_t *sl)
  515. {
  516. smartlist_sort(sl, compare_ptrs_);
  517. }
  518. /* Heap-based priority queue implementation for O(lg N) insert and remove.
  519. * Recall that the heap property is that, for every index I, h[I] <
  520. * H[LEFT_CHILD[I]] and h[I] < H[RIGHT_CHILD[I]].
  521. *
  522. * For us to remove items other than the topmost item, each item must store
  523. * its own index within the heap. When calling the pqueue functions, tell
  524. * them about the offset of the field that stores the index within the item.
  525. *
  526. * Example:
  527. *
  528. * typedef struct timer_t {
  529. * struct timeval tv;
  530. * int heap_index;
  531. * } timer_t;
  532. *
  533. * static int compare(const void *p1, const void *p2) {
  534. * const timer_t *t1 = p1, *t2 = p2;
  535. * if (t1->tv.tv_sec < t2->tv.tv_sec) {
  536. * return -1;
  537. * } else if (t1->tv.tv_sec > t2->tv.tv_sec) {
  538. * return 1;
  539. * } else {
  540. * return t1->tv.tv_usec - t2->tv_usec;
  541. * }
  542. * }
  543. *
  544. * void timer_heap_insert(smartlist_t *heap, timer_t *timer) {
  545. * smartlist_pqueue_add(heap, compare, offsetof(timer_t, heap_index),
  546. * timer);
  547. * }
  548. *
  549. * void timer_heap_pop(smartlist_t *heap) {
  550. * return smartlist_pqueue_pop(heap, compare,
  551. * offsetof(timer_t, heap_index));
  552. * }
  553. */
  554. /** @{ */
  555. /** Functions to manipulate heap indices to find a node's parent and children.
  556. *
  557. * For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x]
  558. * = 2*x + 1. But this is C, so we have to adjust a little. */
  559. /* MAX_PARENT_IDX is the largest IDX in the smartlist which might have
  560. * children whose indices fit inside an int.
  561. * LEFT_CHILD(MAX_PARENT_IDX) == INT_MAX-2;
  562. * RIGHT_CHILD(MAX_PARENT_IDX) == INT_MAX-1;
  563. * LEFT_CHILD(MAX_PARENT_IDX + 1) == INT_MAX // impossible, see max list size.
  564. */
  565. #define MAX_PARENT_IDX ((INT_MAX - 2) / 2)
  566. /* If this is true, then i is small enough to potentially have children
  567. * in the smartlist, and it is save to use LEFT_CHILD/RIGHT_CHILD on it. */
  568. #define IDX_MAY_HAVE_CHILDREN(i) ((i) <= MAX_PARENT_IDX)
  569. #define LEFT_CHILD(i) ( 2*(i) + 1 )
  570. #define RIGHT_CHILD(i) ( 2*(i) + 2 )
  571. #define PARENT(i) ( ((i)-1) / 2 )
  572. /** }@ */
  573. /** @{ */
  574. /** Helper macros for heaps: Given a local variable <b>idx_field_offset</b>
  575. * set to the offset of an integer index within the heap element structure,
  576. * IDX_OF_ITEM(p) gives you the index of p, and IDXP(p) gives you a pointer to
  577. * where p's index is stored. Given additionally a local smartlist <b>sl</b>,
  578. * UPDATE_IDX(i) sets the index of the element at <b>i</b> to the correct
  579. * value (that is, to <b>i</b>).
  580. */
  581. #define IDXP(p) ((int*)STRUCT_VAR_P(p, idx_field_offset))
  582. #define UPDATE_IDX(i) do { \
  583. void *updated = sl->list[i]; \
  584. *IDXP(updated) = i; \
  585. } while (0)
  586. #define IDX_OF_ITEM(p) (*IDXP(p))
  587. /** @} */
  588. /** Helper. <b>sl</b> may have at most one violation of the heap property:
  589. * the item at <b>idx</b> may be greater than one or both of its children.
  590. * Restore the heap property. */
  591. static inline void
  592. smartlist_heapify(smartlist_t *sl,
  593. int (*compare)(const void *a, const void *b),
  594. int idx_field_offset,
  595. int idx)
  596. {
  597. while (1) {
  598. if (! IDX_MAY_HAVE_CHILDREN(idx)) {
  599. /* idx is so large that it cannot have any children, since doing so
  600. * would mean the smartlist was over-capacity. Therefore it cannot
  601. * violate the heap property by being greater than a child (since it
  602. * doesn't have any). */
  603. return;
  604. }
  605. int left_idx = LEFT_CHILD(idx);
  606. int best_idx;
  607. if (left_idx >= sl->num_used)
  608. return;
  609. if (compare(sl->list[idx],sl->list[left_idx]) < 0)
  610. best_idx = idx;
  611. else
  612. best_idx = left_idx;
  613. if (left_idx+1 < sl->num_used &&
  614. compare(sl->list[left_idx+1],sl->list[best_idx]) < 0)
  615. best_idx = left_idx + 1;
  616. if (best_idx == idx) {
  617. return;
  618. } else {
  619. void *tmp = sl->list[idx];
  620. sl->list[idx] = sl->list[best_idx];
  621. sl->list[best_idx] = tmp;
  622. UPDATE_IDX(idx);
  623. UPDATE_IDX(best_idx);
  624. idx = best_idx;
  625. }
  626. }
  627. }
  628. /** Insert <b>item</b> into the heap stored in <b>sl</b>, where order is
  629. * determined by <b>compare</b> and the offset of the item in the heap is
  630. * stored in an int-typed field at position <b>idx_field_offset</b> within
  631. * item.
  632. */
  633. void
  634. smartlist_pqueue_add(smartlist_t *sl,
  635. int (*compare)(const void *a, const void *b),
  636. int idx_field_offset,
  637. void *item)
  638. {
  639. int idx;
  640. smartlist_add(sl,item);
  641. UPDATE_IDX(sl->num_used-1);
  642. for (idx = sl->num_used - 1; idx; ) {
  643. int parent = PARENT(idx);
  644. if (compare(sl->list[idx], sl->list[parent]) < 0) {
  645. void *tmp = sl->list[parent];
  646. sl->list[parent] = sl->list[idx];
  647. sl->list[idx] = tmp;
  648. UPDATE_IDX(parent);
  649. UPDATE_IDX(idx);
  650. idx = parent;
  651. } else {
  652. return;
  653. }
  654. }
  655. }
  656. /** Remove and return the top-priority item from the heap stored in <b>sl</b>,
  657. * where order is determined by <b>compare</b> and the item's position is
  658. * stored at position <b>idx_field_offset</b> within the item. <b>sl</b> must
  659. * not be empty. */
  660. void *
  661. smartlist_pqueue_pop(smartlist_t *sl,
  662. int (*compare)(const void *a, const void *b),
  663. int idx_field_offset)
  664. {
  665. void *top;
  666. tor_assert(sl->num_used);
  667. top = sl->list[0];
  668. *IDXP(top)=-1;
  669. if (--sl->num_used) {
  670. sl->list[0] = sl->list[sl->num_used];
  671. sl->list[sl->num_used] = NULL;
  672. UPDATE_IDX(0);
  673. smartlist_heapify(sl, compare, idx_field_offset, 0);
  674. }
  675. sl->list[sl->num_used] = NULL;
  676. return top;
  677. }
  678. /** Remove the item <b>item</b> from the heap stored in <b>sl</b>,
  679. * where order is determined by <b>compare</b> and the item's position is
  680. * stored at position <b>idx_field_offset</b> within the item. <b>sl</b> must
  681. * not be empty. */
  682. void
  683. smartlist_pqueue_remove(smartlist_t *sl,
  684. int (*compare)(const void *a, const void *b),
  685. int idx_field_offset,
  686. void *item)
  687. {
  688. int idx = IDX_OF_ITEM(item);
  689. tor_assert(idx >= 0);
  690. tor_assert(sl->list[idx] == item);
  691. --sl->num_used;
  692. *IDXP(item) = -1;
  693. if (idx == sl->num_used) {
  694. sl->list[sl->num_used] = NULL;
  695. return;
  696. } else {
  697. sl->list[idx] = sl->list[sl->num_used];
  698. sl->list[sl->num_used] = NULL;
  699. UPDATE_IDX(idx);
  700. smartlist_heapify(sl, compare, idx_field_offset, idx);
  701. }
  702. }
  703. /** Assert that the heap property is correctly maintained by the heap stored
  704. * in <b>sl</b>, where order is determined by <b>compare</b>. */
  705. void
  706. smartlist_pqueue_assert_ok(smartlist_t *sl,
  707. int (*compare)(const void *a, const void *b),
  708. int idx_field_offset)
  709. {
  710. int i;
  711. for (i = sl->num_used - 1; i >= 0; --i) {
  712. if (i>0)
  713. tor_assert(compare(sl->list[PARENT(i)], sl->list[i]) <= 0);
  714. tor_assert(IDX_OF_ITEM(sl->list[i]) == i);
  715. }
  716. }
  717. /** Helper: compare two DIGEST_LEN digests. */
  718. static int
  719. compare_digests_(const void **_a, const void **_b)
  720. {
  721. return tor_memcmp((const char*)*_a, (const char*)*_b, DIGEST_LEN);
  722. }
  723. /** Sort the list of DIGEST_LEN-byte digests into ascending order. */
  724. void
  725. smartlist_sort_digests(smartlist_t *sl)
  726. {
  727. smartlist_sort(sl, compare_digests_);
  728. }
  729. /** Remove duplicate digests from a sorted list, and free them with tor_free().
  730. */
  731. void
  732. smartlist_uniq_digests(smartlist_t *sl)
  733. {
  734. smartlist_uniq(sl, compare_digests_, tor_free_);
  735. }
  736. /** Helper: compare two DIGEST256_LEN digests. */
  737. static int
  738. compare_digests256_(const void **_a, const void **_b)
  739. {
  740. return tor_memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN);
  741. }
  742. /** Sort the list of DIGEST256_LEN-byte digests into ascending order. */
  743. void
  744. smartlist_sort_digests256(smartlist_t *sl)
  745. {
  746. smartlist_sort(sl, compare_digests256_);
  747. }
  748. /** Return the most frequent member of the sorted list of DIGEST256_LEN
  749. * digests in <b>sl</b> */
  750. const uint8_t *
  751. smartlist_get_most_frequent_digest256(smartlist_t *sl)
  752. {
  753. return smartlist_get_most_frequent(sl, compare_digests256_);
  754. }
  755. /** Remove duplicate 256-bit digests from a sorted list, and free them with
  756. * tor_free().
  757. */
  758. void
  759. smartlist_uniq_digests256(smartlist_t *sl)
  760. {
  761. smartlist_uniq(sl, compare_digests256_, tor_free_);
  762. }