diff --git a/src/ripple_app/paths/PathRequest.cpp b/src/ripple_app/paths/PathRequest.cpp index 6c65dc9da..c5c79d514 100644 --- a/src/ripple_app/paths/PathRequest.cpp +++ b/src/ripple_app/paths/PathRequest.cpp @@ -22,6 +22,7 @@ SETUP_LOG (PathRequest) // VFALCO TODO Move these globals into a PathRequests collection inteface PathRequest::StaticLockType PathRequest::sLock ("PathRequest", __FILE__, __LINE__); std::set PathRequest::sRequests; +RippleLineCache::pointer PathRequest::sLineCache; Atomic PathRequest::siLastIdentifier(0); PathRequest::PathRequest (const boost::shared_ptr& subscriber) @@ -113,19 +114,24 @@ Json::Value PathRequest::doCreate (Ledger::ref lrLedger, const Json::Value& valu { assert (lrLedger->isClosed ()); + // Get the ledger and line cache we should use + Ledger::pointer ledger = lrLedger; + RippleLineCache::pointer cache; + { + StaticScopedLockType sl (sLock, __FILE__, __LINE__); + cache = getLineCache (ledger); + } + Json::Value status; bool mValid; { - ScopedLockType sl (mLock, __FILE__, __LINE__); - if (parseJson (value, true) != PFR_PJ_INVALID) { - mValid = isValid (lrLedger); + mValid = isValid (ledger); if (mValid) { - RippleLineCache::pointer cache = boost::make_shared (lrLedger); doUpdate (cache, true); } } @@ -408,15 +414,40 @@ bool PathRequest::doUpdate (RippleLineCache::ref cache, bool fast) return true; } -void PathRequest::updateAll (Ledger::ref ledger, bool newOnly, bool hasNew, CancelCallback shouldCancel) +/** Get the current RippleLineCache, updating it if necessary. + Get the correct ledger to use. + Call with a lock +*/ +RippleLineCache::pointer PathRequest::getLineCache (Ledger::pointer& ledger) +{ + uint32 lineSeq = sLineCache ? sLineCache->getLedger()->getLedgerSeq() : 0; + if ( (lineSeq == 0) || // No cache + (lineSeq < ledger->getLedgerSeq()) || // Cache is out of date + (lineSeq > (ledger->getLedgerSeq() + 16))) // We jumped way back somehow + { + ledger = boost::make_shared(*ledger, false); + sLineCache = boost::make_shared (ledger); + } + else + { + ledger = sLineCache->getLedger(); + } + return sLineCache; +} + +void PathRequest::updateAll (Ledger::ref inLedger, bool newOnly, bool hasNew, CancelCallback shouldCancel) { std::set requests; LoadEvent::autoptr event (getApp().getJobQueue().getLoadEventAP(jtPATH_FIND, "PathRequest::updateAll")); + // Get the ledger and cache we should be using + Ledger::pointer ledger = inLedger; + RippleLineCache::pointer cache; { StaticScopedLockType sl (sLock, __FILE__, __LINE__); requests = sRequests; + cache = getLineCache (ledger); } if (requests.empty ()) @@ -426,7 +457,6 @@ void PathRequest::updateAll (Ledger::ref ledger, bool newOnly, bool hasNew, Canc (newOnly ? " newOnly, " : " all, ") << requests.size() << " requests"; int processed = 0, removed = 0; - RippleLineCache::pointer cache = boost::make_shared (ledger); BOOST_FOREACH (wref wRequest, requests) { diff --git a/src/ripple_app/paths/PathRequest.h b/src/ripple_app/paths/PathRequest.h index 2fc87658d..881cc048f 100644 --- a/src/ripple_app/paths/PathRequest.h +++ b/src/ripple_app/paths/PathRequest.h @@ -64,6 +64,7 @@ private: void setValid (); void resetLevel (int level); int parseJson (const Json::Value&, bool complete); + static RippleLineCache::pointer getLineCache (Ledger::pointer& ledger); typedef RippleRecursiveMutex LockType; typedef LockType::ScopedLockType ScopedLockType; @@ -93,6 +94,9 @@ private: // Track all requests static std::set sRequests; + // Use a RippleLineCache + static RippleLineCache::pointer sLineCache; + typedef RippleRecursiveMutex StaticLockType; typedef LockType::ScopedLockType StaticScopedLockType; static StaticLockType sLock; diff --git a/src/ripple_app/ripple_app.h b/src/ripple_app/ripple_app.h index 056b5ed1e..65a9790ab 100644 --- a/src/ripple_app/ripple_app.h +++ b/src/ripple_app/ripple_app.h @@ -125,6 +125,7 @@ namespace ripple { #include "misc/Offer.h" #include "tx/OfferCancelTransactor.h" #include "tx/OfferCreateTransactor.h" +#include "paths/RippleLineCache.h" #include "paths/PathRequest.h" #include "main/ParameterTable.h" #include "paths/RippleLineCache.h"