Browse Source

in-meory storage for router profiles

pull/1879/head
orignal 2 years ago
parent
commit
48a3c767e5
  1. 14
      libi2pd/NetDb.cpp
  2. 68
      libi2pd/Profiling.cpp
  3. 14
      libi2pd/Profiling.h
  4. 2
      libi2pd/RouterInfo.h

14
libi2pd/NetDb.cpp

@ -85,8 +85,7 @@ namespace data
if (m_IsRunning) if (m_IsRunning)
{ {
if (m_PersistProfiles) if (m_PersistProfiles)
for (auto& it: m_RouterInfos) SaveProfiles ();
it.second->SaveProfile ();
DeleteObsoleteProfiles (); DeleteObsoleteProfiles ();
m_RouterInfos.clear (); m_RouterInfos.clear ();
m_Floodfills.clear (); m_Floodfills.clear ();
@ -179,6 +178,7 @@ namespace data
if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) || if (ts - lastProfilesCleanup >= (uint64_t)(i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT + profilesCleanupVariance) ||
ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup) ts + i2p::data::PEER_PROFILE_AUTOCLEAN_TIMEOUT < lastProfilesCleanup)
{ {
if (m_PersistProfiles) PersistProfiles ();
DeleteObsoleteProfiles (); DeleteObsoleteProfiles ();
lastProfilesCleanup = ts; lastProfilesCleanup = ts;
profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE); profilesCleanupVariance = (rand () % (2 * i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE) - i2p::data::PEER_PROFILE_AUTOCLEAN_VARIANCE);
@ -684,12 +684,12 @@ namespace data
for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();) for (auto it = m_RouterInfos.begin (); it != m_RouterInfos.end ();)
{ {
if (it->second->IsUnreachable ()) if (it->second->IsUnreachable ())
{
if (m_PersistProfiles) it->second->SaveProfile ();
it = m_RouterInfos.erase (it); it = m_RouterInfos.erase (it);
continue; else
{
it->second->DropProfile ();
it++;
} }
++it;
} }
} }
// clean up expired floodfills or not floodfills anymore // clean up expired floodfills or not floodfills anymore
@ -699,7 +699,7 @@ namespace data
if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ()) if ((*it)->IsUnreachable () || !(*it)->IsFloodfill ())
it = m_Floodfills.erase (it); it = m_Floodfills.erase (it);
else else
++it; it++;
} }
} }
} }

68
libi2pd/Profiling.cpp

@ -7,6 +7,7 @@
*/ */
#include <sys/stat.h> #include <sys/stat.h>
#include <unordered_map>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp> #include <boost/property_tree/ini_parser.hpp>
#include "Base.h" #include "Base.h"
@ -19,24 +20,26 @@ namespace i2p
{ {
namespace data namespace data
{ {
i2p::fs::HashedStorage m_ProfilesStorage("peerProfiles", "p", "profile-", "txt"); static i2p::fs::HashedStorage g_ProfilesStorage("peerProfiles", "p", "profile-", "txt");
static std::unordered_map<i2p::data::IdentHash, std::shared_ptr<RouterProfile> > g_Profiles;
static boost::posix_time::ptime GetTime ()
{
return boost::posix_time::second_clock::local_time();
}
RouterProfile::RouterProfile (): RouterProfile::RouterProfile ():
m_LastUpdateTime (boost::posix_time::second_clock::local_time()), m_LastUpdateTime (GetTime ()), m_IsUpdated (false),
m_LastDeclineTime (0), m_LastUnreachableTime (0), m_LastDeclineTime (0), m_LastUnreachableTime (0),
m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0), m_NumTunnelsAgreed (0), m_NumTunnelsDeclined (0), m_NumTunnelsNonReplied (0),
m_NumTimesTaken (0), m_NumTimesRejected (0) m_NumTimesTaken (0), m_NumTimesRejected (0)
{ {
} }
boost::posix_time::ptime RouterProfile::GetTime () const
{
return boost::posix_time::second_clock::local_time();
}
void RouterProfile::UpdateTime () void RouterProfile::UpdateTime ()
{ {
m_LastUpdateTime = GetTime (); m_LastUpdateTime = GetTime ();
m_IsUpdated = true;
} }
void RouterProfile::Save (const IdentHash& identHash) void RouterProfile::Save (const IdentHash& identHash)
@ -59,7 +62,7 @@ namespace data
// save to file // save to file
std::string ident = identHash.ToBase64 (); std::string ident = identHash.ToBase64 ();
std::string path = m_ProfilesStorage.Path(ident); std::string path = g_ProfilesStorage.Path(ident);
try { try {
boost::property_tree::write_ini (path, pt); boost::property_tree::write_ini (path, pt);
@ -72,7 +75,7 @@ namespace data
void RouterProfile::Load (const IdentHash& identHash) void RouterProfile::Load (const IdentHash& identHash)
{ {
std::string ident = identHash.ToBase64 (); std::string ident = identHash.ToBase64 ();
std::string path = m_ProfilesStorage.Path(ident); std::string path = g_ProfilesStorage.Path(ident);
boost::property_tree::ptree pt; boost::property_tree::ptree pt;
if (!i2p::fs::Exists(path)) if (!i2p::fs::Exists(path))
@ -158,6 +161,7 @@ namespace data
void RouterProfile::Unreachable () void RouterProfile::Unreachable ()
{ {
m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch (); m_LastUnreachableTime = i2p::util::GetSecondsSinceEpoch ();
UpdateTime ();
} }
bool RouterProfile::IsLowPartcipationRate () const bool RouterProfile::IsLowPartcipationRate () const
@ -209,30 +213,68 @@ namespace data
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash) std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash)
{ {
auto it = g_Profiles.find (identHash);
if (it != g_Profiles.end ())
return it->second;
auto profile = std::make_shared<RouterProfile> (); auto profile = std::make_shared<RouterProfile> ();
profile->Load (identHash); // if possible profile->Load (identHash); // if possible
g_Profiles.emplace (identHash, profile);
return profile; return profile;
} }
void InitProfilesStorage () void InitProfilesStorage ()
{ {
m_ProfilesStorage.SetPlace(i2p::fs::GetDataDir()); g_ProfilesStorage.SetPlace(i2p::fs::GetDataDir());
m_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64); g_ProfilesStorage.Init(i2p::data::GetBase64SubstitutionTable(), 64);
}
void PersistProfiles ()
{
auto ts = GetTime ();
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
{
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () > PEER_PROFILE_PERSIST_INTERVAL)
{
if (it->second->IsUpdated ())
it->second->Save (it->first);
it = g_Profiles.erase (it);
}
else
it++;
}
}
void SaveProfiles ()
{
auto ts = GetTime ();
for (auto it: g_Profiles)
if (it.second->IsUpdated () && (ts - it.second->GetLastUpdateTime ()).total_seconds () < PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
it.second->Save (it.first);
g_Profiles.clear ();
} }
void DeleteObsoleteProfiles () void DeleteObsoleteProfiles ()
{ {
auto ts = GetTime ();
for (auto it = g_Profiles.begin (); it != g_Profiles.end ();)
{
if ((ts - it->second->GetLastUpdateTime ()).total_seconds () >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600)
it = g_Profiles.erase (it);
else
it++;
}
struct stat st; struct stat st;
std::time_t now = std::time(nullptr); std::time_t now = std::time(nullptr);
std::vector<std::string> files; std::vector<std::string> files;
m_ProfilesStorage.Traverse(files); g_ProfilesStorage.Traverse(files);
for (const auto& path: files) { for (const auto& path: files) {
if (stat(path.c_str(), &st) != 0) { if (stat(path.c_str(), &st) != 0) {
LogPrint(eLogWarning, "Profiling: Can't stat(): ", path); LogPrint(eLogWarning, "Profiling: Can't stat(): ", path);
continue; continue;
} }
if (((now - st.st_mtime) / 3600) >= PEER_PROFILE_EXPIRATION_TIMEOUT) { if (now - st.st_mtime >= PEER_PROFILE_EXPIRATION_TIMEOUT*3600) {
LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path); LogPrint(eLogDebug, "Profiling: Removing expired peer profile: ", path);
i2p::fs::Remove(path); i2p::fs::Remove(path);
} }

14
libi2pd/Profiling.h

@ -29,10 +29,11 @@ namespace data
const char PEER_PROFILE_USAGE_TAKEN[] = "taken"; const char PEER_PROFILE_USAGE_TAKEN[] = "taken";
const char PEER_PROFILE_USAGE_REJECTED[] = "rejected"; const char PEER_PROFILE_USAGE_REJECTED[] = "rejected";
const int PEER_PROFILE_EXPIRATION_TIMEOUT = 72; // in hours (3 days) const int PEER_PROFILE_EXPIRATION_TIMEOUT = 36; // in hours (1.5 days)
const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 24 * 3600; // in seconds (1 day) const int PEER_PROFILE_AUTOCLEAN_TIMEOUT = 6 * 3600; // in seconds (6 hours)
const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3 * 3600; // in seconds (3 hours) const int PEER_PROFILE_AUTOCLEAN_VARIANCE = 3600; // in seconds (1 hour)
const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes) const int PEER_PROFILE_DECLINED_RECENTLY_INTERVAL = 150; // in seconds (2.5 minutes)
const int PEER_PROFILE_PERSIST_INTERVAL = 3300; // in seconds (55 minutes)
const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours) const int PEER_PROFILE_UNREACHABLE_INTERVAL = 2*3600; // on seconds (2 hours)
class RouterProfile class RouterProfile
@ -53,9 +54,11 @@ namespace data
void Unreachable (); void Unreachable ();
boost::posix_time::ptime GetLastUpdateTime () const { return m_LastUpdateTime; };
bool IsUpdated () const { return m_IsUpdated; };
private: private:
boost::posix_time::ptime GetTime () const;
void UpdateTime (); void UpdateTime ();
bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; }; bool IsAlwaysDeclining () const { return !m_NumTunnelsAgreed && m_NumTunnelsDeclined >= 5; };
@ -66,6 +69,7 @@ namespace data
private: private:
boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono boost::posix_time::ptime m_LastUpdateTime; // TODO: use std::chrono
bool m_IsUpdated;
uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds uint64_t m_LastDeclineTime, m_LastUnreachableTime; // in seconds
// participation // participation
uint32_t m_NumTunnelsAgreed; uint32_t m_NumTunnelsAgreed;
@ -79,6 +83,8 @@ namespace data
std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash); std::shared_ptr<RouterProfile> GetRouterProfile (const IdentHash& identHash);
void InitProfilesStorage (); void InitProfilesStorage ();
void DeleteObsoleteProfiles (); void DeleteObsoleteProfiles ();
void SaveProfiles ();
void PersistProfiles ();
} }
} }

2
libi2pd/RouterInfo.h

@ -251,7 +251,7 @@ namespace data
bool SaveToFile (const std::string& fullPath); bool SaveToFile (const std::string& fullPath);
std::shared_ptr<RouterProfile> GetProfile () const; std::shared_ptr<RouterProfile> GetProfile () const;
void SaveProfile () { if (m_Profile) m_Profile->Save (GetIdentHash ()); }; void DropProfile () { m_Profile = nullptr; };
void Update (const uint8_t * buf, size_t len); void Update (const uint8_t * buf, size_t len);
void DeleteBuffer () { m_Buffer = nullptr; }; void DeleteBuffer () { m_Buffer = nullptr; };

Loading…
Cancel
Save