diff --git a/src/llmq/quorums_signing.cpp b/src/llmq/quorums_signing.cpp index 3d2b228cc..433a3a12a 100644 --- a/src/llmq/quorums_signing.cpp +++ b/src/llmq/quorums_signing.cpp @@ -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 -static void TruncateCacheMap(std::unordered_map, H>& m, size_t maxSize, size_t truncateThreshold) -{ - typedef typename std::unordered_map, H> Map; - typedef typename Map::iterator Iterator; - - if (m.size() <= truncateThreshold) { - return; - } - - std::vector 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) { diff --git a/src/llmq/quorums_signing.h b/src/llmq/quorums_signing.h index 7f6aa49c9..41d05d91f 100644 --- a/src/llmq/quorums_signing.h +++ b/src/llmq/quorums_signing.h @@ -10,6 +10,7 @@ #include "net.h" #include "chainparams.h" #include "saltedhasher.h" +#include "unordered_lru_cache.h" #include @@ -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, StaticSaltedHasher> hasSigForIdCache; - std::unordered_map, StaticSaltedHasher> hasSigForSessionCache; - std::unordered_map, StaticSaltedHasher> hasSigForHashCache; + unordered_lru_cache, bool, StaticSaltedHasher, 30000> hasSigForIdCache; + unordered_lru_cache hasSigForSessionCache; + unordered_lru_cache hasSigForHashCache; public: CRecoveredSigsDb(CDBWrapper& _db);