diff --git a/src/cpp/ripple/AccountItems.cpp b/src/cpp/ripple/AccountItems.cpp index 1953ff22d9..6939485431 100644 --- a/src/cpp/ripple/AccountItems.cpp +++ b/src/cpp/ripple/AccountItems.cpp @@ -35,9 +35,9 @@ void AccountItems::fillItems(const uint160& accountID, Ledger::ref ledger) BOOST_FOREACH(uint256& uNode, svOwnerNodes.peekValue()) { - SLE::pointer sleCur = ledger->getSLE(uNode); + SLE::pointer sleCur = ledger->getSLEi(uNode); - AccountItem::pointer item=mOfType->makeItem(accountID, sleCur); + AccountItem::pointer item = mOfType->makeItem(accountID, sleCur); if(item) { mItems.push_back(item); diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 20235bc65b..3081fb3743 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -41,7 +41,7 @@ DatabaseCon::~DatabaseCon() Application::Application() : mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster), - mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), + mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), mSLECache("LedgerEntryCache", 4096, 120), mSNTPClient(mAuxService), mRPCHandler(&mNetOps), mFeeTrack(), mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL), mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL), @@ -301,6 +301,7 @@ void Application::sweep() mTempNodeCache.sweep(); mValidations.sweep(); getMasterLedgerAcquire().sweep(); + mSLECache.sweep(); mSweepTimer.expires_from_now(boost::posix_time::seconds(theConfig.getSize(siSweepInterval))); mSweepTimer.async_wait(boost::bind(&Application::sweep, this)); } diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index 343c9d26c2..b8ef316499 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -29,6 +29,7 @@ class RPCDoor; class PeerDoor; typedef TaggedCache< uint256, std::vector > NodeCache; +typedef TaggedCache< uint256, SLE > SLECache; class DatabaseCon { @@ -60,6 +61,7 @@ class Application ValidationCollection mValidations; SuppressionTable mSuppressions; HashedObjectStore mHashedObjectStore; + SLECache mSLECache; SNTPClient mSNTPClient; JobQueue mJobQueue; RPCHandler mRPCHandler; @@ -118,6 +120,7 @@ public: TXQueue& getTxnQueue() { return mTxnQueue; } PeerDoor& getPeerDoor() { return *mPeerDoor; } OrderBookDB& getOrderBookDB() { return mOrderBookDB; } + SLECache& getSLECache() { return mSLECache; } bool isNew(const uint256& s) { return mSuppressions.addSuppression(s); } diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index e0f9589ebc..26200b78e9 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -954,6 +954,22 @@ SLE::pointer Ledger::getSLE(const uint256& uHash) return boost::make_shared(node->peekSerializer(), node->getTag()); } +SLE::pointer Ledger::getSLEi(const uint256& uId) +{ + uint256 hash; + SHAMapItem::pointer node = mAccountStateMap->peekItem(uId, hash); + if (!node) + return SLE::pointer(); + + SLE::pointer ret = theApp->getSLECache().fetch(hash); + if (!ret) + { + ret = boost::make_shared(node->peekSerializer(), node->getTag()); + theApp->getSLECache().canonicalize(hash, ret); + } + return ret; +} + uint256 Ledger::getFirstLedgerIndex() { SHAMapItem::pointer node = mAccountStateMap->peekFirstItem(); @@ -1179,7 +1195,7 @@ uint256 Ledger::getLedgerHash(uint32 ledgerIndex) int diff = mLedgerSeq - ledgerIndex; if (diff <= 256) { - SLE::pointer hashIndex = getSLE(getLedgerHashIndex()); + SLE::pointer hashIndex = getSLEi(getLedgerHashIndex()); if (hashIndex) { assert(hashIndex->getFieldU32(sfLastLedgerSequence) == (mLedgerSeq - 1)); @@ -1199,7 +1215,7 @@ uint256 Ledger::getLedgerHash(uint32 ledgerIndex) } // in skiplist - SLE::pointer hashIndex = getSLE(getLedgerHashIndex(ledgerIndex)); + SLE::pointer hashIndex = getSLEi(getLedgerHashIndex(ledgerIndex)); if (hashIndex) { int lastSeq = hashIndex->getFieldU32(sfLastLedgerSequence); @@ -1219,7 +1235,7 @@ uint256 Ledger::getLedgerHash(uint32 ledgerIndex) std::vector< std::pair > Ledger::getLedgerHashes() { std::vector< std::pair > ret; - SLE::pointer hashIndex = getSLE(getLedgerHashIndex()); + SLE::pointer hashIndex = getSLEi(getLedgerHashIndex()); if (hashIndex) { STVector256 vec = hashIndex->getFieldV256(sfHashes); diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 20da8705f6..ffbca3fc88 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -201,7 +201,8 @@ public: void pendSave(bool fromConsensus); // next/prev function - SLE::pointer getSLE(const uint256& uHash); + SLE::pointer getSLE(const uint256& uHash); // SLE is mutable + SLE::pointer getSLEi(const uint256& uHash); // SLE is immutable uint256 getFirstLedgerIndex(); uint256 getLastLedgerIndex(); uint256 getNextLedgerIndex(const uint256& uHash); // first node >hash diff --git a/src/cpp/ripple/LedgerEntrySet.cpp b/src/cpp/ripple/LedgerEntrySet.cpp index 43f0fc4515..da90db1453 100644 --- a/src/cpp/ripple/LedgerEntrySet.cpp +++ b/src/cpp/ripple/LedgerEntrySet.cpp @@ -399,7 +399,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result, uint32 index) if (type == &sfGeneric) continue; - SLE::pointer origNode = mLedger->getSLE(it.first); + SLE::pointer origNode = mLedger->getSLEi(it.first); SLE::pointer curNode = it.second.mEntry; if ((type == &sfModifiedNode) && (*curNode == *origNode)) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 4c798660bf..2e4aaded13 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -538,7 +538,7 @@ Json::Value NetworkOPs::getOwnerInfo(Ledger::pointer lpLedger, const RippleAddre BOOST_FOREACH(const uint256& uDirEntry, vuiIndexes) { - SLE::pointer sleCur = lpLedger->getSLE(uDirEntry); + SLE::pointer sleCur = lpLedger->getSLEi(uDirEntry); switch (sleCur->getType()) { diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 8940d55cb8..1c1ba558c0 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -165,6 +165,7 @@ public: void setLastValidation(SerializedValidation::ref v) { mLastValidation = v; } SLE::pointer getSLE(Ledger::pointer lpLedger, const uint256& uHash) { return lpLedger->getSLE(uHash); } + SLE::pointer getSLEi(Ledger::pointer lpLedger, const uint256& uHash) { return lpLedger->getSLEi(uHash); } // // Transaction operations diff --git a/src/cpp/ripple/OrderBookDB.cpp b/src/cpp/ripple/OrderBookDB.cpp index 7113abe243..64ff9804f9 100644 --- a/src/cpp/ripple/OrderBookDB.cpp +++ b/src/cpp/ripple/OrderBookDB.cpp @@ -39,7 +39,7 @@ void OrderBookDB::setup(Ledger::ref ledger) while (currentIndex.isNonZero()) { - SLE::pointer entry=ledger->getSLE(currentIndex); + SLE::pointer entry=ledger->getSLEi(currentIndex); OrderBook::pointer book = OrderBook::newOrderBook(entry); if (book) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 038de7c672..120aa5e55d 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -217,7 +217,7 @@ Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit) if (!txJSON.isMember("Flags")) txJSON["Flags"] = 0; Ledger::pointer lpCurrent = mNetOps->getCurrentLedger(); - SLE::pointer sleAccountRoot = mNetOps->getSLE(lpCurrent, Ledger::getAccountRootIndex(raSrcAddressID.getAccountID())); + SLE::pointer sleAccountRoot = mNetOps->getSLEi(lpCurrent, Ledger::getAccountRootIndex(raSrcAddressID.getAccountID())); if (!sleAccountRoot) { @@ -2147,7 +2147,7 @@ Json::Value RPCHandler::lookupLedger(Json::Value jvRequest, Ledger::pointer& lpL if (-3 == iLedgerIndex) { // Last fully-validated ledger lpLedger = mNetOps->getValidatedLedger(); - iLedgerIndex = lpLedger->getLedgerSeq(); + iLedgerIndex = lpLedger->getLedgerSeq(); } if (iLedgerIndex <= 0) @@ -2364,7 +2364,7 @@ Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest) if (!!uNodeIndex) { - SLE::pointer sleNode = mNetOps->getSLE(lpLedger, uNodeIndex); + SLE::pointer sleNode = mNetOps->getSLEi(lpLedger, uNodeIndex); if (!sleNode) {