Loading src/common/container.c +74 −0 Original line number Diff line number Diff line Loading @@ -459,6 +459,42 @@ smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)) (int (*)(const void *,const void*))compare); } /** Given a smartlist <b>sl</b> sorted with the function <b>compare</b>, * return the most frequent member in the list. Break ties in favor of * later elements. If the list is empty, return NULL. */ void * smartlist_get_most_frequent(const smartlist_t *sl, int (*compare)(const void **a, const void **b)) { const void *most_frequent = NULL; int most_frequent_count = 0; const void **cur = NULL; int i, count=0; if (!sl->num_used) return NULL; for (i = 0; i < sl->num_used; ++i) { const void *item = sl->list[i]; if (cur && 0 == compare(cur, &item)) { ++count; } else { if (cur && count >= most_frequent_count) { most_frequent = *cur; most_frequent_count = count; } cur = &item; count = 1; } } if (cur && count >= most_frequent_count) { most_frequent = *cur; most_frequent_count = count; } return (void*)most_frequent; } /** Given a sorted smartlist <b>sl</b> and the comparison function used to * sort it, remove all duplicate members. If free_fn is provided, calls * free_fn on each duplicate. Otherwise, just removes them. Preserves order. Loading Loading @@ -550,6 +586,13 @@ smartlist_sort_strings(smartlist_t *sl) smartlist_sort(sl, _compare_string_ptrs); } /** Return the most frequent string in the sorted list <b>sl</b> */ char * smartlist_get_most_frequent_string(smartlist_t *sl) { return smartlist_get_most_frequent(sl, _compare_string_ptrs); } /** Remove duplicate strings from a sorted list, and free them with tor_free(). */ void Loading Loading @@ -681,6 +724,37 @@ smartlist_uniq_digests(smartlist_t *sl) smartlist_uniq(sl, _compare_digests, _tor_free); } /** Helper: compare two DIGEST256_LEN digests. */ static int _compare_digests256(const void **_a, const void **_b) { return memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN); } /** Sort the list of DIGEST256_LEN-byte digests into ascending order. */ void smartlist_sort_digests256(smartlist_t *sl) { smartlist_sort(sl, _compare_digests256); } /** Return the most frequent member of the sorted list of DIGEST256_LEN * digests in <b>sl</b> */ char * smartlist_get_most_frequent_digest256(smartlist_t *sl) { return smartlist_get_most_frequent(sl, _compare_digests256); } /** Remove duplicate 256-bit digests from a sorted list, and free them with * tor_free(). */ void smartlist_uniq_digests256(smartlist_t *sl) { smartlist_uniq(sl, _compare_digests256, _tor_free); } /** Helper: Declare an entry type and a map type to implement a mapping using * ht.h. The map type will be called <b>maptype</b>. The key part of each * entry is declared using the C declaration <b>keydecl</b>. All functions Loading src/common/container.h +9 −0 Original line number Diff line number Diff line Loading @@ -93,13 +93,22 @@ void smartlist_del_keeporder(smartlist_t *sl, int idx); void smartlist_insert(smartlist_t *sl, int idx, void *val); void smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)); void *smartlist_get_most_frequent(const smartlist_t *sl, int (*compare)(const void **a, const void **b)); void smartlist_uniq(smartlist_t *sl, int (*compare)(const void **a, const void **b), void (*free_fn)(void *elt)); void smartlist_sort_strings(smartlist_t *sl); void smartlist_sort_digests(smartlist_t *sl); void smartlist_sort_digests256(smartlist_t *sl); char *smartlist_get_most_frequent_string(smartlist_t *sl); char *smartlist_get_most_frequent_digest256(smartlist_t *sl); void smartlist_uniq_strings(smartlist_t *sl); void smartlist_uniq_digests(smartlist_t *sl); void smartlist_uniq_digests256(smartlist_t *sl); void *smartlist_bsearch(smartlist_t *sl, const void *key, int (*compare)(const void *key, const void **member)) ATTR_PURE; Loading Loading
src/common/container.c +74 −0 Original line number Diff line number Diff line Loading @@ -459,6 +459,42 @@ smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)) (int (*)(const void *,const void*))compare); } /** Given a smartlist <b>sl</b> sorted with the function <b>compare</b>, * return the most frequent member in the list. Break ties in favor of * later elements. If the list is empty, return NULL. */ void * smartlist_get_most_frequent(const smartlist_t *sl, int (*compare)(const void **a, const void **b)) { const void *most_frequent = NULL; int most_frequent_count = 0; const void **cur = NULL; int i, count=0; if (!sl->num_used) return NULL; for (i = 0; i < sl->num_used; ++i) { const void *item = sl->list[i]; if (cur && 0 == compare(cur, &item)) { ++count; } else { if (cur && count >= most_frequent_count) { most_frequent = *cur; most_frequent_count = count; } cur = &item; count = 1; } } if (cur && count >= most_frequent_count) { most_frequent = *cur; most_frequent_count = count; } return (void*)most_frequent; } /** Given a sorted smartlist <b>sl</b> and the comparison function used to * sort it, remove all duplicate members. If free_fn is provided, calls * free_fn on each duplicate. Otherwise, just removes them. Preserves order. Loading Loading @@ -550,6 +586,13 @@ smartlist_sort_strings(smartlist_t *sl) smartlist_sort(sl, _compare_string_ptrs); } /** Return the most frequent string in the sorted list <b>sl</b> */ char * smartlist_get_most_frequent_string(smartlist_t *sl) { return smartlist_get_most_frequent(sl, _compare_string_ptrs); } /** Remove duplicate strings from a sorted list, and free them with tor_free(). */ void Loading Loading @@ -681,6 +724,37 @@ smartlist_uniq_digests(smartlist_t *sl) smartlist_uniq(sl, _compare_digests, _tor_free); } /** Helper: compare two DIGEST256_LEN digests. */ static int _compare_digests256(const void **_a, const void **_b) { return memcmp((const char*)*_a, (const char*)*_b, DIGEST256_LEN); } /** Sort the list of DIGEST256_LEN-byte digests into ascending order. */ void smartlist_sort_digests256(smartlist_t *sl) { smartlist_sort(sl, _compare_digests256); } /** Return the most frequent member of the sorted list of DIGEST256_LEN * digests in <b>sl</b> */ char * smartlist_get_most_frequent_digest256(smartlist_t *sl) { return smartlist_get_most_frequent(sl, _compare_digests256); } /** Remove duplicate 256-bit digests from a sorted list, and free them with * tor_free(). */ void smartlist_uniq_digests256(smartlist_t *sl) { smartlist_uniq(sl, _compare_digests256, _tor_free); } /** Helper: Declare an entry type and a map type to implement a mapping using * ht.h. The map type will be called <b>maptype</b>. The key part of each * entry is declared using the C declaration <b>keydecl</b>. All functions Loading
src/common/container.h +9 −0 Original line number Diff line number Diff line Loading @@ -93,13 +93,22 @@ void smartlist_del_keeporder(smartlist_t *sl, int idx); void smartlist_insert(smartlist_t *sl, int idx, void *val); void smartlist_sort(smartlist_t *sl, int (*compare)(const void **a, const void **b)); void *smartlist_get_most_frequent(const smartlist_t *sl, int (*compare)(const void **a, const void **b)); void smartlist_uniq(smartlist_t *sl, int (*compare)(const void **a, const void **b), void (*free_fn)(void *elt)); void smartlist_sort_strings(smartlist_t *sl); void smartlist_sort_digests(smartlist_t *sl); void smartlist_sort_digests256(smartlist_t *sl); char *smartlist_get_most_frequent_string(smartlist_t *sl); char *smartlist_get_most_frequent_digest256(smartlist_t *sl); void smartlist_uniq_strings(smartlist_t *sl); void smartlist_uniq_digests(smartlist_t *sl); void smartlist_uniq_digests256(smartlist_t *sl); void *smartlist_bsearch(smartlist_t *sl, const void *key, int (*compare)(const void *key, const void **member)) ATTR_PURE; Loading