/** * Given a node which was first seen at ``first_seen'' and last seen at * ``last_seen'', return probability that node still be alive now. * * @param first_seen first time node was seen / created * @param last_seen last time node was seen * * @return the probability that the node be still alive now. */ double stable_still_alive_probability(time_t first_seen, time_t last_seen) { time_delta_t life; time_delta_t elapsed; life = delta_time(last_seen, first_seen); if (life <= 0) return 0.0; elapsed = delta_time(tm_time(), last_seen); return stable_alive_probability(life, elapsed); }
/** * Estimate probability of presence for a value published to some roots in * a given time frame. * * @param d how many seconds in the future? * @param rs the STORE lookup path, giving root candidates * @param status the array of STORE status for each entry in the path * * @return an estimated probability of presence of the value in the network. */ double stable_store_presence(time_delta_t d, const lookup_rs_t *rs, const guint16 *status) { double q = 1.0; size_t i; size_t count = lookup_result_path_length(rs); /* * We may be called by publish callbacks invoked to clean up because * the operation was cancelled. Maybe the DHT was disabled during the * operation, meaning our data structures have been cleaned up? In that * case, abort immediately. * * NOTE: this is not an assertion, it can happen in practice and needs to * be explicitly checked for. */ if (NULL == db_lifedata) /* DHT disabled dynamically */ return 0.0; /* * The probability of presence is (1 - q) where q is the probability * that the value be lost by all the nodes, i.e. that all the nodes * to which the value was published to be gone in "d" seconds. */ for (i = 0; i < count; i++) { if (status[i] == STORE_SC_OK) { const knode_t *kn = lookup_result_nth_node(rs, i); struct lifedata *ld = get_lifedata(kn->id); if (NULL == ld) { return 0.0; /* Cannot compute a suitable probability */ } else { time_delta_t alive = delta_time(ld->last_seen, ld->first_seen); double p = stable_alive_probability(alive, d); q *= (1.0 - p); /* (1 - p) is proba this node will be gone */ } } } return 1.0 - q; }
/** * Given a node which was first seen at ``first_seen'' and last seen at * ``last_seen'', return probability that node still be alive now. * * @param first_seen first time node was seen / created * @param last_seen last time node was seen * * @return the probability that the node be still alive now. */ double stable_still_alive_probability(time_t first_seen, time_t last_seen) { time_delta_t life; time_delta_t elapsed; life = delta_time(last_seen, first_seen); if (life <= 0) return 0.0; elapsed = delta_time(tm_time(), last_seen); /* * Safety precaution: regardless of the past lifetime of the node, if * we have not heard from it for more than STABLE_UPPER_THRESH, then * consider it dead. */ return elapsed < STABLE_UPPER_THRESH ? stable_alive_probability(life, elapsed) : 0.0; }