Пример #1
0
/**
 * Record activity on the node.
 */
void
stable_record_activity(const knode_t *kn)
{
    struct lifedata *ld;
    struct lifedata new_ld;

    knode_check(kn);
    g_assert(kn->flags & KNODE_F_ALIVE);

    ld = get_lifedata(kn->id);

    if (NULL == ld) {
        ld = &new_ld;

        new_ld.version = LIFEDATA_STRUCT_VERSION;
        new_ld.first_seen = kn->first_seen;
        new_ld.last_seen = kn->last_seen;

        gnet_stats_count_general(GNR_DHT_STABLE_NODES_HELD, +1);
    } else {
        if (kn->last_seen <= ld->last_seen)
            return;
        ld->last_seen = kn->last_seen;
    }

    dbmw_write(db_lifedata, kn->id->v, ld, sizeof *ld);
}
Пример #2
0
/**
 * The KUID of the node has changed: remove its entry if it had one and make
 * sure we have an entry for the new KUID.
 *
 * @param kn		the old node
 * @param rn		the replacing node
 */
void
stable_replace(const knode_t *kn, const knode_t *rn)
{
	struct lifedata *ld;

	knode_check(kn);
	knode_check(rn);
	g_assert(rn->flags & KNODE_F_ALIVE);

	ld = get_lifedata(kn->id);
	if (NULL == ld)
		return;				/* Node was not recorded in the "stable" set */

	if (GNET_PROPERTY(dht_stable_debug)) {
		g_debug("DHT STABLE removing obsolete %s, now at %s",
			knode_to_string(kn), knode_to_string2(rn));
	}

	/*
	 * Remove the old node and create an entry for the new one.
	 */

	dbmw_delete(db_lifedata, kn->id->v);
	gnet_stats_dec_general(GNR_DHT_STABLE_NODES_HELD);
	stable_record_activity(rn);
}
Пример #3
0
/**
 * 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;
}