public IEnumerable <I2PIdentHash> GetClosestFloodfill( I2PIdentHash dest, int count, ConcurrentBag <I2PIdentHash> exclude, bool nextset) { var minfit = RouletteFloodFill.AverageFit - Math.Max(4.0, RouletteFloodFill.AbsDevFit * 0.8); var subset = (exclude != null && exclude.Any()) ? FloodfillInfos.Where(inf => !exclude.Contains(inf.Key)) : FloodfillInfos; var refkey = nextset ? dest.NextRoutingKey : dest.RoutingKey; var qlist = subset .Select(ri => new { Id = ri.Key, Q = ri.Value.CachedStatistics }) .Where(inf => (inf.Q?.Score ?? 0f) > minfit); return(qlist .Select(p => new { p.Id, Dist = p.Id ^ refkey }) .OrderBy(p => p.Dist) .Take(count) .Select(p => p.Id) .ToArray()); }
void Load() { using (var s = GetStore()) { var sw2 = new Stopwatch(); sw2.Start(); var ix = 0; while (s != null && (ix = s.Next(ix)) > 0) { var reader = new BufRefLen(s.Read(ix)); var recordtype = (StoreRecordId)reader.Read32(); try { switch (recordtype) { case StoreRecordId.StoreIdRouterInfo: var one = new I2PRouterInfo(reader, false); if (!ValidateRI(one)) { s.Delete(ix); RouterInfos.TryRemove(one.Identity.IdentHash, out _); FloodfillInfos.TryRemove(one.Identity.IdentHash, out _); Statistics.DestinationInformationFaulty(one.Identity.IdentHash); continue; } if (!RouterContext.Inst.UseIpV6) { if (!one.Adresses.Any(a => a.Options.ValueContains("host", "."))) { Logging.LogDebug($"NetDb: RouterInfo have no IPV4 address: {one.Identity.IdentHash.Id32}"); s.Delete(ix); continue; } } var re = new RouterEntry( one, new RouterInfoMeta(ix)); RouterInfos[one.Identity.IdentHash] = re; if (re.IsFloodfill) { FloodfillInfos[one.Identity.IdentHash] = re; } break; case StoreRecordId.StoreIdConfig: AccessConfig(delegate(Dictionary <I2PString, I2PString> settings) { var key = new I2PString(reader); settings[key] = new I2PString(reader); }); break; default: s.Delete(ix); break; } } catch (Exception ex) { Logging.LogDebug($"NetDb: Load: Store exception, ix [{ix}] removed. {ex}"); s.Delete(ix); } } sw2.Stop(); Logging.Log($"Store: {sw2.Elapsed}"); } ImportNetDbFiles(); if (RouterInfos.Count < 20) { Logging.LogWarning($"WARNING: NetDB database contains " + $"{RouterInfos.Count} routers. Add router files to {NetDbPath}."); DoBootstrap(); } Statistics.Load(); IsFirewalledUpdate(); #if DEBUG ShowDebugDatabaseInfo(); #endif UpdateSelectionProbabilities(); Save(true); }
void Save(bool onlyupdated) { var created = 0; var updated = 0; var deleted = 0; var sw = new Stopwatch(); sw.Start(); RemoveOldRouterInfos(); using (var s = GetStore()) { foreach (var one in RouterInfos.ToArray()) { try { if (one.Value.Meta.Deleted) { if (one.Value.Meta.StoreIx > 0) { s.Delete(one.Value.Meta.StoreIx); } RouterInfos.TryRemove(one.Key, out _); FloodfillInfos.TryRemove(one.Key, out _); ++deleted; continue; } if (!onlyupdated || (onlyupdated && one.Value.Meta.Updated)) { var rec = new BufLen[] { BufUtils.To32BL((int)StoreRecordId.StoreIdRouterInfo), new BufLen(one.Value.Router.ToByteArray()) }; if (one.Value.Meta.StoreIx > 0) { s.Write(rec, one.Value.Meta.StoreIx); ++updated; } else { one.Value.Meta.StoreIx = s.Write(rec); ++created; } one.Value.Meta.Updated = false; } } catch (Exception ex) { Logging.LogDebug("NetDb: Save: Store exception: " + ex.ToString()); one.Value.Meta.StoreIx = -1; } } SaveConfig(s); } Logging.Log($"NetDb.Save( {( onlyupdated ? "updated" : "all" )} ): " + $"{created} created, {updated} updated, {deleted} deleted."); Statistics.RemoveOldStatistics(); UpdateSelectionProbabilities(); sw.Stop(); Logging.Log($"NetDB: Save: {sw.Elapsed}"); }