From 2403ef66bada5f1fb851ce424af4ab5916faca67 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 8 Feb 2013 12:09:46 -0500 Subject: [PATCH] Coalesce identical adjacent microdescriptor vote lines. --- changes/bug8158 | 3 +++ src/or/dirvote.c | 55 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 changes/bug8158 diff --git a/changes/bug8158 b/changes/bug8158 new file mode 100644 index 000000000..65b21c2a2 --- /dev/null +++ b/changes/bug8158 @@ -0,0 +1,3 @@ + o Minor bugfixes: + - Use less space when formatting identical microdescriptor lines in + directory votes. Fixes bug 8158; bugfix on 0.2.4.1-alpha. diff --git a/src/or/dirvote.c b/src/or/dirvote.c index baaff488d..c10a60fa7 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -3664,31 +3664,66 @@ static const struct consensus_method_range_t { {-1, -1} }; +typedef struct microdesc_vote_line_t { + int low; + int high; + microdesc_t *md; + struct microdesc_vote_line_t *next; +} microdesc_vote_line_t; + vote_microdesc_hash_t * dirvote_format_all_microdesc_vote_lines(const routerinfo_t *ri, time_t now, smartlist_t *microdescriptors_out) { const struct consensus_method_range_t *cmr; + microdesc_vote_line_t *entries = NULL, *ep; vote_microdesc_hash_t *result = NULL; + /* Generate the microdescriptors. */ for (cmr = microdesc_consensus_methods; cmr->low != -1 && cmr->high != -1; cmr++) { microdesc_t *md = dirvote_create_microdescriptor(ri, cmr->low); if (md) { - char buf[128]; - vote_microdesc_hash_t *h; - dirvote_format_microdesc_vote_line(buf, sizeof(buf), md, - cmr->low, cmr->high); - h = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); - h->microdesc_hash_line = tor_strdup(buf); - h->next = result; - result = h; - md->last_listed = now; - smartlist_add(microdescriptors_out, md); + microdesc_vote_line_t *e = + tor_malloc_zero(sizeof(microdesc_vote_line_t)); + e->md = md; + e->low = cmr->low; + e->high = cmr->high; + e->next = entries; + entries = e; } } + /* Compress adjacent identical ones */ + for (ep = entries; ep; ep = ep->next) { + while (ep->next && + fast_memeq(ep->md->digest, ep->next->md->digest, DIGEST256_LEN) && + ep->low == ep->next->high + 1) { + microdesc_vote_line_t *next = ep->next; + ep->low = next->low; + microdesc_free(next->md); + ep->next = next->next; + tor_free(next); + } + } + + /* Format them into vote_microdesc_hash_t, and add to microdescriptors_out.*/ + while ((ep = entries)) { + char buf[128]; + vote_microdesc_hash_t *h; + dirvote_format_microdesc_vote_line(buf, sizeof(buf), ep->md, + ep->low, ep->high); + h = tor_malloc_zero(sizeof(vote_microdesc_hash_t)); + h->microdesc_hash_line = tor_strdup(buf); + h->next = result; + result = h; + ep->md->last_listed = now; + smartlist_add(microdescriptors_out, ep->md); + entries = ep->next; + tor_free(ep); + } + return result; }