20 #ifndef RIPPLE_PEERFINDER_LIVECACHE_H_INCLUDED
21 #define RIPPLE_PEERFINDER_LIVECACHE_H_INCLUDED
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/random.h>
25 #include <ripple/peerfinder/PeerfinderManager.h>
26 #include <ripple/peerfinder/impl/iosformat.h>
27 #include <ripple/peerfinder/impl/Tuning.h>
28 #include <ripple/beast/container/aged_map.h>
29 #include <ripple/beast/utility/maybe_const.h>
30 #include <boost/intrusive/list.hpp>
31 #include <boost/iterator/transform_iterator.hpp>
36 namespace PeerFinder {
49 : boost::intrusive::list_base_hook <>
60 boost::intrusive::constant_time_size <false>
68 template <
bool IsConst>
74 #ifdef _LIBCPP_VERSION
78 #ifndef _LIBCPP_VERSION
92 using iterator = boost::transform_iterator <Transform,
93 typename list_type::const_iterator>;
98 typename list_type::const_reverse_iterator>;
153 auto& e (
const_cast <Element&
>(*pos.base()));
173 template <
bool IsConst>
197 template <
class Allocator = std::allocator <
char>>
198 class Livecache :
protected detail::LivecacheBase
215 Allocator alloc = Allocator());
235 template <
bool IsConst>
237 #ifdef _LIBCPP_VERSION
241 #ifndef _LIBCPP_VERSION
249 IsConst,
typename lists_type::value_type>::type& list)
const
251 return make_hop <IsConst> (list);
256 using iterator = boost::transform_iterator <Transform <false>,
257 typename lists_type::iterator>;
259 using const_iterator = boost::transform_iterator <Transform <true>,
260 typename lists_type::const_iterator>;
263 typename lists_type::reverse_iterator>;
266 typename lists_type::const_reverse_iterator>;
346 explicit hops_t (Allocator
const& alloc);
384 template <
class Allocator>
389 : m_journal (journal)
390 , m_cache (clock, alloc)
395 template <
class Allocator>
405 Element& e (iter->second);
407 iter = m_cache.
erase (iter);
413 "Livecache expired " << n <<
414 ((n > 1) ?
" entries" :
" entry");
418 template <
class Allocator>
429 m_cache.
emplace (ep.address, ep));
430 Element& e (result.
first->second);
435 "Livecache insert " << ep.address <<
436 " at hops " << ep.hops;
439 else if (! result.
second && (ep.hops > e.endpoint.hops))
443 ep.hops - e.endpoint.hops);
445 "Livecache drop " << ep.address <<
446 " at hops +" << excess;
453 if (ep.hops < e.endpoint.hops)
455 hops.reinsert (e, ep.hops);
457 "Livecache update " << ep.address <<
458 " at hops " << ep.hops;
463 "Livecache refresh " << ep.address <<
464 " at hops " << ep.hops;
468 template <
class Allocator>
474 map [
"size"] = size ();
475 map [
"hist"] = hops.histogram();
477 for (
auto iter (m_cache.
cbegin()); iter != m_cache.
cend(); ++iter)
479 auto const& e (iter->second);
481 item [
"hops"] = e.endpoint.hops;
482 item [
"address"] = e.endpoint.address.to_string ();
484 ss << (iter.when() - expired).count();
485 item [
"expires"] = ss.
str();
491 template <
class Allocator>
495 for (
auto& list : m_lists)
508 template <
class Allocator>
513 for (
typename decltype(m_hist)::size_type i (0);
514 i < m_hist.size(); ++i)
522 template <
class Allocator>
525 std::fill (m_hist.begin(), m_hist.end(), 0);
528 template <
class Allocator>
532 assert (e.endpoint.hops >= 0 &&
535 m_lists [e.endpoint.hops].push_front (e);
536 ++m_hist [e.endpoint.hops];
539 template <
class Allocator>
544 list_type& list (m_lists [e.endpoint.
hops]);
545 list.erase (list.iterator_to (e));
546 --m_hist [e.endpoint.
hops];
548 e.endpoint.
hops = numHops;
552 template <
class Allocator>
556 --m_hist [e.endpoint.
hops];
557 list_type& list (m_lists [e.endpoint.
hops]);
558 list.erase (list.iterator_to (e));
beast::detail::aged_container_iterator< false, Iterator, Base > erase(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
bool empty() const noexcept
std::string histogram() const
static const std::chrono::seconds liveCacheSecondsToLive(30)
const_reverse_iterator rbegin() const
std::reference_wrapper< typename beast::maybe_const< IsConst, list_type >::type > m_list
Stream trace() const
Severity stream access functions.
time_point const & when() const
T back_inserter(T... args)
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
A list of Endpoint at the same hops This is a lightweight wrapper around a reference to the underlyin...
boost::transform_iterator< Transform< true >, typename lists_type::const_reverse_iterator > const_reverse_iterator
typename clock_type::time_point time_point
cache_type::size_type size() const
Returns the number of entries in the cache.
boost::transform_iterator< Transform< false >, typename lists_type::reverse_iterator > reverse_iterator
virtual time_point now() const =0
Returns the current time.
Element(Endpoint const &endpoint_)
void insert(Endpoint const &ep)
Creates or updates an existing Element based on a new message.
const_iterator cend() const
beast::aged_map< beast::IP::Endpoint, Element, std::chrono::steady_clock, std::less< beast::IP::Endpoint >, Allocator > cache_type
reverse_iterator rend() const
const_reverse_iterator crend() const
reverse_iterator rbegin() const
const_reverse_iterator rend() const
boost::intrusive::make_list< Element, boost::intrusive::constant_time_size< false > >::type list_type
const_reverse_iterator crbegin() const
Livecache(clock_type &clock, beast::Journal journal, Allocator alloc=Allocator())
Create the cache.
void shuffle()
Shuffle each hop list.
reverse_iterator rbegin()
void move_back(const_iterator pos)
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
beast::xor_shift_engine & default_prng()
Return the default random engine.
void reinsert(Element &e, int hops)
The Livecache holds the short-lived relayed Endpoint messages.
boost::transform_iterator< Transform, typename list_type::const_iterator > iterator
A generic endpoint for log messages.
const_iterator end() const
boost::transform_iterator< Transform< false >, typename lists_type::iterator > iterator
reverse_iterator crend() const
class ripple::PeerFinder::Livecache::hops_t hops
boost::transform_iterator< Transform< true >, typename lists_type::const_iterator > const_iterator
Makes T const or non const depending on a bool.
Left justifies a field at the specified width.
const_iterator begin() const
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
size_type size() const noexcept
hops_t(Allocator const &alloc)
const_iterator cbegin() const
Associative container where each element is also indexed by time.
class beast::detail::aged_ordered_container::chronological_t chronological
Hop(typename beast::maybe_const< IsConst, list_type >::type &list)
void expire()
Erase entries whose time has expired.
const_iterator cend() const
boost::transform_iterator< Transform, typename list_type::const_reverse_iterator > reverse_iterator
bool empty() const
Returns true if the cache is empty.
A version-independent IP address and port combination.
auto emplace(Args &&... args) -> typename std::enable_if<! maybe_multi, std::pair< iterator, bool >>::type
const_iterator cbegin() const
Describes a connectible peer address along with some metadata.
reverse_iterator const_reverse_iterator
static Hop< IsConst > make_hop(typename beast::maybe_const< IsConst, list_type >::type &list)
reverse_iterator crbegin() const
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)