Add cache for CBlockTreeDB::HasTxIndex (#3402)

* Add cache for CBlockTreeDB::HasTxIndex

* Also update mapHasTxIndexCache in WriteTxIndex
This commit is contained in:
Alexander Block 2020-04-08 22:18:33 +02:00 committed by GitHub
parent 2dff0501e9
commit 0e56e32c22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 4 deletions

View File

@ -54,6 +54,14 @@ public:
if (ret.second) if (ret.second)
prune(); prune();
} }
void insert_or_update(const value_type& x)
{
std::pair<iterator, bool> ret = map.insert(x);
if (ret.second)
prune();
else
ret.first->second = x.second;
}
void erase(const key_type& k) void erase(const key_type& k)
{ {
map.erase(k); map.erase(k);

View File

@ -151,7 +151,7 @@ size_t CCoinsViewDB::EstimateSize() const
return db.EstimateSize(DB_COIN, (char)(DB_COIN+1)); return db.EstimateSize(DB_COIN, (char)(DB_COIN+1));
} }
CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) { CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe), mapHasTxIndexCache(10000, 20000) {
} }
bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
@ -241,18 +241,36 @@ bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockF
} }
bool CBlockTreeDB::HasTxIndex(const uint256& txid) { bool CBlockTreeDB::HasTxIndex(const uint256& txid) {
return Exists(std::make_pair(DB_TXINDEX, txid)); {
LOCK(cs);
auto it = mapHasTxIndexCache.find(txid);
if (it != mapHasTxIndexCache.end()) {
return it->second;
}
}
bool r = Exists(std::make_pair(DB_TXINDEX, txid));
LOCK(cs);
mapHasTxIndexCache.insert(std::make_pair(txid, r));
return r;
} }
bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) { bool CBlockTreeDB::ReadTxIndex(const uint256 &txid, CDiskTxPos &pos) {
return Read(std::make_pair(DB_TXINDEX, txid), pos); bool r = Read(std::make_pair(DB_TXINDEX, txid), pos);
LOCK(cs);
mapHasTxIndexCache.insert_or_update(std::make_pair(txid, r));
return r;
} }
bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) { bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
CDBBatch batch(*this); CDBBatch batch(*this);
for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++) for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second); batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second);
return WriteBatch(batch); bool ret = WriteBatch(batch);
LOCK(cs);
for (auto& p : vect) {
mapHasTxIndexCache.insert_or_update(std::make_pair(p.first, true));
}
return ret;
} }
bool CBlockTreeDB::ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) { bool CBlockTreeDB::ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value) {

View File

@ -9,7 +9,9 @@
#include <coins.h> #include <coins.h>
#include <dbwrapper.h> #include <dbwrapper.h>
#include <chain.h> #include <chain.h>
#include <limitedmap.h>
#include <spentindex.h> #include <spentindex.h>
#include <sync.h>
#include <map> #include <map>
#include <string> #include <string>
@ -110,6 +112,10 @@ private:
/** Access to the block database (blocks/index/) */ /** Access to the block database (blocks/index/) */
class CBlockTreeDB : public CDBWrapper class CBlockTreeDB : public CDBWrapper
{ {
private:
CCriticalSection cs;
unordered_limitedmap<uint256, bool> mapHasTxIndexCache;
public: public:
explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false); explicit CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);