Add CachedLedger:

This type alias provide cache-wrapping for Ledger objects.
Through the CachedLedger interface, access to the underlying
Ledger is permitted to allow for cases where the implementation
must perform Ledger specific activities. For example, building
a fetch pack from the contained SHAMap objects.

The CachingReadView is refactored:

* Renamed to CachedView
* Templated on Base, the base type
* base() returns a shared_ptr to the wrapped object
* Constructor requires a shared_ptr<Base>
This commit is contained in:
Vinnie Falco
2015-07-15 14:58:08 -07:00
parent fad9998f9d
commit 110bbf3956
8 changed files with 85 additions and 72 deletions

View File

@@ -2303,7 +2303,7 @@
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\ledger\CachedSLEs.h"> <ClInclude Include="..\..\src\ripple\ledger\CachedSLEs.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\ledger\CachingReadView.h"> <ClInclude Include="..\..\src\ripple\ledger\CachedView.h">
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\ledger\detail\ApplyStateTable.h"> <ClInclude Include="..\..\src\ripple\ledger\detail\ApplyStateTable.h">
</ClInclude> </ClInclude>
@@ -2333,7 +2333,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\ledger\impl\CachingReadView.cpp"> <ClCompile Include="..\..\src\ripple\ledger\impl\CachedView.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile> </ClCompile>

View File

@@ -3030,7 +3030,7 @@
<ClInclude Include="..\..\src\ripple\ledger\CachedSLEs.h"> <ClInclude Include="..\..\src\ripple\ledger\CachedSLEs.h">
<Filter>ripple\ledger</Filter> <Filter>ripple\ledger</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\ledger\CachingReadView.h"> <ClInclude Include="..\..\src\ripple\ledger\CachedView.h">
<Filter>ripple\ledger</Filter> <Filter>ripple\ledger</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\ripple\ledger\detail\ApplyStateTable.h"> <ClInclude Include="..\..\src\ripple\ledger\detail\ApplyStateTable.h">
@@ -3063,7 +3063,7 @@
<ClCompile Include="..\..\src\ripple\ledger\impl\CachedSLEs.cpp"> <ClCompile Include="..\..\src\ripple\ledger\impl\CachedSLEs.cpp">
<Filter>ripple\ledger\impl</Filter> <Filter>ripple\ledger\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\ledger\impl\CachingReadView.cpp"> <ClCompile Include="..\..\src\ripple\ledger\impl\CachedView.cpp">
<Filter>ripple\ledger\impl</Filter> <Filter>ripple\ledger\impl</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\ripple\ledger\impl\Directory.cpp"> <ClCompile Include="..\..\src\ripple\ledger\impl\Directory.cpp">

View File

@@ -22,6 +22,7 @@
#include <ripple/ledger/TxMeta.h> #include <ripple/ledger/TxMeta.h>
#include <ripple/ledger/View.h> #include <ripple/ledger/View.h>
#include <ripple/ledger/CachedView.h>
#include <ripple/app/tx/Transaction.h> #include <ripple/app/tx/Transaction.h>
#include <ripple/basics/CountedObject.h> #include <ripple/basics/CountedObject.h>
#include <ripple/protocol/Indexes.h> #include <ripple/protocol/Indexes.h>
@@ -412,6 +413,9 @@ private:
std::uint32_t mutable mReserveIncrement = 0; std::uint32_t mutable mReserveIncrement = 0;
}; };
/** A ledger wrapped in a CachedView. */
using CachedLedger = CachedView<Ledger>;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
// API // API

View File

@@ -68,7 +68,7 @@ public:
@param ledger A closed ledger @param ledger A closed ledger
*/ */
explicit explicit
OpenLedger (std::shared_ptr< OpenLedger(std::shared_ptr<
Ledger const> const& ledger, Ledger const> const& ledger,
Config const& config, CachedSLEs& cache, Config const& config, CachedSLEs& cache,
beast::Journal journal); beast::Journal journal);

View File

@@ -20,13 +20,13 @@
#include <BeastConfig.h> #include <BeastConfig.h>
#include <ripple/app/ledger/OpenLedger.h> #include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/tx/apply.h> #include <ripple/app/tx/apply.h>
#include <ripple/ledger/CachingReadView.h> #include <ripple/ledger/CachedView.h>
#include <boost/range/adaptor/transformed.hpp> #include <boost/range/adaptor/transformed.hpp>
namespace ripple { namespace ripple {
OpenLedger::OpenLedger( OpenLedger::OpenLedger(std::shared_ptr<
std::shared_ptr<Ledger const> const& ledger, Ledger const> const& ledger,
Config const& config, CachedSLEs& cache, Config const& config, CachedSLEs& cache,
beast::Journal journal) beast::Journal journal)
: j_ (journal) : j_ (journal)
@@ -65,7 +65,7 @@ OpenLedger::modify (std::function<
} }
void void
OpenLedger::accept (std::shared_ptr< OpenLedger::accept(std::shared_ptr<
Ledger const> const& ledger, Ledger const> const& ledger,
OrderedTxs const& locals, bool retriesFirst, OrderedTxs const& locals, bool retriesFirst,
OrderedTxs& retries, ApplyFlags flags, OrderedTxs& retries, ApplyFlags flags,
@@ -113,12 +113,12 @@ OpenLedger::accept (std::shared_ptr<
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::shared_ptr<OpenView> std::shared_ptr<OpenView>
OpenLedger::create (std::shared_ptr< OpenLedger::create(std::shared_ptr<
Ledger const> const& ledger) Ledger const> const& ledger)
{ {
return std::make_shared<OpenView>( return std::make_shared<OpenView>(
open_ledger, std::make_shared< open_ledger, std::make_shared<
CachingReadView const>(ledger, CachedLedger const>(ledger,
cache_)); cache_));
} }

View File

@@ -17,8 +17,8 @@
*/ */
//============================================================================== //==============================================================================
#ifndef RIPPLE_LEDGER_CACHINGREADVIEW_H_INCLUDED #ifndef RIPPLE_LEDGER_CACHEDVIEW_H_INCLUDED
#define RIPPLE_LEDGER_CACHINGREADVIEW_H_INCLUDED #define RIPPLE_LEDGER_CACHEDVIEW_H_INCLUDED
#include <ripple/ledger/CachedSLEs.h> #include <ripple/ledger/CachedSLEs.h>
#include <ripple/ledger/ReadView.h> #include <ripple/ledger/ReadView.h>
@@ -26,41 +26,39 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <type_traits>
namespace ripple { namespace ripple {
//------------------------------------------------------------------------------ namespace detail {
/** ReadView that caches by key and hash. */ class CachedViewImpl
class CachingReadView : public DigestAwareReadView
: public ReadView
{ {
private: private:
DigestAwareReadView const& base_;
CachedSLEs& cache_; CachedSLEs& cache_;
std::mutex mutable mutex_; std::mutex mutable mutex_;
DigestAwareReadView const& base_;
std::shared_ptr<void const> hold_;
std::unordered_map<key_type, std::unordered_map<key_type,
std::shared_ptr<SLE const>, std::shared_ptr<SLE const>,
hardened_hash<>> mutable map_; hardened_hash<>> mutable map_;
public: public:
CachingReadView() = delete; CachedViewImpl() = delete;
CachingReadView (CachingReadView const&) = delete; CachedViewImpl (CachedViewImpl const&) = delete;
CachingReadView& operator= (CachingReadView const&) = delete; CachedViewImpl& operator= (CachedViewImpl const&) = delete;
CachingReadView( CachedViewImpl (DigestAwareReadView const* base,
DigestAwareReadView const* base,
CachedSLEs& cache,
std::shared_ptr<void const> hold);
CachingReadView (std::shared_ptr<
DigestAwareReadView const> const& base,
CachedSLEs& cache) CachedSLEs& cache)
: CachingReadView (&*base, cache, base) : base_ (*base)
, cache_ (cache)
{ {
} }
//
// ReadView
//
bool bool
exists (Keylet const& k) const override; exists (Keylet const& k) const override;
@@ -110,39 +108,58 @@ public:
return base_.txRead(key); return base_.txRead(key);
} }
//
// DigestAwareReadView
//
boost::optional<digest_type>
digest (key_type const& key) const override
{
return base_.digest(key);
}
}; };
//------------------------------------------------------------------------------ } // detail
/** Wrap a DigestAwareReadView with a cache. /** Wraps a DigestAwareReadView to provide caching.
Effects: @tparam Base A subclass of DigestAwareReadView
Returns ownership of a base ReadView that is
wrapped in a thread-safe cache.
The returned ReadView gains a reference to
the base.
Postconditions:
The base object will not be destroyed before
the returned view is destroyed.
The caller is responsible for ensuring that the
`cache` object lifetime extends to the lifetime of
the returned object.
*/ */
inline template <class Base>
std::shared_ptr<ReadView const> class CachedView
makeCached (std::shared_ptr< : public detail::CachedViewImpl
DigestAwareReadView const> const& base,
CachedSLEs& cache)
{ {
return std::make_shared< private:
CachingReadView const>( static_assert(std::is_base_of<
&*base, cache, base); DigestAwareReadView, Base>::value, "");
}
std::shared_ptr<Base const> sp_;
public:
using base_type = Base;
CachedView() = delete;
CachedView (CachedView const&) = delete;
CachedView& operator= (CachedView const&) = delete;
CachedView (std::shared_ptr<
Base const> const& base, CachedSLEs& cache)
: CachedViewImpl (base.get(), cache)
, sp_ (base)
{
}
/** Returns the base type.
@note This breaks encapsulation and bypasses the cache.
*/
std::shared_ptr<Base const> const&
base() const
{
return sp_;
}
};
} // ripple } // ripple

View File

@@ -18,30 +18,21 @@
//============================================================================== //==============================================================================
#include <BeastConfig.h> #include <BeastConfig.h>
#include <ripple/ledger/CachingReadView.h> #include <ripple/ledger/CachedView.h>
#include <ripple/basics/contract.h> #include <ripple/basics/contract.h>
#include <ripple/protocol/Serializer.h> #include <ripple/protocol/Serializer.h>
namespace ripple { namespace ripple {
namespace detail {
CachingReadView::CachingReadView(
DigestAwareReadView const* base,
CachedSLEs& cache,
std::shared_ptr<void const> hold)
: cache_ (cache)
, base_ (*base)
, hold_ (hold)
{
}
bool bool
CachingReadView::exists (Keylet const& k) const CachedViewImpl::exists (Keylet const& k) const
{ {
return read(k) != nullptr; return read(k) != nullptr;
} }
std::shared_ptr<SLE const> std::shared_ptr<SLE const>
CachingReadView::read (Keylet const& k) const CachedViewImpl::read (Keylet const& k) const
{ {
{ {
std::lock_guard< std::lock_guard<
@@ -70,9 +61,10 @@ CachingReadView::read (Keylet const& k) const
return sle; return sle;
} }
if (! k.check(*iter->second)) if (! k.check(*iter->second))
LogicError("CachingReadView::read: wrong type"); LogicError("CachedView::read: wrong type");
return iter->second; return iter->second;
} }
} // detail
} // ripple } // ripple

View File

@@ -23,7 +23,7 @@
#include <ripple/ledger/impl/ApplyViewBase.cpp> #include <ripple/ledger/impl/ApplyViewBase.cpp>
#include <ripple/ledger/impl/ApplyViewImpl.cpp> #include <ripple/ledger/impl/ApplyViewImpl.cpp>
#include <ripple/ledger/impl/CachedSLEs.cpp> #include <ripple/ledger/impl/CachedSLEs.cpp>
#include <ripple/ledger/impl/CachingReadView.cpp> #include <ripple/ledger/impl/CachedView.cpp>
#include <ripple/ledger/impl/Directory.cpp> #include <ripple/ledger/impl/Directory.cpp>
#include <ripple/ledger/impl/OpenView.cpp> #include <ripple/ledger/impl/OpenView.cpp>
#include <ripple/ledger/impl/PaymentSandbox.cpp> #include <ripple/ledger/impl/PaymentSandbox.cpp>