diff --git a/src/ripple/app/ledger/AcceptedLedger.cpp b/src/ripple/app/ledger/AcceptedLedger.cpp index 13a8291cf..dda8edc99 100644 --- a/src/ripple/app/ledger/AcceptedLedger.cpp +++ b/src/ripple/app/ledger/AcceptedLedger.cpp @@ -33,13 +33,11 @@ TaggedCache AcceptedLedger::s_cache ( AcceptedLedger::AcceptedLedger (Ledger::ref ledger) : mLedger (ledger) { - SHAMap& txSet = *ledger->peekTransactionMap (); - - for (std::shared_ptr item = txSet.peekFirstItem (); item; - item = txSet.peekNextItem (item->getTag ())) + for (auto const& item : *ledger->peekTransactionMap()) { SerialIter sit (item->slice()); - insert (std::make_shared (ledger, std::ref (sit))); + insert (std::make_shared( + ledger, std::ref (sit))); } } diff --git a/src/ripple/app/ledger/impl/LedgerConsensus.cpp b/src/ripple/app/ledger/impl/LedgerConsensus.cpp index 105e07782..b2a4d2522 100644 --- a/src/ripple/app/ledger/impl/LedgerConsensus.cpp +++ b/src/ripple/app/ledger/impl/LedgerConsensus.cpp @@ -1857,8 +1857,7 @@ void applyTransactions (std::shared_ptr const& set, if (set) { - for (std::shared_ptr item = set->peekFirstItem (); !!item; - item = set->peekNextItem (item->getTag ())) + for (auto const item : *set) { // If the checkLedger doesn't have the transaction if (!checkLedger->hasTransaction (item->getTag ())) diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index cccea9062..ade17c7a2 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1317,16 +1317,18 @@ bool ApplicationImp::loadOldLedger ( cur = std::make_shared (*cur, true); assert (!cur->isImmutable()); - for (auto it = txns->peekFirstItem(); it != nullptr; - it = txns->peekNextItem(it->getTag())) + for (auto const& item : *txns) { - Transaction::pointer txn = replayLedger->getTransaction(it->getTag()); - m_journal.info << txn->getJson(0); + auto const txn = + replayLedger->getTransaction(item->getTag()); + if (m_journal.info) m_journal.info << + txn->getJson(0); Serializer s; txn->getSTransaction()->add(s); - if (!cur->addTransaction(it->getTag(), s)) - m_journal.warning << "Unable to add transaction " << it->getTag(); - getApp().getHashRouter().setFlag (it->getTag(), SF_SIGGOOD); + if (! cur->addTransaction(item->getTag(), s)) + if (m_journal.warning) m_journal.warning << + "Unable to add transaction " << item->getTag(); + getApp().getHashRouter().setFlag (item->getTag(), SF_SIGGOOD); } // Switch to the mutable snapshot diff --git a/src/ripple/shamap/SHAMap.h b/src/ripple/shamap/SHAMap.h index 7e678ccf7..c582313c2 100644 --- a/src/ripple/shamap/SHAMap.h +++ b/src/ripple/shamap/SHAMap.h @@ -33,9 +33,11 @@ #include #include #include +#include #include #include #include +#include #include namespace ripple { @@ -111,6 +113,19 @@ public: Family& f, beast::Journal journal); + //-------------------------------------------------------------------------- + + /** Iterator to a SHAMap's leaves + This is always a const iterator. + Meets the requirements of ForwardRange. + */ + class iterator; + + iterator begin() const; + iterator end() const; + + //-------------------------------------------------------------------------- + // Returns a new map that's a snapshot of this one. // Handles copy on write for mutable snapshots. std::shared_ptr snapShot (bool isMutable) const; @@ -335,6 +350,70 @@ SHAMap::setUnbacked () backed_ = false; } +//------------------------------------------------------------------------------ + +class SHAMap::iterator + : public boost::iterator_facade< + SHAMap::iterator, + std::shared_ptr const, + std::forward_iterator_tag> +{ +private: + friend class boost::iterator_core_access; + + SHAMap const* map_ = nullptr; + std::shared_ptr< + SHAMapItem const> item_; + +public: + iterator() = default; + iterator (iterator const&) = default; + iterator& operator= (iterator const&) = default; + + iterator (SHAMap const& map, + std::shared_ptr const& item) + : map_(&map) + , item_(item) + { + } + +private: + void + increment() + { + item_ = map_->peekNextItem( + item_->key()); + } + + bool + equal (iterator const& other) const + { + assert(map_ == other.map_); + return item_ == other.item_; + } + + std::shared_ptr< + SHAMapItem const> const& + dereference() const + { + return item_; + } +}; + +inline +SHAMap::iterator +SHAMap::begin() const +{ + return iterator(*this, peekFirstItem()); +} + +inline +SHAMap::iterator +SHAMap::end() const +{ + return iterator(*this, nullptr); +} + } #endif