Add BasicView::txs memberspace interface

This commit is contained in:
Vinnie Falco
2015-06-29 07:34:01 -07:00
parent cb791482a0
commit b7f07aed00
5 changed files with 546 additions and 18 deletions

View File

@@ -632,6 +632,39 @@ bool Ledger::saveValidatedLedger (bool current)
return true; return true;
} }
//------------------------------------------------------------------------------
std::shared_ptr<STTx const>
deserializeTx (SHAMapItem const& item)
{
SerialIter sit(item.slice());
return std::make_shared<STTx const>(sit);
}
std::pair<std::shared_ptr<
STTx const>, std::shared_ptr<
STObject const>>
deserializeTxPlusMeta (SHAMapItem const& item)
{
std::pair<std::shared_ptr<
STTx const>, std::shared_ptr<
STObject const>> result;
SerialIter sit(item.slice());
{
SerialIter s(sit.getSlice(
sit.getVLDataLength()));
result.first = std::make_shared<
STTx const>(s);
}
{
SerialIter s(sit.getSlice(
sit.getVLDataLength()));
result.second = std::make_shared<
STObject const>(s, sfMetadata);
}
return result;
}
/* /*
* Load a ledger from the database. * Load a ledger from the database.
* *
@@ -923,6 +956,80 @@ Ledger::read (Keylet const& k) const
return std::move(sle); return std::move(sle);
} }
//------------------------------------------------------------------------------
class Ledger::tx_iterator_impl
: public BasicView::iterator_impl
{
private:
SHAMap::iterator iter_;
public:
explicit
tx_iterator_impl (SHAMap::iterator iter)
: iter_(iter)
{
}
std::unique_ptr<iterator_impl>
copy() const override
{
return std::make_unique<
tx_iterator_impl>(
iter_);
}
bool
equal (iterator_impl const& impl) const override
{
auto const& other = dynamic_cast<
tx_iterator_impl const&>(impl);
return iter_ == other.iter_;
}
void
increment() override
{
++iter_;
}
txs_type::value_type
dereference() const override
{
return deserializeTxPlusMeta(**iter_);
}
};
bool
Ledger::txEmpty() const
{
return txMap_->getHash().isZero();
}
auto
Ledger::txBegin() const ->
std::unique_ptr<iterator_impl>
{
// Can't iterate open Ledger objects
// because they don't have the metadata!
assert(closed());
return std::make_unique<
tx_iterator_impl>(txMap_->begin());
}
auto
Ledger::txEnd() const ->
std::unique_ptr<iterator_impl>
{
// Can't iterate open Ledger objects
// because they don't have the metadata!
assert(closed());
return std::make_unique<
tx_iterator_impl>(txMap_->end());
}
//------------------------------------------------------------------------------
bool bool
Ledger::unchecked_erase( Ledger::unchecked_erase(
uint256 const& key) uint256 const& key)

View File

@@ -140,6 +140,15 @@ public:
std::shared_ptr<SLE const> std::shared_ptr<SLE const>
read (Keylet const& k) const override; read (Keylet const& k) const override;
bool
txEmpty() const override;
std::unique_ptr<iterator_impl>
txBegin() const override;
std::unique_ptr<iterator_impl>
txEnd() const override;
bool bool
unchecked_erase (uint256 const& key) override; unchecked_erase (uint256 const& key) override;
@@ -418,14 +427,15 @@ public:
static std::map< std::uint32_t, std::pair<uint256, uint256> > static std::map< std::uint32_t, std::pair<uint256, uint256> >
getHashesByIndex (std::uint32_t minSeq, std::uint32_t maxSeq); getHashesByIndex (std::uint32_t minSeq, std::uint32_t maxSeq);
protected: private:
class tx_iterator_impl;
void saveValidatedLedgerAsync(Job&, bool current) void saveValidatedLedgerAsync(Job&, bool current)
{ {
saveValidatedLedger(current); saveValidatedLedger(current);
} }
bool saveValidatedLedger (bool current); bool saveValidatedLedger (bool current);
private:
// ledger close flags // ledger close flags
static const std::uint32_t sLCF_NoConsensusTime = 1; static const std::uint32_t sLCF_NoConsensusTime = 1;
@@ -485,6 +495,29 @@ private:
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Deserialize a SHAMapItem containing a single STTx
Throw:
May throw on deserializaton error
*/
std::shared_ptr<STTx const>
deserializeTx (SHAMapItem const& item);
/** Deserialize a SHAMapItem containing STTx + STObject metadata
The SHAMap must contain two variable length
serialization objects.
Throw:
May throw on deserializaton error
*/
std::pair<std::shared_ptr<
STTx const>, std::shared_ptr<
STObject const>>
deserializeTxPlusMeta (SHAMapItem const& item);
std::tuple<Ledger::pointer, std::uint32_t, uint256> std::tuple<Ledger::pointer, std::uint32_t, uint256>
loadLedgerHelper(std::string const& sqlSuffix); loadLedgerHelper(std::string const& sqlSuffix);

View File

@@ -84,8 +84,9 @@ private:
// The SLEs and Serializers in here are // The SLEs and Serializers in here are
// shared between copy-constructed instances // shared between copy-constructed instances
using item_list = std::map<uint256, Item>; using item_list = std::map<uint256, Item>;
using tx_list = hardened_hash_map< // List of tx, key order
uint256, std::pair<std::shared_ptr< using tx_map = std::map<uint256,
std::pair<std::shared_ptr<
Serializer const>, std::shared_ptr< Serializer const>, std::shared_ptr<
Serializer const>>>; Serializer const>>>;
@@ -94,7 +95,7 @@ private:
BasicView const& base_; BasicView const& base_;
ViewFlags flags_ = tapNONE; ViewFlags flags_ = tapNONE;
ViewInfo info_; ViewInfo info_;
tx_list txs_; tx_map txs_;
item_list items_; item_list items_;
std::uint32_t destroyedCoins_ = 0; std::uint32_t destroyedCoins_ = 0;
boost::optional<STAmount> deliverAmount_; boost::optional<STAmount> deliverAmount_;
@@ -193,6 +194,16 @@ public:
std::shared_ptr<SLE const> std::shared_ptr<SLE const>
read (Keylet const& k) const override; read (Keylet const& k) const override;
virtual
bool
txEmpty() const override;
std::unique_ptr<iterator_impl>
txBegin() const override;
std::unique_ptr<iterator_impl>
txEnd() const override;
bool bool
unchecked_erase( unchecked_erase(
uint256 const& key) override; uint256 const& key) override;
@@ -301,6 +312,8 @@ public:
} }
private: private:
class tx_iterator_impl;
static static
bool bool
threadTx (TxMeta& meta, threadTx (TxMeta& meta,

View File

@@ -170,6 +170,93 @@ MetaView::read (Keylet const& k) const
return sle; return sle;
} }
//------------------------------------------------------------------------------
class MetaView::tx_iterator_impl
: public BasicView::iterator_impl
{
private:
bool metadata_;
tx_map::const_iterator iter_;
public:
explicit
tx_iterator_impl (bool metadata,
tx_map::const_iterator iter)
: metadata_(metadata)
, iter_(iter)
{
}
std::unique_ptr<iterator_impl>
copy() const override
{
return std::make_unique<
tx_iterator_impl>(
metadata_, iter_);
}
bool
equal (iterator_impl const& impl) const override
{
auto const& other = dynamic_cast<
tx_iterator_impl const&>(impl);
return iter_ == other.iter_;
}
void
increment() override
{
++iter_;
}
txs_type::value_type
dereference() const override
{
txs_type::value_type result;
{
SerialIter sit(
iter_->second.first->slice());
result.first = std::make_shared<
STTx const>(sit);
}
if (metadata_)
{
SerialIter sit(
iter_->second.second->slice());
result.second = std::make_shared<
STObject const>(sit, sfMetadata);
}
return result;
}
};
bool
MetaView::txEmpty() const
{
return txs_.empty();
}
auto
MetaView::txBegin() const ->
std::unique_ptr<iterator_impl>
{
return std::make_unique<
tx_iterator_impl>(
closed(), txs_.cbegin());
}
auto
MetaView::txEnd() const ->
std::unique_ptr<iterator_impl>
{
return std::make_unique<
tx_iterator_impl>(
closed(), txs_.cend());
}
//------------------------------------------------------------------------------
bool bool
MetaView::unchecked_erase (uint256 const& key) MetaView::unchecked_erase (uint256 const& key)
{ {
@@ -293,9 +380,7 @@ MetaView::txInsert (uint256 const& key,
if (txs_.count(key) || if (txs_.count(key) ||
base_.txExists(key)) base_.txExists(key))
LogicError("duplicate_tx: " + to_string(key)); LogicError("duplicate_tx: " + to_string(key));
txs_.emplace(std::piecewise_construct, txs_.emplace(key, std::make_pair(
std::forward_as_tuple(key),
std::forward_as_tuple(
txn, metaData)); txn, metaData));
} }

View File

@@ -23,6 +23,8 @@
#include <ripple/protocol/Protocol.h> #include <ripple/protocol/Protocol.h>
#include <ripple/protocol/Serializer.h> #include <ripple/protocol/Serializer.h>
#include <ripple/protocol/STLedgerEntry.h> #include <ripple/protocol/STLedgerEntry.h>
#include <ripple/protocol/STObject.h>
#include <ripple/protocol/STTx.h>
#include <ripple/protocol/TER.h> #include <ripple/protocol/TER.h>
#include <ripple/core/Config.h> #include <ripple/core/Config.h>
#include <ripple/ledger/View.h> #include <ripple/ledger/View.h>
@@ -99,15 +101,27 @@ struct ViewInfo
and transaction items. There is no checkpointing and transaction items. There is no checkpointing
or calculation of metadata. or calculation of metadata.
A raw interace is provided for mutable ledgers. A raw interace is provided for mutable ledgers,
this is used internally by implementations and
should not be called directly.
*/ */
// VFALCO Rename unchecked functions to raw
class BasicView class BasicView
{ {
protected:
class iterator_impl;
public: public:
using key_type = uint256; using key_type = uint256;
using mapped_type = using mapped_type =
std::shared_ptr<SLE const>; std::shared_ptr<SLE const>;
BasicView()
: txs(*this)
{
}
virtual ~BasicView() = default; virtual ~BasicView() = default;
/** Returns information about the ledger. */ /** Returns information about the ledger. */
@@ -191,6 +205,21 @@ public:
std::shared_ptr<SLE const> std::shared_ptr<SLE const>
read (Keylet const& k) const = 0; read (Keylet const& k) const = 0;
// used by the implementation
virtual
bool
txEmpty() const = 0;
// used by the implementation
virtual
std::unique_ptr<iterator_impl>
txBegin() const = 0;
// used by the implementation
virtual
std::unique_ptr<iterator_impl>
txEnd() const = 0;
/** Unconditionally erase a state item. /** Unconditionally erase a state item.
Requirements: Requirements:
@@ -266,7 +295,11 @@ public:
std::size_t std::size_t
txCount() const = 0; txCount() const = 0;
/** Returns `true` if a tx exists in the tx map. */ /** Returns `true` if a tx exists in the tx map.
A tx exists in the map if it is part of the
base ledger, or if it is a newly inserted tx.
*/
virtual virtual
bool bool
txExists (uint256 const& key) const = 0; txExists (uint256 const& key) const = 0;
@@ -290,9 +323,62 @@ public:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// A Forward Range container
// representing the list of transactions
//
class txs_type
{
private:
friend class BasicView;
BasicView& view_;
explicit
txs_type (BasicView& view)
: view_ (view)
{
}
public:
/** ForwardIterator to access transactions */
class iterator;
using const_iterator = iterator;
/** Transaction followed by optional metadata. */
using value_type = std::pair<
std::shared_ptr<STTx const>,
std::shared_ptr<STObject const>>;
txs_type() = delete;
txs_type (txs_type const&) = delete;
txs_type& operator= (txs_type const&) = delete;
bool
empty() const;
/** Return iterator to the beginning of the tx list.
Meets the requirements of `ForwardIterator`
*/
iterator
begin() const;
/** Return iterator to one past the end of the tx list.
Meets the requirements of `ForwardIterator`
*/
iterator
end() const;
};
// Memberspace
// The list of transactions.
txs_type const txs;
//--------------------------------------------------------------------------
// Called to adjust returned balances // Called to adjust returned balances
// This is required to support PaymentView // This is required to support PaymentView
virtual virtual
STAmount STAmount
balanceHook (AccountID const& account, balanceHook (AccountID const& account,
@@ -305,6 +391,175 @@ public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class BasicView::iterator_impl
{
public:
iterator_impl() = default;
iterator_impl(iterator_impl const&) = delete;
iterator_impl& operator=(iterator_impl const&) = delete;
virtual
~iterator_impl() = default;
virtual
std::unique_ptr<iterator_impl>
copy() const = 0;
virtual
bool
equal (iterator_impl const& impl) const = 0;
virtual
void
increment() = 0;
virtual
txs_type::value_type
dereference() const = 0;
};
//------------------------------------------------------------------------------
class BasicView::txs_type::iterator
{
public:
using value_type =
BasicView::txs_type::value_type;
using pointer = value_type const*;
using reference = value_type const&;
using difference_type =
std::ptrdiff_t;
using iterator_category =
std::forward_iterator_tag;
iterator() = default;
iterator (iterator const& other)
: view_ (other.view_)
, impl_ (other.impl_->copy())
, cache_ (other.cache_)
{
}
iterator (iterator&& other)
: view_ (other.view_)
, impl_ (std::move(other.impl_))
, cache_ (std::move(other.cache_))
{
}
// Used by the implementation
explicit
iterator (BasicView const& view,
std::unique_ptr<
iterator_impl> impl)
: view_ (&view)
, impl_ (std::move(impl))
{
}
iterator&
operator= (iterator const& other)
{
if (this == &other)
return *this;
view_ = other.view_;
impl_ = other.impl_->copy();
cache_ = other.cache_;
return *this;
}
iterator&
operator= (iterator&& other)
{
view_ = other.view_;
impl_ = std::move(other.impl_);
cache_ = std::move(other.cache_);
return *this;
}
bool
operator== (iterator const& other) const
{
assert(view_ == other.view_);
return impl_->equal(*other.impl_);
}
bool
operator!= (iterator const& other) const
{
return ! (*this == other);
}
// Can throw
reference
operator*() const
{
if (! cache_)
cache_ = impl_->dereference();
return *cache_;
}
// Can throw
pointer
operator->() const
{
return &**this;
}
iterator&
operator++()
{
impl_->increment();
cache_ = boost::none;
return *this;
}
iterator
operator++(int)
{
iterator prev(*view_,
impl_->copy());
prev.cache_ = std::move(cache_);
++(*this);
return prev;
}
private:
BasicView const* view_ = nullptr;
std::unique_ptr<iterator_impl> impl_;
boost::optional<value_type> mutable cache_;
};
inline
bool
BasicView::txs_type::empty() const
{
return view_.txEmpty();
}
inline
auto
BasicView::txs_type::begin() const ->
iterator
{
return iterator(view_, view_.txBegin());
}
inline
auto
BasicView::txs_type::end() const ->
iterator
{
return iterator(view_, view_.txEnd());
}
//------------------------------------------------------------------------------
enum ViewFlags enum ViewFlags
{ {
tapNONE = 0x00, tapNONE = 0x00,
@@ -327,8 +582,8 @@ enum ViewFlags
}; };
inline inline
ViewFlags operator|( ViewFlags
ViewFlags const& lhs, operator|(ViewFlags const& lhs,
ViewFlags const& rhs) ViewFlags const& rhs)
{ {
return static_cast<ViewFlags>( return static_cast<ViewFlags>(
@@ -338,8 +593,7 @@ ViewFlags operator|(
inline inline
ViewFlags ViewFlags
operator&( operator&(ViewFlags const& lhs,
ViewFlags const& lhs,
ViewFlags const& rhs) ViewFlags const& rhs)
{ {
return static_cast<ViewFlags>( return static_cast<ViewFlags>(
@@ -532,6 +786,24 @@ public:
return view_.read(k); return view_.read(k);
} }
bool
txEmpty() const override
{
return view_.txEmpty();
}
std::unique_ptr<iterator_impl>
txBegin() const override
{
return view_.txBegin();
}
std::unique_ptr<iterator_impl>
txEnd() const override
{
return view_.txEnd();
}
bool bool
unchecked_erase( unchecked_erase(
uint256 const& key) override uint256 const& key) override
@@ -637,6 +909,24 @@ public:
return view_.read(k); return view_.read(k);
} }
bool
txEmpty() const override
{
return view_.txEmpty();
}
std::unique_ptr<iterator_impl>
txBegin() const override
{
return view_.txBegin();
}
std::unique_ptr<iterator_impl>
txEnd() const override
{
return view_.txEnd();
}
bool bool
unchecked_erase( unchecked_erase(
uint256 const& key) override uint256 const& key) override