/** * DBMW foreach iterator to remove old entries. * @return TRUE if entry must be deleted. */ static gboolean prune_old(gpointer key, gpointer value, size_t u_len, gpointer u_data) { const kuid_t *id = key; const struct lifedata *ld = value; time_delta_t d; gboolean expired; double p; (void) u_len; (void) u_data; d = delta_time(tm_time(), ld->last_seen); if (d <= STABLE_EXPIRE) { expired = FALSE; p = 1.0; } else { p = stable_still_alive_probability(ld->first_seen, ld->last_seen); expired = p < STABLE_PROBA; } if (GNET_PROPERTY(dht_stable_debug) > 4) { g_debug("DHT STABLE node %s life=%s last_seen=%s, p=%.2f%%%s", kuid_to_hex_string(id), compact_time(delta_time(ld->last_seen, ld->first_seen)), compact_time2(d), p * 100.0, expired ? " [EXPIRED]" : ""); } return expired; }
/** * DBMW foreach iterator to remove old entries. * @return TRUE if entry must be deleted. */ static bool guid_prune_old_entries(void *key, void *value, size_t u_len, void *u_data) { const guid_t *guid = key; const struct guiddata *gd = value; time_delta_t d; double p = 0.0; bool expired; (void) u_len; (void) u_data; /* * We reuse the statistical probability model of DHT nodes to project * whether it makes sense to keep an entry. */ d = delta_time(tm_time(), gd->last_time); if (gd->create_time == gd->last_time) { expired = d > GUID_STABLE_LIFETIME; } else { p = stable_still_alive_probability(gd->create_time, gd->last_time); expired = p < GUID_STABLE_PROBA; } if (GNET_PROPERTY(guid_debug) > 5) { g_debug("GUID cached %s life=%s last_seen=%s, p=%.2f%%%s", guid_hex_str(guid), compact_time(delta_time(gd->last_time, gd->create_time)), compact_time2(d), p * 100.0, expired ? " [EXPIRED]" : ""); } return expired; }
/** * Record a SHA1 for publishing. */ void publisher_add(const sha1_t *sha1) { struct publisher_entry *pe; struct pubdata *pd; g_assert(sha1 != NULL); if (NULL == db_pubdata) return; /* Shutdowning */ /* * If already known, ignore silently. */ if (hikset_lookup(publisher_sha1, sha1)) return; /* * Create persistent publishing data if none known already. */ pd = get_pubdata(sha1); if (NULL == pd) { struct pubdata new_pd; new_pd.next_enqueue = 0; new_pd.expiration = 0; dbmw_write(db_pubdata, sha1, &new_pd, sizeof new_pd); if (GNET_PROPERTY(publisher_debug) > 2) { g_debug("PUBLISHER allocating new SHA-1 %s", sha1_to_string(sha1)); } } else { if (GNET_PROPERTY(publisher_debug) > 2) { time_delta_t enqueue = delta_time(pd->next_enqueue, tm_time()); time_delta_t expires = delta_time(pd->expiration, tm_time()); g_debug("PUBLISHER existing SHA-1 %s, next enqueue %s%s, %s%s", sha1_to_string(sha1), enqueue > 0 ? "in " : "", enqueue > 0 ? compact_time(enqueue) : "now", pd->expiration ? (expires > 0 ? "expires in " : "expired") : "not published", expires > 0 ? compact_time2(expires) : ""); } } /* * New entry will be processed immediately. */ pe = publisher_entry_alloc(sha1); hikset_insert_key(publisher_sha1, &pe->sha1); publisher_handle(pe); }