smartlist.c 24 KB

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