mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Improve performance of some RPC ledger commands using visitors.
Adds SHAMap::visitLeaves and Ledger::visitStateItems
This commit is contained in:
@@ -990,6 +990,16 @@ void Ledger::addJson (Json::Value& ret, int options)
|
||||
ret["ledger"] = getJson (options);
|
||||
}
|
||||
|
||||
static void stateItemTagAppender(Json::Value& value, SHAMapItem::ref smi)
|
||||
{
|
||||
value.append (smi->getTag ().GetHex ());
|
||||
}
|
||||
|
||||
static void stateItemFullAppender(Json::Value& value, SLE::ref sle)
|
||||
{
|
||||
value.append (sle->getJson (0));
|
||||
}
|
||||
|
||||
Json::Value Ledger::getJson (int options)
|
||||
{
|
||||
Json::Value ledger (Json::objectValue);
|
||||
@@ -1077,23 +1087,11 @@ Json::Value Ledger::getJson (int options)
|
||||
|
||||
if (mAccountStateMap && (bFull || isSetBit (options, LEDGER_JSON_DUMP_STATE)))
|
||||
{
|
||||
Json::Value state (Json::arrayValue);
|
||||
SHAMap::ScopedLockType l (mAccountStateMap->peekMutex (), __FILE__, __LINE__);
|
||||
|
||||
for (SHAMapItem::pointer item = mAccountStateMap->peekFirstItem (); !!item;
|
||||
item = mAccountStateMap->peekNextItem (item->getTag ()))
|
||||
{
|
||||
if (bFull || isSetBit (options, LEDGER_JSON_EXPAND))
|
||||
{
|
||||
SerializerIterator sit (item->peekSerializer ());
|
||||
SerializedLedgerEntry sle (sit, item->getTag ());
|
||||
state.append (sle.getJson (0));
|
||||
}
|
||||
else
|
||||
state.append (item->getTag ().GetHex ());
|
||||
}
|
||||
|
||||
ledger["accountState"] = state;
|
||||
Json::Value& state = (ledger["accountState"] = Json::arrayValue);
|
||||
if (bFull || isSetBit (options, LEDGER_JSON_EXPAND))
|
||||
visitStateItems(BIND_TYPE(stateItemFullAppender, beast::ref(state), P_1));
|
||||
else
|
||||
mAccountStateMap->visitLeaves(BIND_TYPE(stateItemTagAppender, beast::ref(state), P_1));
|
||||
}
|
||||
|
||||
return ledger;
|
||||
@@ -1236,6 +1234,17 @@ void Ledger::visitAccountItems (const uint160& accountID, FUNCTION_TYPE<void (SL
|
||||
|
||||
}
|
||||
|
||||
static void visitHelper (FUNCTION_TYPE<void (SLE::ref)>& function, SHAMapItem::ref item)
|
||||
{
|
||||
function (boost::make_shared<SLE> (item->peekSerializer (), item->getTag ()));
|
||||
}
|
||||
|
||||
void Ledger::visitStateItems (FUNCTION_TYPE<void (SLE::ref)> function)
|
||||
{
|
||||
if (mAccountStateMap)
|
||||
mAccountStateMap->visitLeaves(BIND_TYPE(&visitHelper, beast::ref(function), P_1));
|
||||
}
|
||||
|
||||
/*
|
||||
// VFALCO: A proof of concept for making an iterator instead of a visitor
|
||||
class AccountItemIterator
|
||||
|
||||
@@ -260,6 +260,7 @@ public:
|
||||
SLE::pointer getAccountRoot (const RippleAddress & naAccountID);
|
||||
void updateSkipList ();
|
||||
void visitAccountItems (const uint160 & acctID, FUNCTION_TYPE<void (SLE::ref)>);
|
||||
void visitStateItems (FUNCTION_TYPE<void (SLE::ref)>);
|
||||
|
||||
// database functions (low-level)
|
||||
static Ledger::pointer loadByIndex (uint32 ledgerIndex);
|
||||
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
SHAMapItem::pointer peekNextItem (uint256 const& );
|
||||
SHAMapItem::pointer peekNextItem (uint256 const& , SHAMapTreeNode::TNType & type);
|
||||
SHAMapItem::pointer peekPrevItem (uint256 const& );
|
||||
void visitLeaves(FUNCTION_TYPE<void (SHAMapItem::ref)>);
|
||||
|
||||
// comparison/sync functions
|
||||
void getMissingNodes (std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
|
||||
|
||||
@@ -24,6 +24,60 @@ static const uint256 uZero;
|
||||
|
||||
KeyCache <uint256, UptimeTimerAdapter> SHAMap::fullBelowCache ("fullBelowCache", 524288, 240);
|
||||
|
||||
void SHAMap::visitLeaves (FUNCTION_TYPE<void (SHAMapItem::ref item)> function)
|
||||
{
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
|
||||
assert (root->isValid ());
|
||||
|
||||
if (!root || root->isEmpty ())
|
||||
return;
|
||||
|
||||
if (!root->isInner ())
|
||||
{
|
||||
function (root->peekItem ());
|
||||
return;
|
||||
}
|
||||
|
||||
typedef std::pair<int, SHAMapTreeNode*> posPair;
|
||||
|
||||
std::stack<posPair> stack;
|
||||
SHAMapTreeNode* node = root.get ();
|
||||
int pos = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (pos < 16)
|
||||
{
|
||||
if (node->isEmptyBranch (pos))
|
||||
++pos;
|
||||
else
|
||||
{
|
||||
SHAMapTreeNode* child = getNodePointerNT (node->getChildNodeID (pos), node->getChildHash (pos));
|
||||
if (child->isLeaf ())
|
||||
{
|
||||
function (child->peekItem ());
|
||||
++pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos != 15)
|
||||
stack.push (posPair (pos + 1, node)); // save next position
|
||||
|
||||
node = child;
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.empty ())
|
||||
break;
|
||||
pos = stack.top ().first;
|
||||
node = stack.top ().second;
|
||||
stack.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
void SHAMap::getMissingNodes (std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& hashes, int max,
|
||||
SHAMapSyncFilter* filter)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user