mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Cache the hashes of nodes known to be full below.
Remove the TNByID entries for those nodes in state trees. This reduces the memory and I/O neded during ledger fetching and prevents ledger fetching from crushing other caches.
This commit is contained in:
@@ -341,6 +341,7 @@ void Application::sweep()
|
||||
getMasterLedgerAcquire().sweep();
|
||||
mSLECache.sweep();
|
||||
AcceptedLedger::sweep();
|
||||
SHAMap::sweep();
|
||||
mSweepTimer.expires_from_now(boost::posix_time::seconds(theConfig.getSize(siSweepInterval)));
|
||||
mSweepTimer.async_wait(boost::bind(&Application::sweep, this));
|
||||
}
|
||||
|
||||
@@ -853,6 +853,14 @@ void SHAMap::dropCache()
|
||||
mTNByID[*root] = root;
|
||||
}
|
||||
|
||||
void SHAMap::dropBelow(SHAMapTreeNode* d)
|
||||
{
|
||||
if (d->isInner())
|
||||
for (int i = 0 ; i < 16; ++i)
|
||||
if (!d->isEmptyBranch(i))
|
||||
mTNByID.erase(d->getChildNodeID(i));
|
||||
}
|
||||
|
||||
void SHAMap::dump(bool hash)
|
||||
{
|
||||
cLog(lsINFO) << " MAP Contains";
|
||||
|
||||
@@ -354,6 +354,8 @@ private:
|
||||
|
||||
SHAMapType mType;
|
||||
|
||||
static KeyCache<uint256> fullBelowCache;
|
||||
|
||||
protected:
|
||||
|
||||
void dirtyUp(std::stack<SHAMapTreeNode::pointer>& stack, const uint256& target, uint256 prevHash);
|
||||
@@ -372,6 +374,7 @@ protected:
|
||||
|
||||
SHAMapItem::pointer onlyBelow(SHAMapTreeNode*);
|
||||
void eraseChildren(SHAMapTreeNode::pointer);
|
||||
void dropBelow(SHAMapTreeNode*);
|
||||
|
||||
bool walkBranch(SHAMapTreeNode* node, SHAMapItem::ref otherMapItem, bool isFirstMap,
|
||||
SHAMapDiff& differences, int& maxCount);
|
||||
@@ -472,6 +475,8 @@ public:
|
||||
|
||||
bool deepCompare(SHAMap& other);
|
||||
virtual void dump(bool withHashes = false);
|
||||
|
||||
static void sweep() { fullBelowCache.sweep(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,8 @@ SETUP_LOG();
|
||||
|
||||
static const uint256 uZero;
|
||||
|
||||
KeyCache<uint256> SHAMap::fullBelowCache("fullBelowCache", 65536, 240);
|
||||
|
||||
void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
|
||||
SHAMapSyncFilter* filter)
|
||||
{
|
||||
@@ -49,46 +51,56 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
|
||||
int branch = (base + ii) % 16;
|
||||
if (!node->isEmptyBranch(branch))
|
||||
{
|
||||
SHAMapNode childID = node->getChildNodeID(branch);
|
||||
const uint256& childHash = node->getChildHash(branch);
|
||||
SHAMapTreeNode* d = NULL;
|
||||
try
|
||||
if (!fullBelowCache.isPresent(childHash))
|
||||
{
|
||||
d = getNodePointer(childID, childHash);
|
||||
}
|
||||
catch (SHAMapMissingNode&)
|
||||
{ // node is not in the map
|
||||
if (filter != NULL)
|
||||
SHAMapNode childID = node->getChildNodeID(branch);
|
||||
SHAMapTreeNode* d = NULL;
|
||||
try
|
||||
{
|
||||
std::vector<unsigned char> nodeData;
|
||||
if (filter->haveNode(childID, childHash, nodeData))
|
||||
d = getNodePointer(childID, childHash);
|
||||
}
|
||||
catch (SHAMapMissingNode&)
|
||||
{ // node is not in the map
|
||||
if (filter != NULL)
|
||||
{
|
||||
assert(mSeq >= 1);
|
||||
SHAMapTreeNode::pointer ptr =
|
||||
boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq - 1, snfPREFIX, childHash, true);
|
||||
cLog(lsTRACE) << "Got sync node from cache: " << *ptr;
|
||||
mTNByID[*ptr] = ptr;
|
||||
d = ptr.get();
|
||||
std::vector<unsigned char> nodeData;
|
||||
if (filter->haveNode(childID, childHash, nodeData))
|
||||
{
|
||||
assert(mSeq >= 1);
|
||||
SHAMapTreeNode::pointer ptr =
|
||||
boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq - 1, snfPREFIX, childHash, true);
|
||||
cLog(lsTRACE) << "Got sync node from cache: " << *ptr;
|
||||
mTNByID[*ptr] = ptr;
|
||||
d = ptr.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!d)
|
||||
{ // we need this node
|
||||
nodeIDs.push_back(childID);
|
||||
hashes.push_back(childHash);
|
||||
if (--max <= 0)
|
||||
return;
|
||||
have_all = false;
|
||||
}
|
||||
else if (d->isInner() && !d->isFullBelow()) // we might need children of this node
|
||||
{
|
||||
have_all = false;
|
||||
stack.push(d);
|
||||
if (!d)
|
||||
{ // we need this node
|
||||
nodeIDs.push_back(childID);
|
||||
hashes.push_back(childHash);
|
||||
if (--max <= 0)
|
||||
return;
|
||||
have_all = false;
|
||||
}
|
||||
else if (d->isInner() && !d->isFullBelow()) // we might need children of this node
|
||||
{
|
||||
have_all = false;
|
||||
stack.push(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (have_all)
|
||||
{
|
||||
node->setFullBelow();
|
||||
if (mType == smtSTATE)
|
||||
{
|
||||
fullBelowCache.add(node->getHash());
|
||||
dropBelow(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nodeIDs.empty())
|
||||
clearSynching();
|
||||
@@ -123,27 +135,37 @@ std::vector<uint256> SHAMap::getNeededHashes(int max)
|
||||
if (!node->isEmptyBranch(branch))
|
||||
{
|
||||
const uint256& childHash = node->getChildHash(branch);
|
||||
try
|
||||
if (!fullBelowCache.isPresent(childHash))
|
||||
{
|
||||
SHAMapTreeNode* d = getNodePointer(node->getChildNodeID(branch), childHash);
|
||||
assert(d);
|
||||
if (d->isInner() && !d->isFullBelow())
|
||||
try
|
||||
{
|
||||
have_all = false;
|
||||
stack.push(d);
|
||||
SHAMapTreeNode* d = getNodePointer(node->getChildNodeID(branch), childHash);
|
||||
assert(d);
|
||||
if (d->isInner() && !d->isFullBelow())
|
||||
{
|
||||
have_all = false;
|
||||
stack.push(d);
|
||||
}
|
||||
}
|
||||
catch (SHAMapMissingNode&)
|
||||
{ // node is not in the map
|
||||
have_all = false;
|
||||
ret.push_back(childHash);
|
||||
if (--max <= 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
catch (SHAMapMissingNode&)
|
||||
{ // node is not in the map
|
||||
have_all = false;
|
||||
ret.push_back(childHash);
|
||||
if (--max <= 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (have_all)
|
||||
{
|
||||
node->setFullBelow();
|
||||
if (mType == smtSTATE)
|
||||
{
|
||||
fullBelowCache.add(node->getHash());
|
||||
dropBelow(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret.empty())
|
||||
clearSynching();
|
||||
|
||||
Reference in New Issue
Block a user