diff --git a/src/cpp/ripple/Pathfinder.cpp b/src/cpp/ripple/Pathfinder.cpp index 9f3c604a8d..35a55da78c 100644 --- a/src/cpp/ripple/Pathfinder.cpp +++ b/src/cpp/ripple/Pathfinder.cpp @@ -138,7 +138,7 @@ static int getEffectiveLength(const STPath& spPath) return length; } -Pathfinder::Pathfinder(Ledger::ref ledger, +Pathfinder::Pathfinder(Ledger::ref ledger, RLCache::ref cache, const RippleAddress& uSrcAccountID, const RippleAddress& uDstAccountID, const uint160& uSrcCurrencyID, const uint160& uSrcIssuerID, const STAmount& saDstAmount, bool& bValid) : mSrcAccountID(uSrcAccountID.getAccountID()), @@ -147,7 +147,7 @@ Pathfinder::Pathfinder(Ledger::ref ledger, mSrcCurrencyID(uSrcCurrencyID), mSrcIssuerID(uSrcIssuerID), mSrcAmount(uSrcCurrencyID, uSrcIssuerID, 1u, 0, true), - mLedger(ledger) + mLedger(ledger), mRLCache(cache) { if (((mSrcAccountID == mDstAccountID) && (mSrcCurrencyID == mDstAmount.getCurrency())) || mDstAmount.isZero()) @@ -443,7 +443,7 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax bool bRequireAuth = isSetBit(sleEnd->getFieldU32(sfFlags), lsfRequireAuth); bool dstCurrency = speEnd.mCurrencyID == mDstAmount.getCurrency(); - AccountItems& rippleLines(getRippleLines(speEnd.mAccountID)); + AccountItems& rippleLines(mRLCache->getRippleLines(speEnd.mAccountID)); std::vector< std::pair > candidates; candidates.reserve(rippleLines.getItems().size()); @@ -776,8 +776,9 @@ boost::unordered_set usAccountDestCurrencies(const RippleAddress& raAcc return usCurrencies; } -AccountItems& Pathfinder::getRippleLines(const uint160& accountID) +AccountItems& RLCache::getRippleLines(const uint160& accountID) { + boost::mutex::scoped_lock sl(mLock); boost::unordered_map::iterator it = mRLMap.find(accountID); if (it == mRLMap.end()) it = mRLMap.insert(std::make_pair(accountID, boost::make_shared @@ -799,7 +800,7 @@ int Pathfinder::getPathsOut(const uint160& currencyID, const uint160& accountID, return it->second; int count = 0; - AccountItems& rippleLines(getRippleLines(accountID)); + AccountItems& rippleLines(mRLCache->getRippleLines(accountID)); BOOST_FOREACH(AccountItem::ref item, rippleLines.getItems()) { RippleState* rspEntry = (RippleState*) item.get(); diff --git a/src/cpp/ripple/Pathfinder.h b/src/cpp/ripple/Pathfinder.h index acc5e5a7d9..c1a9df966f 100644 --- a/src/cpp/ripple/Pathfinder.h +++ b/src/cpp/ripple/Pathfinder.h @@ -35,6 +35,21 @@ public: }; #endif +class RLCache +{ +protected: + boost::mutex mLock; + Ledger::pointer mLedger; + boost::unordered_map mRLMap; + +public: + typedef boost::shared_ptr pointer; + typedef const pointer& ref; + + RLCache(Ledger::ref l) : mLedger(l) { ; } + AccountItems& getRippleLines(const uint160& accountID); +}; + class Pathfinder { uint160 mSrcAccountID; @@ -47,6 +62,7 @@ class Pathfinder Ledger::pointer mLedger; PathState::pointer mPsDefault; LoadEvent::pointer mLoadMonitor; + RLCache::pointer mRLCache; boost::unordered_map mRLMap; boost::unordered_map, int> mPOMap; @@ -63,13 +79,11 @@ class Pathfinder bool matchesOrigin(const uint160& currency, const uint160& issuer); - AccountItems& getRippleLines(const uint160& accountID); - int getPathsOut(const uint160& currency, const uint160& accountID, bool isAuthRequired, bool isDestCurrency, const uint160& dest); public: - Pathfinder(Ledger::ref ledger, + Pathfinder(Ledger::ref ledger, RLCache::ref cache, const RippleAddress& srcAccountID, const RippleAddress& dstAccountID, const uint160& srcCurrencyID, const uint160& srcIssuerID, const STAmount& dstAmount, bool& bValid); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index b72ea21ddf..69e27236f5 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -180,7 +180,8 @@ Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit) { ScopedUnlock su(theApp->getMasterLock()); bool bValid; - Pathfinder pf(lSnapshot, raSrcAddressID, dstAccountID, + RLCache::pointer cache = boost::make_shared(lSnapshot); + Pathfinder pf(lSnapshot, cache, raSrcAddressID, dstAccountID, saSendMax.getCurrency(), saSendMax.getIssuer(), saSend, bValid); if (!bValid || !pf.findPaths(theConfig.PATH_SEARCH_SIZE, 3, spsPaths)) @@ -1304,6 +1305,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost, Scope jvResult["destination_account"] = raDst.humanAccountID(); Json::Value jvArray(Json::arrayValue); + RLCache::pointer cache = boost::make_shared(lSnapShot); for (unsigned int i=0; i != jvSrcCurrencies.size(); ++i) { Json::Value jvSource = jvSrcCurrencies[i]; @@ -1339,7 +1341,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost, Scope STPathSet spsComputed; bool bValid; - Pathfinder pf(lSnapShot, raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount, bValid); + Pathfinder pf(lSnapShot, cache, raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount, bValid); if (!bValid || !pf.findPaths(theConfig.PATH_SEARCH_SIZE, 3, spsComputed)) {