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/beast/container/aged_map.h>
26 #include <ripple/beast/utility/maybe_const.h>
27 #include <ripple/peerfinder/PeerfinderManager.h>
28 #include <ripple/peerfinder/impl/Tuning.h>
29 #include <ripple/peerfinder/impl/iosformat.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 
48 protected:
49  struct Element : boost::intrusive::list_base_hook<>
50  {
51  Element(Endpoint const& endpoint_) : endpoint(endpoint_)
52  {
53  }
54 
56  };
57 
58  using list_type = boost::intrusive::
59  make_list<Element, boost::intrusive::constant_time_size<false>>::type;
60 
61 public:
66  template <bool IsConst>
67  class Hop
68  {
69  public:
70  // Iterator transformation to extract the endpoint from Element
71  struct Transform
72 #ifdef _LIBCPP_VERSION
73  : public std::unary_function<Element, Endpoint>
74 #endif
75  {
76 #ifndef _LIBCPP_VERSION
79 #endif
80 
81  explicit Transform() = default;
82 
83  Endpoint const&
84  operator()(Element const& e) const
85  {
86  return e.endpoint;
87  }
88  };
89 
90  public:
91  using iterator = boost::
92  transform_iterator<Transform, typename list_type::const_iterator>;
93 
95 
96  using reverse_iterator = boost::transform_iterator<
97  Transform,
98  typename list_type::const_reverse_iterator>;
99 
101 
102  iterator
103  begin() const
104  {
105  return iterator(m_list.get().cbegin(), Transform());
106  }
107 
108  iterator
109  cbegin() const
110  {
111  return iterator(m_list.get().cbegin(), Transform());
112  }
113 
114  iterator
115  end() const
116  {
117  return iterator(m_list.get().cend(), Transform());
118  }
119 
120  iterator
121  cend() const
122  {
123  return iterator(m_list.get().cend(), Transform());
124  }
125 
127  rbegin() const
128  {
129  return reverse_iterator(m_list.get().crbegin(), Transform());
130  }
131 
133  crbegin() const
134  {
135  return reverse_iterator(m_list.get().crbegin(), Transform());
136  }
137 
139  rend() const
140  {
141  return reverse_iterator(m_list.get().crend(), Transform());
142  }
143 
145  crend() const
146  {
147  return reverse_iterator(m_list.get().crend(), Transform());
148  }
149 
150  // move the element to the end of the container
151  void
153  {
154  auto& e(const_cast<Element&>(*pos.base()));
155  m_list.get().erase(m_list.get().iterator_to(e));
156  m_list.get().push_back(e);
157  }
158 
159  private:
160  explicit Hop(
162  : m_list(list)
163  {
164  }
165 
166  friend class LivecacheBase;
167 
171  };
172 
173 protected:
174  // Work-around to call Hop's private constructor from Livecache
175  template <bool IsConst>
176  static Hop<IsConst>
178  {
179  return Hop<IsConst>(list);
180  }
181 };
182 
183 } // namespace detail
184 
185 //------------------------------------------------------------------------------
186 
199 template <class Allocator = std::allocator<char>>
200 class Livecache : protected detail::LivecacheBase
201 {
202 private:
203  using cache_type = beast::aged_map<
205  Element,
208  Allocator>;
209 
212 
213 public:
214  using allocator_type = Allocator;
215 
217  Livecache(
218  clock_type& clock,
219  beast::Journal journal,
220  Allocator alloc = Allocator());
221 
222  //
223  // Iteration by hops
224  //
225  // The range [begin, end) provides a sequence of list_type
226  // where each list contains endpoints at a given hops.
227  //
228 
229  class hops_t
230  {
231  private:
232  // An endpoint at hops=0 represents the local node.
233  // Endpoints coming in at maxHops are stored at maxHops +1,
234  // but not given out (since they would exceed maxHops). They
235  // are used for automatic connection attempts.
236  //
239 
240  template <bool IsConst>
241  struct Transform
242 #ifdef _LIBCPP_VERSION
243  : public std::
244  unary_function<typename lists_type::value_type, Hop<IsConst>>
245 #endif
246  {
247 #ifndef _LIBCPP_VERSION
248  using first_argument = typename lists_type::value_type;
249  using result_type = Hop<IsConst>;
250 #endif
251 
252  explicit Transform() = default;
253 
254  Hop<IsConst>
256  IsConst,
257  typename lists_type::value_type>::type& list) const
258  {
259  return make_hop<IsConst>(list);
260  }
261  };
262 
263  public:
264  using iterator = boost::
265  transform_iterator<Transform<false>, typename lists_type::iterator>;
266 
267  using const_iterator = boost::transform_iterator<
269  typename lists_type::const_iterator>;
270 
271  using reverse_iterator = boost::transform_iterator<
273  typename lists_type::reverse_iterator>;
274 
275  using const_reverse_iterator = boost::transform_iterator<
277  typename lists_type::const_reverse_iterator>;
278 
279  iterator
281  {
282  return iterator(m_lists.begin(), Transform<false>());
283  }
284 
286  begin() const
287  {
289  }
290 
292  cbegin() const
293  {
295  }
296 
297  iterator
298  end()
299  {
300  return iterator(m_lists.end(), Transform<false>());
301  }
302 
304  end() const
305  {
307  }
308 
310  cend() const
311  {
313  }
314 
317  {
319  }
320 
322  rbegin() const
323  {
325  }
326 
328  crbegin() const
329  {
331  }
332 
335  {
337  }
338 
340  rend() const
341  {
343  }
344 
346  crend() const
347  {
349  }
350 
352  void
353  shuffle();
354 
356  histogram() const;
357 
358  private:
359  explicit hops_t(Allocator const& alloc);
360 
361  void
362  insert(Element& e);
363 
364  // Reinsert e at a new hops
365  void
366  reinsert(Element& e, int hops);
367 
368  void
369  remove(Element& e);
370 
371  friend class Livecache;
374  } hops;
375 
377  bool
378  empty() const
379  {
380  return m_cache.empty();
381  }
382 
384  typename cache_type::size_type
385  size() const
386  {
387  return m_cache.size();
388  }
389 
391  void
392  expire();
393 
395  void
396  insert(Endpoint const& ep);
397 
399  void
401 };
402 
403 //------------------------------------------------------------------------------
404 
405 template <class Allocator>
407  clock_type& clock,
408  beast::Journal journal,
409  Allocator alloc)
410  : m_journal(journal), m_cache(clock, alloc), hops(alloc)
411 {
412 }
413 
414 template <class Allocator>
415 void
417 {
418  std::size_t n(0);
419  typename cache_type::time_point const expired(
421  for (auto iter(m_cache.chronological.begin());
422  iter != m_cache.chronological.end() && iter.when() <= expired;)
423  {
424  Element& e(iter->second);
425  hops.remove(e);
426  iter = m_cache.erase(iter);
427  ++n;
428  }
429  if (n > 0)
430  {
431  JLOG(m_journal.debug()) << beast::leftw(18) << "Livecache expired " << n
432  << ((n > 1) ? " entries" : " entry");
433  }
434 }
435 
436 template <class Allocator>
437 void
439 {
440  // The caller already incremented hop, so if we got a
441  // message at maxHops we will store it at maxHops + 1.
442  // This means we won't give out the address to other peers
443  // but we will use it to make connections and hand it out
444  // when redirecting.
445  //
446  assert(ep.hops <= (Tuning::maxHops + 1));
448  m_cache.emplace(ep.address, ep));
449  Element& e(result.first->second);
450  if (result.second)
451  {
452  hops.insert(e);
453  JLOG(m_journal.debug()) << beast::leftw(18) << "Livecache insert "
454  << ep.address << " at hops " << ep.hops;
455  return;
456  }
457  else if (!result.second && (ep.hops > e.endpoint.hops))
458  {
459  // Drop duplicates at higher hops
460  std::size_t const excess(ep.hops - e.endpoint.hops);
461  JLOG(m_journal.trace()) << beast::leftw(18) << "Livecache drop "
462  << ep.address << " at hops +" << excess;
463  return;
464  }
465 
466  m_cache.touch(result.first);
467 
468  // Address already in the cache so update metadata
469  if (ep.hops < e.endpoint.hops)
470  {
471  hops.reinsert(e, ep.hops);
472  JLOG(m_journal.debug()) << beast::leftw(18) << "Livecache update "
473  << ep.address << " at hops " << ep.hops;
474  }
475  else
476  {
477  JLOG(m_journal.trace()) << beast::leftw(18) << "Livecache refresh "
478  << ep.address << " at hops " << ep.hops;
479  }
480 }
481 
482 template <class Allocator>
483 void
485 {
486  typename cache_type::time_point const expired(
488  map["size"] = size();
489  map["hist"] = hops.histogram();
490  beast::PropertyStream::Set set("entries", map);
491  for (auto iter(m_cache.cbegin()); iter != m_cache.cend(); ++iter)
492  {
493  auto const& e(iter->second);
495  item["hops"] = e.endpoint.hops;
496  item["address"] = e.endpoint.address.to_string();
498  ss << (iter.when() - expired).count();
499  item["expires"] = ss.str();
500  }
501 }
502 
503 //------------------------------------------------------------------------------
504 
505 template <class Allocator>
506 void
508 {
509  for (auto& list : m_lists)
510  {
512  v.reserve(list.size());
513  std::copy(list.begin(), list.end(), std::back_inserter(v));
514  std::shuffle(v.begin(), v.end(), default_prng());
515  list.clear();
516  for (auto& e : v)
517  list.push_back(e);
518  }
519 }
520 
521 template <class Allocator>
524 {
526  for (typename decltype(m_hist)::size_type i(0); i < m_hist.size(); ++i)
527  {
528  ss << m_hist[i] << ((i < Tuning::maxHops + 1) ? ", " : "");
529  }
530  return ss.str();
531 }
532 
533 template <class Allocator>
535 {
536  std::fill(m_hist.begin(), m_hist.end(), 0);
537 }
538 
539 template <class Allocator>
540 void
542 {
543  assert(e.endpoint.hops >= 0 && e.endpoint.hops <= Tuning::maxHops + 1);
544  // This has security implications without a shuffle
545  m_lists[e.endpoint.hops].push_front(e);
546  ++m_hist[e.endpoint.hops];
547 }
548 
549 template <class Allocator>
550 void
552 {
553  assert(numHops >= 0 && numHops <= Tuning::maxHops + 1);
554  list_type& list(m_lists[e.endpoint.hops]);
555  list.erase(list.iterator_to(e));
556  --m_hist[e.endpoint.hops];
557 
558  e.endpoint.hops = numHops;
559  insert(e);
560 }
561 
562 template <class Allocator>
563 void
565 {
566  --m_hist[e.endpoint.hops];
567  list_type& list(m_lists[e.endpoint.hops]);
568  list.erase(list.iterator_to(e));
569 }
570 
571 } // namespace PeerFinder
572 } // namespace ripple
573 
574 #endif
ripple::PeerFinder::Livecache::m_journal
beast::Journal m_journal
Definition: Livecache.h:210
ripple::PeerFinder::detail::LivecacheBase::Hop::reverse_iterator
boost::transform_iterator< Transform, typename list_type::const_reverse_iterator > reverse_iterator
Definition: Livecache.h:98
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:2016
beast::detail::aged_ordered_container::empty
bool empty() const noexcept
Definition: aged_ordered_container.h:841
ripple::PeerFinder::Livecache::hops_t::histogram
std::string histogram() const
Definition: Livecache.h:523
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:322
std::chrono::steady_clock
ripple::PeerFinder::Livecache::hops_t::Transform
Definition: Livecache.h:241
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:255
ripple::Dir::const_iterator
Definition: Directory.h:49
std::string
STL class.
ripple::PeerFinder::detail::LivecacheBase::Element
Definition: Livecache.h:49
ripple::PeerFinder::detail::LivecacheBase
Definition: Livecache.h:43
ripple::PeerFinder::Livecache::hops_t::m_lists
lists_type m_lists
Definition: Livecache.h:372
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::PeerFinder::Livecache::hops_t::insert
void insert(Element &e)
Definition: Livecache.h:541
ripple::PeerFinder::Livecache::hops_t::reverse_iterator
boost::transform_iterator< Transform< false >, typename lists_type::reverse_iterator > reverse_iterator
Definition: Livecache.h:273
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:103
beast::detail::aged_container_iterator::when
time_point const & when() const
Definition: aged_container_iterator.h:158
std::back_inserter
T back_inserter(T... args)
ripple::PeerFinder::Livecache::onWrite
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
Definition: Livecache.h:484
ripple::PeerFinder::Livecache::hops_t::Transform::result_type
Hop< IsConst > result_type
Definition: Livecache.h:249
ripple::PeerFinder::Livecache::m_cache
cache_type m_cache
Definition: Livecache.h:211
ripple::PeerFinder::Livecache::hops_t::iterator
boost::transform_iterator< Transform< false >, typename lists_type::iterator > iterator
Definition: Livecache.h:265
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:67
std::reference_wrapper::get
T get(T... args)
ripple::PeerFinder::Livecache::hops_t::remove
void remove(Element &e)
Definition: Livecache.h:564
ripple::PeerFinder::detail::LivecacheBase::list_type
boost::intrusive::make_list< Element, boost::intrusive::constant_time_size< false > >::type list_type
Definition: Livecache.h:59
ripple::PeerFinder::detail::LivecacheBase::LivecacheBase
LivecacheBase()=default
std::less
beast::PropertyStream::Set
Definition: PropertyStream.h:308
algorithm
beast::detail::aged_ordered_container::time_point
typename clock_type::time_point time_point
Definition: aged_ordered_container.h:86
ripple::PeerFinder::Livecache::size
cache_type::size_type size() const
Returns the number of entries in the cache.
Definition: Livecache.h:385
ripple::PeerFinder::Livecache::hops_t::Transform::Transform
Transform()=default
ripple::PeerFinder::detail::LivecacheBase::Hop::const_iterator
iterator const_iterator
Definition: Livecache.h:94
std::fill
T fill(T... args)
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:438
ripple::PeerFinder::Livecache::hops_t::m_hist
Histogram m_hist
Definition: Livecache.h:373
ripple::PeerFinder::detail::LivecacheBase::Hop::Transform
Definition: Livecache.h:71
std::reference_wrapper
ripple::PeerFinder::detail::LivecacheBase::Hop::iterator
boost::transform_iterator< Transform, typename list_type::const_iterator > iterator
Definition: Livecache.h:92
ripple::PeerFinder::detail::LivecacheBase::Hop::cbegin
iterator cbegin() const
Definition: Livecache.h:109
beast::detail::aged_ordered_container::chronological_t::end
iterator end()
Definition: aged_ordered_container.h:508
ripple::PeerFinder::detail::LivecacheBase::Hop::cend
iterator cend() const
Definition: Livecache.h:121
beast::detail::aged_ordered_container::cend
const_iterator cend() const
Definition: aged_ordered_container.h:773
beast::detail::aged_ordered_container::clock
clock_type & clock()
Definition: aged_ordered_container.h:689
beast::detail::aged_ordered_container::chronological_t::begin
iterator begin()
Definition: aged_ordered_container.h:490
ripple::PeerFinder::detail::LivecacheBase::Hop::rend
reverse_iterator rend() const
Definition: Livecache.h:139
ripple::PeerFinder::Livecache::hops_t::crend
const_reverse_iterator crend() const
Definition: Livecache.h:346
ripple::PeerFinder::detail::LivecacheBase::Hop::rbegin
reverse_iterator rbegin() const
Definition: Livecache.h:127
ripple::PeerFinder::Livecache::hops_t
Definition: Livecache.h:229
ripple::PeerFinder::Livecache::hops_t::rend
const_reverse_iterator rend() const
Definition: Livecache.h:340
ripple::PeerFinder::detail::LivecacheBase::Hop::end
iterator end() const
Definition: Livecache.h:115
ripple::PeerFinder::Livecache::hops_t::crbegin
const_reverse_iterator crbegin() const
Definition: Livecache.h:328
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:1929
ripple::PeerFinder::Livecache::Livecache
Livecache(clock_type &clock, beast::Journal journal, Allocator alloc=Allocator())
Create the cache.
Definition: Livecache.h:406
ripple::PeerFinder::Livecache::hops_t::shuffle
void shuffle()
Shuffle each hop list.
Definition: Livecache.h:507
ripple::PeerFinder::Livecache::hops_t::rbegin
reverse_iterator rbegin()
Definition: Livecache.h:316
ripple::PeerFinder::detail::LivecacheBase::Hop::move_back
void move_back(const_iterator pos)
Definition: Livecache.h:152
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:276
std::array< int, 1+Tuning::maxHops+1 >
ripple::PeerFinder::Livecache::hops_t::const_iterator
boost::transform_iterator< Transform< true >, typename lists_type::const_iterator > const_iterator
Definition: Livecache.h:269
ripple::PeerFinder::detail::LivecacheBase::Hop::m_list
std::reference_wrapper< typename beast::maybe_const< IsConst, list_type >::type > m_list
Definition: Livecache.h:170
ripple::default_prng
beast::xor_shift_engine & default_prng()
Return the default random engine.
Definition: ripple/basics/random.h:65
ripple::PeerFinder::Livecache::hops_t::reinsert
void reinsert(Element &e, int hops)
Definition: Livecache.h:551
ripple::PeerFinder::Livecache
The Livecache holds the short-lived relayed Endpoint messages.
Definition: Livecache.h:39
std::copy
T copy(T... args)
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::PeerFinder::Livecache::hops_t::end
const_iterator end() const
Definition: Livecache.h:304
ripple::PeerFinder::Livecache::allocator_type
Allocator allocator_type
Definition: Livecache.h:214
beast::abstract_clock< std::chrono::steady_clock >
std::unary_function
ripple::PeerFinder::detail::LivecacheBase::Hop::crend
reverse_iterator crend() const
Definition: Livecache.h:145
std::array::rend
T rend(T... args)
ripple::PeerFinder::Livecache::hops
class ripple::PeerFinder::Livecache::hops_t hops
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:286
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:847
ripple::PeerFinder::Livecache::hops_t::end
iterator end()
Definition: Livecache.h:298
ripple::PeerFinder::Livecache::hops_t::hops_t
hops_t(Allocator const &alloc)
Definition: Livecache.h:534
ripple::PeerFinder::Livecache::hops_t::cbegin
const_iterator cbegin() const
Definition: Livecache.h:292
ripple::PeerFinder::detail::LivecacheBase::Element::endpoint
Endpoint endpoint
Definition: Livecache.h:55
beast::detail::aged_ordered_container
Associative container where each element is also indexed by time.
Definition: aged_ordered_container.h:82
beast::maybe_const::type
typename std::conditional< IsConst, typename std::remove_const< T >::type const, typename std::remove_const< T >::type >::type type
Definition: maybe_const.h:35
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:160
std::array::begin
T begin(T... args)
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:208
std
STL namespace.
ripple::PeerFinder::Livecache::expire
void expire()
Erase entries whose time has expired.
Definition: Livecache.h:416
ripple::PeerFinder::detail::LivecacheBase::Hop::Transform::operator()
Endpoint const & operator()(Element const &e) const
Definition: Livecache.h:84
ripple::PeerFinder::Livecache::hops_t::cend
const_iterator cend() const
Definition: Livecache.h:310
ripple::PeerFinder::Livecache::empty
bool empty() const
Returns true if the cache is empty.
Definition: Livecache.h:378
std::stringstream::str
T str(T... args)
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
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)
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:277
beast::detail::aged_ordered_container::cbegin
const_iterator cbegin() const
Definition: aged_ordered_container.h:755
ripple::PeerFinder::Endpoint::hops
int hops
Definition: PeerfinderManager.h:120
ripple::PeerFinder::Endpoint
Describes a connectible peer address along with some metadata.
Definition: PeerfinderManager.h:114
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:334
ripple::PeerFinder::Tuning::maxHops
@ maxHops
Definition: peerfinder/impl/Tuning.h:111
ripple::PeerFinder::Endpoint::address
beast::IP::Endpoint address
Definition: PeerfinderManager.h:121
ripple::PeerFinder::detail::LivecacheBase::make_hop
static Hop< IsConst > make_hop(typename beast::maybe_const< IsConst, list_type >::type &list)
Definition: Livecache.h:177
ripple::PeerFinder::detail::LivecacheBase::Hop::crbegin
reverse_iterator crbegin() const
Definition: Livecache.h:133
std::array::rbegin
T rbegin(T... args)
beast::detail::aged_ordered_container::size_type
std::size_t size_type
Definition: aged_ordered_container.h:92
ripple::PeerFinder::Livecache::hops_t::Transform::first_argument
typename lists_type::value_type first_argument
Definition: Livecache.h:248
beast::detail::aged_ordered_container::touch
void touch(beast::detail::aged_container_iterator< is_const, Iterator, Base > pos)
Definition: aged_ordered_container.h:1025
ripple::PeerFinder::Livecache::hops_t::begin
iterator begin()
Definition: Livecache.h:280