mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-07 07:44:13 +00:00
cache full addresses in memory when requested or received
This commit is contained in:
parent
bf85a69a2f
commit
c3fa0ae8cc
@ -9,7 +9,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@ -49,7 +49,7 @@ namespace client
|
|||||||
if (m_IsPersist)
|
if (m_IsPersist)
|
||||||
i2p::config::GetOption("addressbook.hostsfile", m_HostsFile);
|
i2p::config::GetOption("addressbook.hostsfile", m_HostsFile);
|
||||||
}
|
}
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const override;
|
std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) override;
|
||||||
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) override;
|
void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) override;
|
||||||
void RemoveAddress (const i2p::data::IdentHash& ident) override;
|
void RemoveAddress (const i2p::data::IdentHash& ident) override;
|
||||||
|
|
||||||
@ -72,6 +72,7 @@ namespace client
|
|||||||
std::string etagsPath, indexPath, localPath;
|
std::string etagsPath, indexPath, localPath;
|
||||||
bool m_IsPersist;
|
bool m_IsPersist;
|
||||||
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
std::string m_HostsFile; // file to dump hosts.txt, empty if not used
|
||||||
|
std::unordered_map<i2p::data::IdentHash, std::vector<uint8_t> > m_FullAddressesCache; // ident hash -> full ident buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
bool AddressBookFilesystemStorage::Init()
|
bool AddressBookFilesystemStorage::Init()
|
||||||
@ -92,8 +93,12 @@ namespace client
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident) const
|
std::shared_ptr<const i2p::data::IdentityEx> AddressBookFilesystemStorage::GetAddress (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
|
auto it = m_FullAddressesCache.find (ident);
|
||||||
|
if (it != m_FullAddressesCache.end ())
|
||||||
|
return std::make_shared<i2p::data::IdentityEx>(it->second.data (), it->second.size ());
|
||||||
|
|
||||||
if (!m_IsPersist)
|
if (!m_IsPersist)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "Addressbook: Persistence is disabled");
|
LogPrint(eLogDebug, "Addressbook: Persistence is disabled");
|
||||||
@ -101,43 +106,55 @@ namespace client
|
|||||||
}
|
}
|
||||||
std::string filename = storage.Path(ident.ToBase32());
|
std::string filename = storage.Path(ident.ToBase32());
|
||||||
std::ifstream f(filename, std::ifstream::binary);
|
std::ifstream f(filename, std::ifstream::binary);
|
||||||
if (!f.is_open ()) {
|
if (!f.is_open ())
|
||||||
|
{
|
||||||
LogPrint(eLogDebug, "Addressbook: Requested, but not found: ", filename);
|
LogPrint(eLogDebug, "Addressbook: Requested, but not found: ", filename);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.seekg (0,std::ios::end);
|
f.seekg (0,std::ios::end);
|
||||||
size_t len = f.tellg ();
|
size_t len = f.tellg ();
|
||||||
if (len < i2p::data::DEFAULT_IDENTITY_SIZE) {
|
if (len < i2p::data::DEFAULT_IDENTITY_SIZE)
|
||||||
|
{
|
||||||
LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
|
LogPrint (eLogError, "Addressbook: File ", filename, " is too short: ", len);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
f.seekg(0, std::ios::beg);
|
f.seekg(0, std::ios::beg);
|
||||||
uint8_t * buf = new uint8_t[len];
|
std::vector<uint8_t> buf(len);
|
||||||
f.read((char *)buf, len);
|
f.read((char *)buf.data (), len);
|
||||||
auto address = std::make_shared<i2p::data::IdentityEx>(buf, len);
|
if (!f)
|
||||||
delete[] buf;
|
{
|
||||||
return address;
|
LogPrint (eLogError, "Addressbook: Couldn't read ", filename);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
m_FullAddressesCache.try_emplace (ident, buf);
|
||||||
|
return std::make_shared<i2p::data::IdentityEx>(buf.data (), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookFilesystemStorage::AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
|
void AddressBookFilesystemStorage::AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address)
|
||||||
{
|
{
|
||||||
|
if (!address) return;
|
||||||
|
size_t len = address->GetFullLen ();
|
||||||
|
if (!len) return; // invalid address
|
||||||
|
auto [it, inserted] = m_FullAddressesCache.try_emplace (address->GetIdentHash(), len);
|
||||||
|
if (inserted)
|
||||||
|
{
|
||||||
|
address->ToBuffer (it->second.data (), len);
|
||||||
if (!m_IsPersist) return;
|
if (!m_IsPersist) return;
|
||||||
std::string path = storage.Path( address->GetIdentHash().ToBase32() );
|
std::string path = storage.Path( address->GetIdentHash().ToBase32() );
|
||||||
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
std::ofstream f (path, std::ofstream::binary | std::ofstream::out);
|
||||||
if (!f.is_open ()) {
|
if (!f.is_open ())
|
||||||
|
{
|
||||||
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
LogPrint (eLogError, "Addressbook: Can't open file ", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
size_t len = address->GetFullLen ();
|
f.write ((const char *)it->second.data (), len);
|
||||||
uint8_t * buf = new uint8_t[len];
|
}
|
||||||
address->ToBuffer (buf, len);
|
|
||||||
f.write ((char *)buf, len);
|
|
||||||
delete[] buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident)
|
void AddressBookFilesystemStorage::RemoveAddress (const i2p::data::IdentHash& ident)
|
||||||
{
|
{
|
||||||
|
m_FullAddressesCache.erase (ident);
|
||||||
if (!m_IsPersist) return;
|
if (!m_IsPersist) return;
|
||||||
storage.Remove( ident.ToBase32() );
|
storage.Remove( ident.ToBase32() );
|
||||||
}
|
}
|
||||||
@ -341,7 +358,7 @@ namespace client
|
|||||||
StopSubscriptions ();
|
StopSubscriptions ();
|
||||||
if (m_SubscriptionsUpdateTimer)
|
if (m_SubscriptionsUpdateTimer)
|
||||||
{
|
{
|
||||||
delete m_SubscriptionsUpdateTimer;
|
m_SubscriptionsUpdateTimer->cancel ();
|
||||||
m_SubscriptionsUpdateTimer = nullptr;
|
m_SubscriptionsUpdateTimer = nullptr;
|
||||||
}
|
}
|
||||||
bool isDownloading = m_Downloading.valid ();
|
bool isDownloading = m_Downloading.valid ();
|
||||||
@ -682,7 +699,7 @@ namespace client
|
|||||||
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
auto dest = i2p::client::context.GetSharedLocalDestination ();
|
||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
m_SubscriptionsUpdateTimer = new boost::asio::deadline_timer (dest->GetService ());
|
m_SubscriptionsUpdateTimer = std::make_unique<boost::asio::deadline_timer>(dest->GetService ());
|
||||||
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
|
m_SubscriptionsUpdateTimer->expires_from_now (boost::posix_time::minutes(INITIAL_SUBSCRIPTION_UPDATE_TIMEOUT));
|
||||||
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
m_SubscriptionsUpdateTimer->async_wait (std::bind (&AddressBook::HandleSubscriptionsUpdateTimer,
|
||||||
this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
|
@ -62,7 +62,7 @@ namespace client
|
|||||||
typedef std::map<std::string, std::shared_ptr<Address>, std::less<> > Addresses;
|
typedef std::map<std::string, std::shared_ptr<Address>, std::less<> > Addresses;
|
||||||
|
|
||||||
virtual ~AddressBookStorage () {};
|
virtual ~AddressBookStorage () {};
|
||||||
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) const = 0;
|
virtual std::shared_ptr<const i2p::data::IdentityEx> GetAddress (const i2p::data::IdentHash& ident) = 0;
|
||||||
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
virtual void AddAddress (std::shared_ptr<const i2p::data::IdentityEx> address) = 0;
|
||||||
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
|
virtual void RemoveAddress (const i2p::data::IdentHash& ident) = 0;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ namespace client
|
|||||||
int m_NumRetries;
|
int m_NumRetries;
|
||||||
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
std::vector<std::shared_ptr<AddressBookSubscription> > m_Subscriptions;
|
||||||
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
std::shared_ptr<AddressBookSubscription> m_DefaultSubscription; // in case if we don't know any addresses yet
|
||||||
boost::asio::deadline_timer * m_SubscriptionsUpdateTimer;
|
std::unique_ptr<boost::asio::deadline_timer> m_SubscriptionsUpdateTimer;
|
||||||
bool m_IsEnabled;
|
bool m_IsEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user