3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/random.h>
5#include <xrpl/beast/container/aged_map.h>
6#include <xrpl/beast/net/IPEndpoint.h>
7#include <xrpl/beast/utility/Journal.h>
8#include <xrpl/beast/utility/PropertyStream.h>
9#include <xrpl/beast/utility/instrumentation.h>
10#include <xrpl/beast/utility/maybe_const.h>
11#include <xrpl/peerfinder/Types.h>
12#include <xrpl/peerfinder/detail/Tuning.h>
14#include <boost/intrusive/list.hpp>
15#include <boost/iterator/transform_iterator.hpp>
45 struct Element : boost::intrusive::list_base_hook<>
55 boost::intrusive::make_list<Element, boost::intrusive::constant_time_size<false>>::type;
63 template <
bool IsConst>
83 using iterator = boost::transform_iterator<Transform, list_type::const_iterator>;
88 boost::transform_iterator<Transform, list_type::const_reverse_iterator>;
144 auto& e(
const_cast<Element&
>(*pos.base()));
145 list_.get().erase(
list_.get().iterator_to(e));
146 list_.get().push_back(e);
161 template <
bool IsConst>
186template <
class Allocator = std::allocator<
char>>
226 template <
bool IsConst>
242 using iterator = boost::transform_iterator<Transform<false>, lists_type::iterator>;
245 boost::transform_iterator<Transform<true>, lists_type::const_iterator>;
248 boost::transform_iterator<Transform<false>, lists_type::reverse_iterator>;
251 boost::transform_iterator<Transform<true>, lists_type::const_reverse_iterator>;
335 explicit HopsT(Allocator
const& alloc);
391template <
class Allocator>
397template <
class Allocator>
404 for (
auto iter(
cache_.chronological.begin());
405 iter !=
cache_.chronological.end() && iter.when() <= expired;)
409 iter =
cache_.erase(iter);
415 << ((n > 1) ?
" entries" :
" entry");
419template <
class Allocator>
431 "xrpl::peer_finder::Livecache::insert : maximum input hops");
433 Element& e(result.first->second);
438 <<
" at hops " << ep.
hops;
446 <<
" at hops +" << excess;
450 cache_.touch(result.first);
457 <<
" at hops " << ep.
hops;
462 <<
" at hops " << ep.
hops;
466template <
class Allocator>
472 map[
"size"] =
size();
473 map[
"hist"] =
hops.histogram();
475 for (
auto iter(
cache_.cbegin()); iter !=
cache_.cend(); ++iter)
477 auto const& e(iter->second);
479 item[
"hops"] = e.endpoint.hops;
480 item[
"address"] = e.endpoint.address.toString();
482 ss << (iter.when() - expired).count();
483 item[
"expires"] = ss.
str();
489template <
class Allocator>
505template <
class Allocator>
510 for (
auto const& h :
hist_)
519template <
class Allocator>
525template <
class Allocator>
531 "xrpl::peer_finder::Livecache::HopsT::insert : maximum input hops");
537template <
class Allocator>
543 "xrpl::peer_finder::Livecache::HopsT::reinsert : maximum hops input");
546 list.erase(list.iterator_to(e));
554template <
class Allocator>
561 list.erase(list.iterator_to(e));
T back_inserter(T... args)
A generic endpoint for log messages.
clock_type::time_point time_point
A version-independent IP address and port combination.
void shuffle()
Shuffle each hop list.
HopsT(Allocator const &alloc)
void reinsert(Element &e, std::uint32_t hops)
boost::transform_iterator< Transform< false >, lists_type::reverse_iterator > reverse_iterator
boost::transform_iterator< Transform< true >, lists_type::const_reverse_iterator > const_reverse_iterator
reverse_iterator rbegin()
const_reverse_iterator rend() const
const_reverse_iterator crend() const
const_iterator end() const
boost::transform_iterator< Transform< true >, lists_type::const_iterator > const_iterator
std::array< int, 1+tuning::kMaxHops+1 > Histogram
boost::transform_iterator< Transform< false >, lists_type::iterator > iterator
const_iterator cend() const
const_reverse_iterator crbegin() const
const_reverse_iterator rbegin() const
const_iterator cbegin() const
std::string histogram() const
const_iterator begin() const
std::array< list_type, 1+tuning::kMaxHops+1 > lists_type
The Livecache holds the short-lived relayed Endpoint messages.
beast::aged_map< beast::ip::Endpoint, Element, std::chrono::steady_clock, std::less< beast::ip::Endpoint >, Allocator > cache_type
void expire()
Erase entries whose time has expired.
cache_type::size_type size() const
Returns the number of entries in the cache.
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
void insert(Endpoint const &ep)
Creates or updates an existing Element based on a new message.
Livecache(clock_type &clock, beast::Journal journal, Allocator alloc=Allocator())
Create the cache.
class xrpl::peer_finder::Livecache::HopsT hops
bool empty() const
Returns true if the cache is empty.
A list of Endpoint at the same hops This is a lightweight wrapper around a reference to the underlyin...
reverse_iterator rend() const
reverse_iterator rbegin() const
Hop(beast::MaybeConst< IsConst, list_type >::type &list)
reverse_iterator crbegin() const
reverse_iterator const_reverse_iterator
std::reference_wrapper< typename beast::MaybeConst< IsConst, list_type >::type > list_
friend class LivecacheBase
boost::transform_iterator< Transform, list_type::const_iterator > iterator
reverse_iterator crend() const
void moveBack(const_iterator pos)
boost::transform_iterator< Transform, list_type::const_reverse_iterator > reverse_iterator
boost::intrusive::make_list< Element, boost::intrusive::constant_time_size< false > >::type list_type
static Hop< IsConst > makeHop(beast::MaybeConst< IsConst, list_type >::type &list)
detail::AgedOrderedContainer< false, true, Key, T, Clock, Compare, Allocator > aged_map
constexpr std::uint32_t kMaxHops
constexpr std::chrono::seconds kLiveCacheSecondsToLive(30)
beast::AbstractClock< std::chrono::steady_clock > clock_type
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,...
Dir::ConstIterator const_iterator
beast::xor_shift_engine & defaultPrng()
Return the default random engine.
std:: conditional_t< IsConst, typename std::remove_const< T >::type const, std::remove_const_t< T > > type
Describes a connectable peer address along with some metadata.
beast::ip::Endpoint address
Element(Endpoint endpoint)