smartlist.c 23 KB

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