rippled
Livecache.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_PEERFINDER_LIVECACHE_H_INCLUDED
21 #define RIPPLE_PEERFINDER_LIVECACHE_H_INCLUDED
22 
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>
32 
33 #include <algorithm>
34 
35 namespace ripple {
36 namespace PeerFinder {
37 
38 template <class>
39 class Livecache;
40 
41 namespace detail {
42 
44 {
45 public:
46  explicit LivecacheBase() = default;
47 protected:
48  struct Element
49  : boost::intrusive::list_base_hook <>
50  {
51  Element (Endpoint const& endpoint_)
52  : endpoint (endpoint_)
53  {
54  }
55 
57  };
58 
59  using list_type = boost::intrusive::make_list <Element,
60  boost::intrusive::constant_time_size <false>
61  >::type;
62 
63 public:
68  template <bool IsConst>
69  class Hop
70  {
71  public:
72  // Iterator transformation to extract the endpoint from Element
73  struct Transform
74 #ifdef _LIBCPP_VERSION
75  : public std::unary_function<Element, Endpoint>
76 #endif
77  {
78 #ifndef _LIBCPP_VERSION
81 #endif
82 
83  explicit Transform() = default;
84 
85  Endpoint const& operator() (Element const& e) const
86  {
87  return e.endpoint;
88  }
89  };
90 
91  public:
92  using iterator = boost::transform_iterator <Transform,
93  typename list_type::const_iterator>;
94 
96 
97  using reverse_iterator = boost::transform_iterator <Transform,
98  typename list_type::const_reverse_iterator>;
99 
101 
102  iterator begin () const
103  {
104  return iterator (m_list.get().cbegin(),
105  Transform());
106  }
107 
108  iterator cbegin () const
109  {
110  return iterator (m_list.get().cbegin(),
111  Transform());
112  }
113 
114  iterator end () const
115  {
116  return iterator (m_list.get().cend(),
117  Transform());
118  }
119 
120  iterator cend () const
121  {
122  return iterator (m_list.get().cend(),
123  Transform());
124  }
125 
127  {
128  return reverse_iterator (m_list.get().crbegin(),
129  Transform());
130  }
131 
133  {
134  return reverse_iterator (m_list.get().crbegin(),
135  Transform());
136  }
137 
139  {
140  return reverse_iterator (m_list.get().crend(),
141  Transform());
142  }
143 
145  {
146  return reverse_iterator (m_list.get().crend(),
147  Transform());
148  }
149 
150  // move the element to the end of the container
152  {
153  auto& e (const_cast <Element&>(*pos.base()));
154  m_list.get().erase (m_list.get().iterator_to (e));
155  m_list.get().push_back (e);
156  }
157 
158  private:
159  explicit Hop (typename beast::maybe_const <
160  IsConst, list_type>::type& list)
161  : m_list (list)
162  {
163  }
164 
165  friend class LivecacheBase;
166 
168  IsConst, list_type>::type> m_list;
169  };
170 
171 protected:
172  // Work-around to call Hop's private constructor from Livecache
173  template <bool IsConst>
175  IsConst, list_type>::type& list)
176  {
177  return Hop <IsConst> (list);
178  }
179 };
180 
181 }
182 
183 //------------------------------------------------------------------------------
184 
197 template <class Allocator = std::allocator <char>>
198 class Livecache : protected detail::LivecacheBase
199 {
200 private:
203  Allocator>;
204 
207 
208 public:
209  using allocator_type = Allocator;
210 
212  Livecache (
213  clock_type& clock,
214  beast::Journal journal,
215  Allocator alloc = Allocator());
216 
217  //
218  // Iteration by hops
219  //
220  // The range [begin, end) provides a sequence of list_type
221  // where each list contains endpoints at a given hops.
222  //
223 
224  class hops_t
225  {
226  private:
227  // An endpoint at hops=0 represents the local node.
228  // Endpoints coming in at maxHops are stored at maxHops +1,
229  // but not given out (since they would exceed maxHops). They
230  // are used for automatic connection attempts.
231  //
234 
235  template <bool IsConst>
236  struct Transform
237 #ifdef _LIBCPP_VERSION
238  : public std::unary_function<typename lists_type::value_type, Hop<IsConst>>
239 #endif
240  {
241 #ifndef _LIBCPP_VERSION
242  using first_argument = typename lists_type::value_type;
243  using result_type = Hop <IsConst>;
244 #endif
245 
246  explicit Transform() = default;
247 
248  Hop <IsConst> operator() (typename beast::maybe_const <
249  IsConst, typename lists_type::value_type>::type& list) const
250  {
251  return make_hop <IsConst> (list);
252  }
253  };
254 
255  public:
256  using iterator = boost::transform_iterator <Transform <false>,
257  typename lists_type::iterator>;
258 
259  using const_iterator = boost::transform_iterator <Transform <true>,
260  typename lists_type::const_iterator>;
261 
262  using reverse_iterator = boost::transform_iterator <Transform <false>,
263  typename lists_type::reverse_iterator>;
264 
265  using const_reverse_iterator = boost::transform_iterator <Transform <true>,
266  typename lists_type::const_reverse_iterator>;
267 
269  {
270  return iterator (m_lists.begin(),
272  }
273 
275  {
276  return const_iterator (m_lists.cbegin(),
277  Transform <true>());
278  }
279 
281  {
282  return const_iterator (m_lists.cbegin(),
283  Transform <true>());
284  }
285 
287  {
288  return iterator (m_lists.end(),
290  }
291 
293  {
294  return const_iterator (m_lists.cend(),
295  Transform <true>());
296  }
297 
299  {
300  return const_iterator (m_lists.cend(),
301  Transform <true>());
302  }
303 
305  {
306  return reverse_iterator (m_lists.rbegin(),
308  }
309 
311  {
313  Transform <true>());
314  }
315 
317  {
319  Transform <true>());
320  }
321 
323  {
324  return reverse_iterator (m_lists.rend(),
326  }
327 
329  {
331  Transform <true>());
332  }
333 
335  {
337  Transform <true>());
338  }
339 
341  void shuffle ();
342 
343  std::string histogram() const;
344 
345  private:
346  explicit hops_t (Allocator const& alloc);
347 
348  void insert (Element& e);
349 
350  // Reinsert e at a new hops
351  void reinsert (Element& e, int hops);
352 
353  void remove (Element& e);
354 
355  friend class Livecache;
358  } hops;
359 
361  bool empty () const
362  {
363  return m_cache.empty ();
364  }
365 
367  typename cache_type::size_type size() const
368  {
369  return m_cache.size();
370  }
371 
373  void expire ();
374 
376  void insert (Endpoint const& ep);
377 
380 };
381 
382 //------------------------------------------------------------------------------
383 
384 template <class Allocator>
386  clock_type& clock,
387  beast::Journal journal,
388  Allocator alloc)
389  : m_journal (journal)
390  , m_cache (clock, alloc)
391  , hops (alloc)
392 {
393 }
394 
395 template <class Allocator>
396 void
398 {
399  std::size_t n (0);
400  typename cache_type::time_point const expired (
402  for (auto iter (m_cache.chronological.begin());
403  iter != m_cache.chronological.end() && iter.when() <= expired;)
404  {
405  Element& e (iter->second);
406  hops.remove (e);
407  iter = m_cache.erase (iter);
408  ++n;
409  }
410  if (n > 0)
411  {
412  JLOG(m_journal.debug()) << beast::leftw (18) <<
413  "Livecache expired " << n <<
414  ((n > 1) ? " entries" : " entry");
415  }
416 }
417 
418 template <class Allocator>
420 {
421  // The caller already incremented hop, so if we got a
422  // message at maxHops we will store it at maxHops + 1.
423  // This means we won't give out the address to other peers
424  // but we will use it to make connections and hand it out
425  // when redirecting.
426  //
427  assert (ep.hops <= (Tuning::maxHops + 1));
429  m_cache.emplace (ep.address, ep));
430  Element& e (result.first->second);
431  if (result.second)
432  {
433  hops.insert (e);
434  JLOG(m_journal.debug()) << beast::leftw (18) <<
435  "Livecache insert " << ep.address <<
436  " at hops " << ep.hops;
437  return;
438  }
439  else if (! result.second && (ep.hops > e.endpoint.hops))
440  {
441  // Drop duplicates at higher hops
442  std::size_t const excess (
443  ep.hops - e.endpoint.hops);
444  JLOG(m_journal.trace()) << beast::leftw(18) <<
445  "Livecache drop " << ep.address <<
446  " at hops +" << excess;
447  return;
448  }
449 
450  m_cache.touch (result.first);
451 
452  // Address already in the cache so update metadata
453  if (ep.hops < e.endpoint.hops)
454  {
455  hops.reinsert (e, ep.hops);
456  JLOG(m_journal.debug()) << beast::leftw (18) <<
457  "Livecache update " << ep.address <<
458  " at hops " << ep.hops;
459  }
460  else
461  {
462  JLOG(m_journal.trace()) << beast::leftw (18) <<
463  "Livecache refresh " << ep.address <<
464  " at hops " << ep.hops;
465  }
466 }
467 
468 template <class Allocator>
469 void
471 {
472  typename cache_type::time_point const expired (
474  map ["size"] = size ();
475  map ["hist"] = hops.histogram();
476  beast::PropertyStream::Set set ("entries", map);
477  for (auto iter (m_cache.cbegin()); iter != m_cache.cend(); ++iter)
478  {
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();
486  }
487 }
488 
489 //------------------------------------------------------------------------------
490 
491 template <class Allocator>
492 void
494 {
495  for (auto& list : m_lists)
496  {
498  v.reserve (list.size());
499  std::copy (list.begin(), list.end(),
500  std::back_inserter (v));
501  std::shuffle (v.begin(), v.end(), default_prng());
502  list.clear();
503  for (auto& e : v)
504  list.push_back (e);
505  }
506 }
507 
508 template <class Allocator>
511 {
513  for (typename decltype(m_hist)::size_type i (0);
514  i < m_hist.size(); ++i)
515  {
516  ss << m_hist[i] <<
517  ((i < Tuning::maxHops + 1) ? ", " : "");
518  }
519  return ss.str();
520 }
521 
522 template <class Allocator>
524 {
525  std::fill (m_hist.begin(), m_hist.end(), 0);
526 }
527 
528 template <class Allocator>
529 void
531 {
532  assert (e.endpoint.hops >= 0 &&
533  e.endpoint.hops <= Tuning::maxHops + 1);
534  // This has security implications without a shuffle
535  m_lists [e.endpoint.hops].push_front (e);
536  ++m_hist [e.endpoint.hops];
537 }
538 
539 template <class Allocator>
540 void
542 {
543  assert (numHops >= 0 && numHops <= Tuning::maxHops + 1);
544  list_type& list (m_lists [e.endpoint.hops]);
545  list.erase (list.iterator_to (e));
546  --m_hist [e.endpoint.hops];
547 
548  e.endpoint.hops = numHops;
549  insert (e);
550 }
551 
552 template <class Allocator>
553 void
555 {
556  --m_hist [e.endpoint.hops];
557  list_type& list (m_lists [e.endpoint.hops]);
558  list.erase (list.iterator_to (e));
559 }
560 
561 }
562 }
563 
564 #endif
ripple::PeerFinder::Livecache::m_journal
beast::Journal m_journal
Definition: Livecache.h:205
beast::detail::aged_ordered_container::erase
beast::detail::aged_container_iterator< false, Iterator, Base > erase(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_ordered_container.h:1788
beast::detail::aged_ordered_container::empty
bool empty() const noexcept
Definition: aged_ordered_container.h:811
ripple::PeerFinder::Livecache::hops_t::histogram
std::string histogram() const
Definition: Livecache.h:510
ripple::PeerFinder::Tuning::liveCacheSecondsToLive
static const std::chrono::seconds liveCacheSecondsToLive(30)
ripple::PeerFinder::Livecache::hops_t::rbegin
const_reverse_iterator rbegin() const
Definition: Livecache.h:310
std::chrono::steady_clock
ripple::PeerFinder::Livecache::hops_t::Transform
Definition: Livecache.h:236
ripple::PeerFinder::Livecache::hops_t::Transform::operator()
Hop< IsConst > operator()(typename beast::maybe_const< IsConst, typename lists_type::value_type >::type &list) const
Definition: Livecache.h:248
std::string
STL class.
ripple::PeerFinder::detail::LivecacheBase::Hop::m_list
std::reference_wrapper< typename beast::maybe_const< IsConst, list_type >::type > m_list
Definition: Livecache.h:168
ripple::PeerFinder::detail::LivecacheBase::Element
Definition: Livecache.h:48
ripple::PeerFinder::detail::LivecacheBase
Definition: Livecache.h:43
ripple::PeerFinder::Livecache::hops_t::m_lists
lists_type m_lists
Definition: Livecache.h:356
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:287
beast::PropertyStream::Map
Definition: PropertyStream.h:185
ripple::PeerFinder::Livecache::hops_t::insert
void insert(Element &e)
Definition: Livecache.h:530
std::pair
std::vector::reserve
T reserve(T... args)
std::vector
STL class.
ripple::PeerFinder::detail::LivecacheBase::Hop::begin
iterator begin() const
Definition: Livecache.h:102
beast::detail::aged_container_iterator::when
time_point const & when() const
Definition: aged_container_iterator.h:141
std::back_inserter
T back_inserter(T... args)
ripple::PeerFinder::Livecache::onWrite
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
Definition: Livecache.h:470
ripple::PeerFinder::Livecache::m_cache
cache_type m_cache
Definition: Livecache.h:206
std::stringstream
STL class.
ripple::PeerFinder::detail::LivecacheBase::Hop
A list of Endpoint at the same hops This is a lightweight wrapper around a reference to the underlyin...
Definition: Livecache.h:69
std::reference_wrapper::get
T get(T... args)
ripple::PeerFinder::Livecache::hops_t::const_reverse_iterator
boost::transform_iterator< Transform< true >, typename lists_type::const_reverse_iterator > const_reverse_iterator
Definition: Livecache.h:266
ripple::PeerFinder::Livecache::hops_t::remove
void remove(Element &e)
Definition: Livecache.h:554
ripple::PeerFinder::detail::LivecacheBase::LivecacheBase
LivecacheBase()=default
std::less
beast::PropertyStream::Set
Definition: PropertyStream.h:246
algorithm
beast::detail::aged_ordered_container::time_point
typename clock_type::time_point time_point
Definition: aged_ordered_container.h:90
ripple::PeerFinder::Livecache::size
cache_type::size_type size() const
Returns the number of entries in the cache.
Definition: Livecache.h:367
ripple::PeerFinder::Livecache::hops_t::Transform::Transform
Transform()=default
ripple::PeerFinder::detail::LivecacheBase::Hop::const_iterator
iterator const_iterator
Definition: Livecache.h:95
std::fill
T fill(T... args)
ripple::PeerFinder::Livecache::hops_t::reverse_iterator
boost::transform_iterator< Transform< false >, typename lists_type::reverse_iterator > reverse_iterator
Definition: Livecache.h:263
beast::abstract_clock::now
virtual time_point now() const =0
Returns the current time.
ripple::PeerFinder::detail::LivecacheBase::Element::Element
Element(Endpoint const &endpoint_)
Definition: Livecache.h:51
ripple::PeerFinder::Livecache::insert
void insert(Endpoint const &ep)
Creates or updates an existing Element based on a new message.
Definition: Livecache.h:419
ripple::PeerFinder::Livecache::hops_t::m_hist
Histogram m_hist
Definition: Livecache.h:357
ripple::PeerFinder::detail::LivecacheBase::Hop::Transform
Definition: Livecache.h:73
std::reference_wrapper
ripple::PeerFinder::detail::LivecacheBase::Hop::cbegin
iterator cbegin() const
Definition: Livecache.h:108
beast::detail::aged_ordered_container::chronological_t::end
iterator end()
Definition: aged_ordered_container.h:510
ripple::PeerFinder::detail::LivecacheBase::Hop::cend
iterator cend() const
Definition: Livecache.h:120
beast::detail::aged_ordered_container::cend
const_iterator cend() const
Definition: aged_ordered_container.h:743
beast::detail::aged_ordered_container::clock
clock_type & clock()
Definition: aged_ordered_container.h:659
beast::detail::aged_ordered_container::chronological_t::begin
iterator begin()
Definition: aged_ordered_container.h:495
ripple::PeerFinder::Livecache::cache_type
beast::aged_map< beast::IP::Endpoint, Element, std::chrono::steady_clock, std::less< beast::IP::Endpoint >, Allocator > cache_type
Definition: Livecache.h:203
ripple::PeerFinder::detail::LivecacheBase::Hop::rend
reverse_iterator rend() const
Definition: Livecache.h:138
ripple::PeerFinder::Livecache::hops_t::crend
const_reverse_iterator crend() const
Definition: Livecache.h:334
ripple::PeerFinder::detail::LivecacheBase::Hop::rbegin
reverse_iterator rbegin() const
Definition: Livecache.h:126
ripple::PeerFinder::Livecache::hops_t
Definition: Livecache.h:224
ripple::PeerFinder::Livecache::hops_t::rend
const_reverse_iterator rend() const
Definition: Livecache.h:328
ripple::PeerFinder::detail::LivecacheBase::list_type
boost::intrusive::make_list< Element, boost::intrusive::constant_time_size< false > >::type list_type
Definition: Livecache.h:61
ripple::PeerFinder::detail::LivecacheBase::Hop::end
iterator end() const
Definition: Livecache.h:114
ripple::PeerFinder::Livecache::hops_t::crbegin
const_reverse_iterator crbegin() const
Definition: Livecache.h:316
ripple::PeerFinder::Livecache::Livecache
Livecache(clock_type &clock, beast::Journal journal, Allocator alloc=Allocator())
Create the cache.
Definition: Livecache.h:385
ripple::PeerFinder::Livecache::hops_t::shuffle
void shuffle()
Shuffle each hop list.
Definition: Livecache.h:493
ripple::PeerFinder::Livecache::hops_t::rbegin
reverse_iterator rbegin()
Definition: Livecache.h:304
ripple::PeerFinder::detail::LivecacheBase::Hop::move_back
void move_back(const_iterator pos)
Definition: Livecache.h:151
ripple::set
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
Definition: BasicConfig.h:271
std::array< int, 1+Tuning::maxHops+1 >
ripple::default_prng
beast::xor_shift_engine & default_prng()
Return the default random engine.
Definition: ripple/basics/random.h:68
ripple::PeerFinder::Livecache::hops_t::reinsert
void reinsert(Element &e, int hops)
Definition: Livecache.h:541
ripple::PeerFinder::Livecache
The Livecache holds the short-lived relayed Endpoint messages.
Definition: Livecache.h:39
std::copy
T copy(T... args)
ripple::PeerFinder::detail::LivecacheBase::Hop::iterator
boost::transform_iterator< Transform, typename list_type::const_iterator > iterator
Definition: Livecache.h:93
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:60
ripple::PeerFinder::Livecache::hops_t::end
const_iterator end() const
Definition: Livecache.h:292
ripple::PeerFinder::Livecache::allocator_type
Allocator allocator_type
Definition: Livecache.h:209
ripple::PeerFinder::Livecache::hops_t::iterator
boost::transform_iterator< Transform< false >, typename lists_type::iterator > iterator
Definition: Livecache.h:257
beast::abstract_clock< std::chrono::steady_clock >
std::unary_function
ripple::PeerFinder::detail::LivecacheBase::Hop::crend
reverse_iterator crend() const
Definition: Livecache.h:144
std::array::rend
T rend(T... args)
ripple::PeerFinder::Livecache::hops
class ripple::PeerFinder::Livecache::hops_t hops
ripple::PeerFinder::Livecache::hops_t::const_iterator
boost::transform_iterator< Transform< true >, typename lists_type::const_iterator > const_iterator
Definition: Livecache.h:260
beast::maybe_const
Makes T const or non const depending on a bool.
Definition: maybe_const.h:29
ripple::PeerFinder::detail::LivecacheBase::Hop::Transform::Transform
Transform()=default
beast::leftw
Left justifies a field at the specified width.
Definition: iosformat.h:33
ripple::PeerFinder::Livecache::hops_t::begin
const_iterator begin() const
Definition: Livecache.h:274
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
beast::detail::aged_ordered_container::size
size_type size() const noexcept
Definition: aged_ordered_container.h:817
ripple::PeerFinder::Livecache::hops_t::end
iterator end()
Definition: Livecache.h:286
ripple::PeerFinder::Livecache::hops_t::hops_t
hops_t(Allocator const &alloc)
Definition: Livecache.h:523
ripple::PeerFinder::Livecache::hops_t::cbegin
const_iterator cbegin() const
Definition: Livecache.h:280
ripple::PeerFinder::detail::LivecacheBase::Element::endpoint
Endpoint endpoint
Definition: Livecache.h:56
beast::detail::aged_ordered_container
Associative container where each element is also indexed by time.
Definition: aged_ordered_container.h:86
beast::detail::aged_ordered_container::chronological
class beast::detail::aged_ordered_container::chronological_t chronological
ripple::PeerFinder::detail::LivecacheBase::Hop::Hop
Hop(typename beast::maybe_const< IsConst, list_type >::type &list)
Definition: Livecache.h:159
std::array::begin
T begin(T... args)
ripple::PeerFinder::Livecache::expire
void expire()
Erase entries whose time has expired.
Definition: Livecache.h:397
ripple::PeerFinder::detail::LivecacheBase::Hop::Transform::operator()
Endpoint const & operator()(Element const &e) const
Definition: Livecache.h:85
ripple::PeerFinder::Livecache::hops_t::cend
const_iterator cend() const
Definition: Livecache.h:298
ripple::PeerFinder::detail::LivecacheBase::Hop::reverse_iterator
boost::transform_iterator< Transform, typename list_type::const_reverse_iterator > reverse_iterator
Definition: Livecache.h:98
ripple::PeerFinder::Livecache::empty
bool empty() const
Returns true if the cache is empty.
Definition: Livecache.h:361
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:292
std::size_t
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:39
std::array::end
T end(T... args)
beast::detail::aged_ordered_container::emplace
auto emplace(Args &&... args) -> typename std::enable_if<! maybe_multi, std::pair< iterator, bool >>::type
Definition: aged_ordered_container.h:1716
beast::detail::aged_ordered_container::cbegin
const_iterator cbegin() const
Definition: aged_ordered_container.h:725
ripple::PeerFinder::Endpoint
Describes a connectible peer address along with some metadata.
Definition: PeerfinderManager.h:96
ripple::PeerFinder::detail::LivecacheBase::Hop::const_reverse_iterator
reverse_iterator const_reverse_iterator
Definition: Livecache.h:100
std::shuffle
T shuffle(T... args)
ripple::PeerFinder::Livecache::hops_t::rend
reverse_iterator rend()
Definition: Livecache.h:322
ripple::PeerFinder::Tuning::maxHops
@ maxHops
Definition: peerfinder/impl/Tuning.h:108
ripple::PeerFinder::detail::LivecacheBase::make_hop
static Hop< IsConst > make_hop(typename beast::maybe_const< IsConst, list_type >::type &list)
Definition: Livecache.h:174
ripple::PeerFinder::detail::LivecacheBase::Hop::crbegin
reverse_iterator crbegin() const
Definition: Livecache.h:132
std::array::rbegin
T rbegin(T... args)
ripple::PeerFinder::Livecache::hops_t::Transform::result_type
Hop< IsConst > result_type
Definition: Livecache.h:243
ripple::PeerFinder::Livecache::hops_t::Transform::first_argument
typename lists_type::value_type first_argument
Definition: Livecache.h:242
beast::detail::aged_ordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_ordered_container.h:1009
ripple::PeerFinder::Livecache::hops_t::begin
iterator begin()
Definition: Livecache.h:268