mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Make the dirty node save logic work during consensus ledger close.
This commit is contained in:
@@ -60,6 +60,8 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
static uint64 sGenesisClose;
|
||||
|
||||
uint256 mHash, mParentHash, mTransHash, mAccountHash;
|
||||
uint64 mTotCoins;
|
||||
uint64 mCloseTime; // when this ledger closes
|
||||
@@ -67,8 +69,6 @@ private:
|
||||
uint16 mLedgerInterval;
|
||||
bool mClosed, mValidHash, mAccepted, mImmutable;
|
||||
|
||||
static uint64 sGenesisClose;
|
||||
|
||||
SHAMap::pointer mTransactionMap, mAccountStateMap;
|
||||
|
||||
mutable boost::recursive_mutex mLock;
|
||||
@@ -102,6 +102,8 @@ public:
|
||||
bool isClosed() { return mClosed; }
|
||||
bool isAccepted() { return mAccepted; }
|
||||
bool isImmutable() { return mImmutable; }
|
||||
void armDirty() { mTransactionMap->armDirty(); mAccountStateMap->armDirty(); }
|
||||
void disarmDirty() { mTransactionMap->disarmDirty(); mAccountStateMap->disarmDirty(); }
|
||||
|
||||
// This ledger has closed, will never be accepted, and is accepting
|
||||
// new transactions to be re-repocessed when do accept a new last-closed ledger
|
||||
|
||||
@@ -752,6 +752,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
Log(lsDEBUG) << "Previous LCL " << mPrevLedgerHash.GetHex();
|
||||
|
||||
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
|
||||
newLCL->armDirty();
|
||||
|
||||
#ifdef DEBUG
|
||||
Json::StyledStreamWriter ssw;
|
||||
|
||||
@@ -629,6 +629,12 @@ bool SHAMap::fetchNode(const uint256& hash, std::vector<unsigned char>& data)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SHAMap::armDirty()
|
||||
{ // begin saving dirty nodes
|
||||
++mSeq;
|
||||
mDirtyNodes = boost::make_shared< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> >();
|
||||
}
|
||||
|
||||
int SHAMap::flushDirty(int maxNodes, HashedObjectType t, uint32 seq)
|
||||
{
|
||||
int flushed = 0;
|
||||
@@ -636,37 +642,45 @@ int SHAMap::flushDirty(int maxNodes, HashedObjectType t, uint32 seq)
|
||||
|
||||
if(mDirtyNodes)
|
||||
{
|
||||
while (!mDirtyNodes->empty())
|
||||
HashedObjectBulkWriter bw;
|
||||
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>& dirtyNodes = *mDirtyNodes;
|
||||
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = dirtyNodes.begin();
|
||||
while (it != dirtyNodes.end())
|
||||
{
|
||||
SHAMapTreeNode::pointer& din = mDirtyNodes->begin()->second;
|
||||
s.erase();
|
||||
din->addRaw(s);
|
||||
HashedObject::store(t, seq, s.peekData(), s.getSHA512Half());
|
||||
mDirtyNodes->erase(mDirtyNodes->begin());
|
||||
if(flushed++>=maxNodes) return flushed;
|
||||
it->second->addRaw(s);
|
||||
bw.store(t, seq, s.peekData(), s.getSHA512Half());
|
||||
if (flushed++ >= maxNodes)
|
||||
return flushed;
|
||||
it = dirtyNodes.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
return flushed;
|
||||
}
|
||||
|
||||
void SHAMap::disarmDirty()
|
||||
{ // stop saving dirty nodes
|
||||
mDirtyNodes = boost::shared_ptr< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> >();
|
||||
}
|
||||
|
||||
SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& nodeID)
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
|
||||
SHAMapTreeNode::pointer node=checkCacheNode(nodeID);
|
||||
if(node) return node;
|
||||
SHAMapTreeNode::pointer node = checkCacheNode(nodeID);
|
||||
if (node) return node;
|
||||
|
||||
node=root;
|
||||
while(nodeID!=*node)
|
||||
node = root;
|
||||
while (nodeID != *node)
|
||||
{
|
||||
int branch=node->selectBranch(nodeID.getNodeID());
|
||||
assert(branch>=0);
|
||||
if( (branch<0) || (node->isEmptyBranch(branch)) )
|
||||
int branch = node->selectBranch(nodeID.getNodeID());
|
||||
assert(branch >= 0);
|
||||
if ((branch < 0) || node->isEmptyBranch(branch))
|
||||
return SHAMapTreeNode::pointer();
|
||||
|
||||
node=getNode(node->getChildNodeID(branch), node->getChildHash(branch), false);
|
||||
if(!node) throw SHAMapException(MissingNode);
|
||||
node = getNode(node->getChildNodeID(branch), node->getChildHash(branch), false);
|
||||
if (!node) throw SHAMapException(MissingNode);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ private:
|
||||
mutable boost::recursive_mutex mLock;
|
||||
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> mTNByID;
|
||||
|
||||
boost::shared_ptr<std::map<SHAMapNode, SHAMapTreeNode::pointer> > mDirtyNodes;
|
||||
boost::shared_ptr< boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer> > mDirtyNodes;
|
||||
|
||||
SHAMapTreeNode::pointer root;
|
||||
|
||||
@@ -329,7 +329,9 @@ public:
|
||||
// return value: true=successfully completed, false=too different
|
||||
bool compare(SHAMap::pointer otherMap, SHAMapDiff& differences, int maxCount);
|
||||
|
||||
void armDirty();
|
||||
int flushDirty(int maxNodes, HashedObjectType t, uint32 seq);
|
||||
void disarmDirty();
|
||||
|
||||
void setSeq(uint32 seq) { mSeq = seq; }
|
||||
uint32 getSeq() { return mSeq; }
|
||||
|
||||
Reference in New Issue
Block a user