From 51a85504a8afcdccf67f638e0fcfd60c935f08e8 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 3 Mar 2013 02:09:19 -0800 Subject: [PATCH] Startup and shutdown improvements. Performance improvements. --- src/cpp/ripple/Application.cpp | 3 ++- src/cpp/ripple/Application.h | 3 +++ src/cpp/ripple/Ledger.cpp | 39 +++++++++++++++++++++++++++++++++ src/cpp/ripple/Ledger.h | 1 + src/cpp/ripple/LedgerMaster.cpp | 18 ++++++++++++--- src/cpp/ripple/SHAMap.cpp | 8 +++++-- src/cpp/ripple/SHAMap.h | 8 +++---- 7 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 3081fb374..fac0ce76a 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -45,7 +45,7 @@ Application::Application() : 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), - mSweepTimer(mAuxService) + mSweepTimer(mAuxService), mShutdown(false) { getRand(mNonce256.begin(), mNonce256.size()); getRand(reinterpret_cast(&mNonceST), sizeof(mNonceST)); @@ -58,6 +58,7 @@ bool Instance::running = true; void Application::stop() { cLog(lsINFO) << "Received shutdown request"; + mShutdown = true; mIOService.stop(); mHashedObjectStore.bulkWrite(); mValidations.flush(); diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index b8ef31649..cafa5b7c7 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -87,6 +87,8 @@ class Application std::map mPeerMap; boost::recursive_mutex mPeerMapLock; + volatile bool mShutdown; + void startNewLedger(); void loadOldLedger(const std::string&); @@ -140,6 +142,7 @@ public: uint256 getNonce256() { return mNonce256; } std::size_t getNonceST() { return mNonceST; } + bool isShutdown() { return mShutdown; } void setup(); void run(); void stop(); diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 0ca0b7d93..543d2d105 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -781,6 +781,45 @@ bool Ledger::getHashesByIndex(uint32 ledgerIndex, uint256& ledgerHash, uint256& #endif } +std::map< uint32, std::pair > Ledger::getHashesByIndex(uint32 minSeq, uint32 maxSeq) +{ +#ifndef NO_SQLITE_PREPARE + std::map< uint32, std::pair > ret; + DatabaseCon *con = theApp->getLedgerDB(); + ScopedLock sl(con->getDBLock()); + + static SqliteStatement pSt(con->getDB()->getSqliteDB(), + "SELECT LedgerSeq,LedgerHash,PrevHash FROM Ledgers INDEXED BY SeqLedger " + "WHERE LedgerSeq >= ? AND LedgerSeq <= ?;"); + + std::pair hashes; + + pSt.bind(1, minSeq); + pSt.bind(2, maxSeq); + + do + { + int r = pSt.step(); + if (pSt.isDone(r)) + { + pSt.reset(); + return ret; + } + if (!pSt.isRow(r)) + { + pSt.reset(); + return ret; + } + hashes.first.SetHex(pSt.peekString(1), true); + hashes.second.SetHex(pSt.peekString(2), true); + ret[pSt.getUInt32(0)] = hashes; + } while(1); + +#else +#error SQLite prepare is required +#endif +} + Ledger::pointer Ledger::getLastFullLedger() { try diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 62de1c819..34d88b8fd 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -202,6 +202,7 @@ public: static Ledger::pointer loadByHash(const uint256& ledgerHash); static uint256 getHashByIndex(uint32 index); static bool getHashesByIndex(uint32 index, uint256& ledgerHash, uint256& parentHash); + static std::map< uint32, std::pair > getHashesByIndex(uint32 minSeq, uint32 maxSeq); void pendSave(bool fromConsensus); // next/prev function diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index a3f35cdf2..8f538f8bf 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -145,6 +145,8 @@ void LedgerMaster::asyncAccept(Ledger::pointer ledger) uint32 seq = ledger->getLedgerSeq(); uint256 prevHash = ledger->getParentHash(); + std::map< uint32, std::pair > ledgerHashes; + while (seq > 0) { { @@ -155,10 +157,20 @@ void LedgerMaster::asyncAccept(Ledger::pointer ledger) break; } - uint256 tHash, pHash; - if (!Ledger::getHashesByIndex(seq, tHash, pHash) || (tHash != prevHash)) + std::map< uint32, std::pair >::iterator it = ledgerHashes.find(seq); + if (it == ledgerHashes.end()) + { + if (theApp->isShutdown()) + return; + ledgerHashes = Ledger::getHashesByIndex((seq < 500) ? 0 : (seq - 499), seq); + it = ledgerHashes.find(seq); + if (it == ledgerHashes.end()) + break; + } + + if (it->second.first != prevHash) break; - prevHash = pHash; + prevHash = it->second.second; } resumeAcquiring(); diff --git a/src/cpp/ripple/SHAMap.cpp b/src/cpp/ripple/SHAMap.cpp index 294cad85c..c733d46e7 100644 --- a/src/cpp/ripple/SHAMap.cpp +++ b/src/cpp/ripple/SHAMap.cpp @@ -23,8 +23,12 @@ DECLARE_INSTANCE(SHAMapTreeNode); void SHAMapNode::setHash() const { - std::size_t h = theApp->getNonceST() + mDepth; - mHash = mNodeID.hash_combine(h); + std::size_t h = theApp->getNonceST() + (mDepth * 0x9e3779b9); + + const unsigned int *ptr = reinterpret_cast(mNodeID.begin()); + for (int i = (mDepth + 3) / 4; i >= 0; --i) + boost::hash_combine(h, *ptr++); + mHash = h; } std::size_t hash_value(const SHAMapNode& mn) diff --git a/src/cpp/ripple/SHAMap.h b/src/cpp/ripple/SHAMap.h index 5e2eb8d09..ff42121f0 100644 --- a/src/cpp/ripple/SHAMap.h +++ b/src/cpp/ripple/SHAMap.h @@ -43,20 +43,21 @@ public: SHAMapNode() : mDepth(0), mHash(0) { ; } SHAMapNode(int depth, const uint256& hash); - virtual ~SHAMapNode() { ; } int getDepth() const { return mDepth; } const uint256& getNodeID() const { return mNodeID; } - bool isValid() const { return (mDepth >= 0) && (mDepth < 64); } + bool isValid() const { return (mDepth >= 0) && (mDepth < 64); } + bool isRoot() const { return mDepth == 0; } size_t getHash() const { if (mHash == 0) setHash(); return mHash; } - virtual bool isPopulated() const { return false; } + virtual bool isPopulated() const { return false; } SHAMapNode getParentNodeID() const { assert(mDepth); return SHAMapNode(mDepth - 1, mNodeID); } + SHAMapNode getChildNodeID(int m) const; int selectBranch(const uint256& hash) const; @@ -68,7 +69,6 @@ public: bool operator!=(const uint256&) const; bool operator<=(const SHAMapNode&) const; bool operator>=(const SHAMapNode&) const; - bool isRoot() const { return mDepth == 0; } virtual std::string getString() const; void dump() const;