r15939@catbus: nickm | 2007-10-18 22:14:15 -0400

Remember the valid-until time of the most recent consensus that listed
 a router, and (if we are a cache) never delete the routerdesc until
 that conensus is expired.  This is way easier than retaining multiple
 consensuses.  (Of course, the info isn't retained across restarts,
 but that only affects a few caches at a time.) 
 


svn:r12041
This commit is contained in:
Nick Mathewson 2007-10-19 02:15:47 +00:00
parent 90de3ca9ae
commit 29dfdac923
5 changed files with 53 additions and 5 deletions

View file

@ -21,6 +21,9 @@ Changes in version 0.2.0.9-alpha - 2007-10-??
- If we find a cached-routers file that's been sitting around for more
than 28 days unmodified, then most likely it's a leftover from when we
upgraded to 0.2.0.8-alpha. Remove it. It has no good routers anyway.
- When we (as a cache) download a descriptor because it was listed in a
consensus, remember when the consensus was supposed to expire, and
don't expire the descriptor until then.
o Minor features (performance):
- Call routerlist_remove_old_routers() much less often. This should

View file

@ -1049,6 +1049,8 @@ routers_update_all_from_networkstatus(time_t now)
routers_update_status_from_consensus_networkstatus(rl->routers, 0);
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
ri->routerlist_index = ri_sl_idx);
if (rl->old_routers)
signed_descs_update_status_from_consensus_networkstatus(rl->old_routers);
entry_guards_compute_status();
me = router_get_my_routerinfo();
@ -1216,6 +1218,11 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
else
router->is_named = 0;
}
if (!memcmp(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
if (ns->valid_until > router->cache_info.last_listed_as_valid_until)
router->cache_info.last_listed_as_valid_until = ns->valid_until;
}
if (!authdir) {
/* If we're not an authdir, believe others. */
@ -1239,6 +1246,31 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
router_dir_info_changed();
}
/**DOCDOC*/
void
signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs)
{
networkstatus_vote_t *ns = current_consensus;
if (!ns)
return;
if (!ns->desc_digest_map) {
char dummy[DIGEST_LEN];
/* instantiates the digest map. */
memset(dummy, 0, sizeof(dummy));
router_get_consensus_status_by_descriptor_digest(dummy);
}
SMARTLIST_FOREACH(descs, signed_descriptor_t *, d,
{
routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
d->signed_descriptor_digest);
if (rs) {
if (ns->valid_until > d->last_listed_as_valid_until)
d->last_listed_as_valid_until = ns->valid_until;
}
});
}
/** Generate networkstatus lines for a single routerstatus_t object, and
* return the result in a newly allocated string. Used only by controller
* interface (for now.) */

View file

@ -1102,6 +1102,9 @@ typedef struct signed_descriptor_t {
/** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of
* this descriptor in the corresponding file. */
off_t saved_offset;
/** The valid-until time of the most recent consensus that listed this
* descriptor. 0 for "never listed in a consensus, so far as we know." */
time_t last_listed_as_valid_until;
/* If true, we do not ever try to save this object in the cache. */
unsigned int do_not_cache : 1;
/* If true, this item is meant to represent an extrainfo. */
@ -3098,6 +3101,9 @@ void routers_update_all_from_networkstatus(time_t now);
void routerstatus_list_update_from_consensus_networkstatus(time_t now);
void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
int reset_failures);
void signed_descs_update_status_from_consensus_networkstatus(
smartlist_t *descs);
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
int getinfo_helper_networkstatus(control_connection_t *conn,
const char *question, char **answer);

View file

@ -2791,7 +2791,8 @@ _compare_duration_idx(const void *_d1, const void *_d2)
* indices <b>lo</b> or higher may be changed.
*/
static void
routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi,
routerlist_remove_old_cached_routers_with_id(time_t now,
time_t cutoff, int lo, int hi,
digestmap_t *retain)
{
int i, n = hi-lo+1;
@ -2827,7 +2828,8 @@ routerlist_remove_old_cached_routers_with_id(time_t cutoff, int lo, int hi,
signed_descriptor_t *r = smartlist_get(lst, i);
signed_descriptor_t *r_next;
lifespans[i-lo].idx = i;
if (retain && digestmap_get(retain, r->signed_descriptor_digest)) {
if (r->last_listed_as_valid_until >= now ||
(retain && digestmap_get(retain, r->signed_descriptor_digest))) {
must_keep[i-lo] = 1;
}
if (i < hi) {
@ -2933,6 +2935,7 @@ routerlist_remove_old_routers(void)
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
router = smartlist_get(routerlist->routers, i);
if (router->cache_info.published_on <= cutoff &&
router->cache_info.last_listed_as_valid_until < now &&
!digestmap_get(retain,router->cache_info.signed_descriptor_digest)) {
/* Too old: remove it. (If we're a cache, just move it into
* old_routers.) */
@ -2952,6 +2955,7 @@ routerlist_remove_old_routers(void)
for (i = 0; i < smartlist_len(routerlist->old_routers); ++i) {
sd = smartlist_get(routerlist->old_routers, i);
if (sd->published_on <= cutoff &&
sd->last_listed_as_valid_until < now &&
!digestmap_get(retain, sd->signed_descriptor_digest)) {
/* Too old. Remove it. */
routerlist_remove_old(routerlist, sd, i--);
@ -2987,13 +2991,14 @@ routerlist_remove_old_routers(void)
hi = i;
}
if (memcmp(cur_id, r->identity_digest, DIGEST_LEN)) {
routerlist_remove_old_cached_routers_with_id(cutoff, i+1, hi, retain);
routerlist_remove_old_cached_routers_with_id(now,
cutoff, i+1, hi, retain);
cur_id = r->identity_digest;
hi = i;
}
}
if (hi>=0)
routerlist_remove_old_cached_routers_with_id(cutoff, 0, hi, retain);
routerlist_remove_old_cached_routers_with_id(now, cutoff, 0, hi, retain);
//routerlist_assert_ok(routerlist);
done:

View file

@ -74,6 +74,7 @@ typedef enum {
K_VOTE_DIGEST,
K_CONSENSUS_DIGEST,
K_CONSENSUS_METHODS,
K_CONSENSUS_METHOD,
A_PURPOSE,
_A_UNKNOWN,
@ -339,7 +340,8 @@ static token_rule_t networkstatus_consensus_token_table[] = {
T1( "known-flags", K_KNOWN_FLAGS, CONCAT_ARGS, NO_OBJ ),
T01("client-versions", K_CLIENT_VERSIONS, CONCAT_ARGS, NO_OBJ ),
T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
T01("server-versions", K_SERVER_VERSIONS, CONCAT_ARGS, NO_OBJ ),
T01("consensus-method", K_CONSENSUS_METHOD, EQ(1), NO_OBJ),
END_OF_TABLE
};