/** * Prune the database, removing old entries not updated since at least * STABLE_EXPIRE seconds and which have less than STABLE_PROBA chance of * still being alive, given our probability density function. */ static void stable_prune_old(void) { if (GNET_PROPERTY(dht_stable_debug)) { g_debug("DHT STABLE pruning old stable node records (%zu)", dbmw_count(db_lifedata)); } dbmw_foreach_remove(db_lifedata, prune_old, NULL); gnet_stats_set_general(GNR_DHT_STABLE_NODES_HELD, dbmw_count(db_lifedata)); if (GNET_PROPERTY(dht_stable_debug)) { g_debug("DHT STABLE pruned old stable node records (%zu remaining)", dbmw_count(db_lifedata)); } dbstore_compact(db_lifedata); }
/** * Remove expired items at startup time. */ static void publisher_trim_pubdata(void) { size_t count; if (GNET_PROPERTY(publisher_debug)) { count = dbmw_count(db_pubdata); g_debug("PUBLISHER scanning %u retrieved SHA1%s", (unsigned) count, plural(count)); } dbmw_foreach_remove(db_pubdata, publisher_remove_expired, NULL); count = dbmw_count(db_pubdata); if (GNET_PROPERTY(publisher_debug)) { g_debug("PUBLISHER kept information about %u SHA1%s", (unsigned) count, plural(count)); } dbstore_compact(db_pubdata); }
/** * Recreate keyinfo data from persisted information. */ static G_GNUC_COLD void keys_init_keyinfo(void) { struct keys_create_context ctx; if (GNET_PROPERTY(dht_keys_debug)) { size_t count = dbmw_count(db_keydata); g_debug("DHT KEYS scanning %u persisted key%s", (unsigned) count, plural(count)); } ctx.our_kuid = get_our_kuid(); ctx.dbkeys = hset_create(HASH_KEY_FIXED, sizeof(uint64)); dbmw_foreach_remove(db_keydata, reload_ki, &ctx); if (GNET_PROPERTY(dht_keys_debug)) { size_t count = dbmw_count(db_keydata); g_debug("DHT KEYS kept %u key%s, now loading associated values", (unsigned) count, plural(count)); } /* * FIXME: * Unfortunately, we have to reset the keydata database for each of * the keys we're going to recreate, because the logic adding values * back to the key will fill each of the keydata appropriately, and it * expects the amount of values in the keyinfo and the keydata to match. * * Therefore, we need to rename the old keydata database, open a new one, * write empty keydata values in it, then discard the old keydata if * everything goes well. In case of a crash in the middle of the * restoration, we'll be able to recover by opening the old keydata first * if it exists. * * It is far from critical though: if we reset the keydata database and * we crash in the middle of the restore, then we'll lose all the persisted * keys and values and will simply restart with an empty storage. * * Given the contorsions needed to fix that, and the little value for * the user, just leaving a FIXME note. * --RAM, 2012-11-17 */ hikset_foreach(keys, keys_reset_keydata, NULL); values_init_data(ctx.dbkeys); hset_foreach(ctx.dbkeys, keys_free_dbkey, NULL); hset_free_null(&ctx.dbkeys); hikset_foreach_remove(keys, keys_discard_if_empty, NULL); dbmw_foreach_remove(db_keydata, keys_delete_if_empty, NULL); dbstore_compact(db_keydata); g_soft_assert_log(hikset_count(keys) == dbmw_count(db_keydata), "keys reloaded: %zu, key data persisted: %zu", hikset_count(keys), dbmw_count(db_keydata)); if (GNET_PROPERTY(dht_keys_debug)) { g_debug("DHT KEYS reloaded %zu key%s", hikset_count(keys), plural(hikset_count(keys))); } gnet_stats_set_general(GNR_DHT_KEYS_HELD, hikset_count(keys)); }