Use unordered_lru_cache in CRecoveredSigsDb
This commit is contained in:
parent
9e4aa1f98c
commit
293c9ad6a1
@ -37,66 +37,57 @@ bool CRecoveredSigsDb::HasRecoveredSig(Consensus::LLMQType llmqType, const uint2
|
||||
|
||||
bool CRecoveredSigsDb::HasRecoveredSigForId(Consensus::LLMQType llmqType, const uint256& id)
|
||||
{
|
||||
int64_t t = GetTimeMillis();
|
||||
|
||||
auto cacheKey = std::make_pair(llmqType, id);
|
||||
bool ret;
|
||||
{
|
||||
LOCK(cs);
|
||||
auto it = hasSigForIdCache.find(cacheKey);
|
||||
if (it != hasSigForIdCache.end()) {
|
||||
it->second.second = t;
|
||||
return it->second.first;
|
||||
if (hasSigForIdCache.get(cacheKey, ret)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto k = std::make_tuple(std::string("rs_r"), (uint8_t)llmqType, id);
|
||||
bool ret = db.Exists(k);
|
||||
ret = db.Exists(k);
|
||||
|
||||
LOCK(cs);
|
||||
hasSigForIdCache.emplace(cacheKey, std::make_pair(ret, t));
|
||||
hasSigForIdCache.insert(cacheKey, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CRecoveredSigsDb::HasRecoveredSigForSession(const uint256& signHash)
|
||||
{
|
||||
int64_t t = GetTimeMillis();
|
||||
|
||||
bool ret;
|
||||
{
|
||||
LOCK(cs);
|
||||
auto it = hasSigForSessionCache.find(signHash);
|
||||
if (it != hasSigForSessionCache.end()) {
|
||||
it->second.second = t;
|
||||
return it->second.first;
|
||||
if (hasSigForSessionCache.get(signHash, ret)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
auto k = std::make_tuple(std::string("rs_s"), signHash);
|
||||
bool ret = db.Exists(k);
|
||||
ret = db.Exists(k);
|
||||
|
||||
LOCK(cs);
|
||||
hasSigForSessionCache.emplace(signHash, std::make_pair(ret, t));
|
||||
hasSigForSessionCache.insert(signHash, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CRecoveredSigsDb::HasRecoveredSigForHash(const uint256& hash)
|
||||
{
|
||||
int64_t t = GetTimeMillis();
|
||||
|
||||
bool ret;
|
||||
{
|
||||
LOCK(cs);
|
||||
auto it = hasSigForHashCache.find(hash);
|
||||
if (it != hasSigForHashCache.end()) {
|
||||
it->second.second = t;
|
||||
return it->second.first;
|
||||
if (hasSigForHashCache.get(hash, ret)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
auto k = std::make_tuple(std::string("rs_h"), hash);
|
||||
bool ret = db.Exists(k);
|
||||
ret = db.Exists(k);
|
||||
|
||||
LOCK(cs);
|
||||
hasSigForHashCache.emplace(hash, std::make_pair(ret, t));
|
||||
hasSigForHashCache.insert(hash, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -167,34 +158,9 @@ void CRecoveredSigsDb::WriteRecoveredSig(const llmq::CRecoveredSig& recSig)
|
||||
int64_t t = GetTimeMillis();
|
||||
|
||||
LOCK(cs);
|
||||
hasSigForIdCache[std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.id)] = std::make_pair(true, t);
|
||||
hasSigForSessionCache[signHash] = std::make_pair(true, t);
|
||||
hasSigForHashCache[recSig.GetHash()] = std::make_pair(true, t);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename K, typename H>
|
||||
static void TruncateCacheMap(std::unordered_map<K, std::pair<bool, int64_t>, H>& m, size_t maxSize, size_t truncateThreshold)
|
||||
{
|
||||
typedef typename std::unordered_map<K, std::pair<bool, int64_t>, H> Map;
|
||||
typedef typename Map::iterator Iterator;
|
||||
|
||||
if (m.size() <= truncateThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Iterator> vec;
|
||||
vec.reserve(m.size());
|
||||
for (auto it = m.begin(); it != m.end(); ++it) {
|
||||
vec.emplace_back(it);
|
||||
}
|
||||
// sort by last access time (descending order)
|
||||
std::sort(vec.begin(), vec.end(), [](const Iterator& it1, const Iterator& it2) {
|
||||
return it1->second.second > it2->second.second;
|
||||
});
|
||||
|
||||
for (size_t i = maxSize; i < vec.size(); i++) {
|
||||
m.erase(vec[i]);
|
||||
hasSigForIdCache.insert(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.id), true);
|
||||
hasSigForSessionCache.insert(signHash, true);
|
||||
hasSigForHashCache.insert(recSig.GetHash(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,10 +223,6 @@ void CRecoveredSigsDb::CleanupOldRecoveredSigs(int64_t maxAge)
|
||||
hasSigForSessionCache.erase(signHash);
|
||||
hasSigForHashCache.erase(recSig.GetHash());
|
||||
}
|
||||
|
||||
TruncateCacheMap(hasSigForIdCache, MAX_CACHE_SIZE, MAX_CACHE_TRUNCATE_THRESHOLD);
|
||||
TruncateCacheMap(hasSigForSessionCache, MAX_CACHE_SIZE, MAX_CACHE_TRUNCATE_THRESHOLD);
|
||||
TruncateCacheMap(hasSigForHashCache, MAX_CACHE_SIZE, MAX_CACHE_TRUNCATE_THRESHOLD);
|
||||
}
|
||||
|
||||
for (auto& e : toDelete2) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "net.h"
|
||||
#include "chainparams.h"
|
||||
#include "saltedhasher.h"
|
||||
#include "unordered_lru_cache.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@ -68,16 +69,13 @@ public:
|
||||
|
||||
class CRecoveredSigsDb
|
||||
{
|
||||
static const size_t MAX_CACHE_SIZE = 30000;
|
||||
static const size_t MAX_CACHE_TRUNCATE_THRESHOLD = 50000;
|
||||
|
||||
private:
|
||||
CDBWrapper& db;
|
||||
|
||||
CCriticalSection cs;
|
||||
std::unordered_map<std::pair<Consensus::LLMQType, uint256>, std::pair<bool, int64_t>, StaticSaltedHasher> hasSigForIdCache;
|
||||
std::unordered_map<uint256, std::pair<bool, int64_t>, StaticSaltedHasher> hasSigForSessionCache;
|
||||
std::unordered_map<uint256, std::pair<bool, int64_t>, StaticSaltedHasher> hasSigForHashCache;
|
||||
unordered_lru_cache<std::pair<Consensus::LLMQType, uint256>, bool, StaticSaltedHasher, 30000> hasSigForIdCache;
|
||||
unordered_lru_cache<uint256, bool, StaticSaltedHasher, 30000> hasSigForSessionCache;
|
||||
unordered_lru_cache<uint256, bool, StaticSaltedHasher, 30000> hasSigForHashCache;
|
||||
|
||||
public:
|
||||
CRecoveredSigsDb(CDBWrapper& _db);
|
||||
|
Loading…
Reference in New Issue
Block a user