Use unordered_lru_cache in CRecoveredSigsDb

This commit is contained in:
Alexander Block 2019-03-11 07:31:08 +01:00
parent 9e4aa1f98c
commit 293c9ad6a1
2 changed files with 22 additions and 62 deletions

View File

@ -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) {

View File

@ -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);