37 const size_t DeadNonceList::INITIAL_CAPACITY;
38 const size_t DeadNonceList::MIN_CAPACITY;
39 const size_t DeadNonceList::MAX_CAPACITY;
40 const DeadNonceList::Entry DeadNonceList::MARK;
41 const size_t DeadNonceList::EXPECTED_MARK_COUNT;
42 const double DeadNonceList::CAPACITY_UP;
43 const double DeadNonceList::CAPACITY_DOWN;
44 const size_t DeadNonceList::EVICT_LIMIT;
47 : m_lifetime(lifetime)
48 , m_capacity(INITIAL_CAPACITY)
49 , m_markInterval(m_lifetime / EXPECTED_MARK_COUNT)
50 , m_adjustCapacityInterval(m_lifetime)
53 NDN_THROW(std::invalid_argument(
"lifetime is less than MIN_LIFETIME"));
56 for (
size_t i = 0; i < EXPECTED_MARK_COUNT; ++i) {
57 m_queue.push_back(MARK);
60 m_markEvent =
getScheduler().schedule(m_markInterval, [
this] { mark(); });
61 m_adjustCapacityEvent =
getScheduler().schedule(m_adjustCapacityInterval, [
this] { adjustCapacity(); });
64 static_assert(INITIAL_CAPACITY >= MIN_CAPACITY,
"INITIAL_CAPACITY is too small");
65 static_assert(INITIAL_CAPACITY <= MAX_CAPACITY,
"INITIAL_CAPACITY is too large");
66 BOOST_ASSERT_MSG(static_cast<size_t>(MIN_CAPACITY * CAPACITY_UP) > MIN_CAPACITY,
67 "CAPACITY_UP must be able to increase from MIN_CAPACITY");
68 BOOST_ASSERT_MSG(static_cast<size_t>(MAX_CAPACITY * CAPACITY_DOWN) < MAX_CAPACITY,
69 "CAPACITY_DOWN must be able to decrease from MAX_CAPACITY");
70 BOOST_ASSERT_MSG(CAPACITY_UP > 1.0,
"CAPACITY_UP must adjust up");
71 BOOST_ASSERT_MSG(CAPACITY_DOWN < 1.0,
"CAPACITY_DOWN must adjust down");
72 static_assert(EVICT_LIMIT >= 1,
"EVICT_LIMIT must be at least 1");
78 return m_queue.size() - countMarks();
84 Entry entry = DeadNonceList::makeEntry(name, nonce);
85 return m_ht.find(entry) != m_ht.end();
91 Entry entry = DeadNonceList::makeEntry(name, nonce);
92 const auto iter = m_ht.find(entry);
93 bool isDuplicate = iter != m_ht.end();
95 NFD_LOG_TRACE(
"adding " << (isDuplicate ?
"duplicate " :
"") << name <<
" nonce=" << nonce);
98 m_queue.relocate(m_queue.end(), m_index.project<
Queue>(iter));
101 m_queue.push_back(entry);
111 std::memcpy(&n, nonce.data(),
sizeof(n));
112 return CityHash64WithSeed(reinterpret_cast<const char*>(nameWire.wire()), nameWire.size(), n);
116 DeadNonceList::countMarks()
const 118 return m_ht.count(MARK);
122 DeadNonceList::mark()
124 m_queue.push_back(MARK);
125 size_t nMarks = countMarks();
126 m_actualMarkCounts.insert(nMarks);
130 m_markEvent =
getScheduler().schedule(m_markInterval, [
this] { mark(); });
134 DeadNonceList::adjustCapacity()
136 auto oldCapacity = m_capacity;
137 auto equalRange = m_actualMarkCounts.equal_range(EXPECTED_MARK_COUNT);
138 if (equalRange.second == m_actualMarkCounts.begin()) {
140 m_capacity = std::max(MIN_CAPACITY, static_cast<size_t>(m_capacity * CAPACITY_DOWN));
142 else if (equalRange.first == m_actualMarkCounts.end()) {
144 m_capacity = std::min(MAX_CAPACITY, static_cast<size_t>(m_capacity * CAPACITY_UP));
147 if (m_capacity != oldCapacity) {
148 NFD_LOG_TRACE(
"adjusting capacity " << oldCapacity <<
" -> " << m_capacity);
151 m_actualMarkCounts.clear();
154 m_adjustCapacityEvent =
getScheduler().schedule(m_adjustCapacityInterval, [
this] { adjustCapacity(); });
158 DeadNonceList::evictEntries()
160 if (m_queue.size() <= m_capacity)
163 auto nEvict = std::min(m_queue.size() - m_capacity, EVICT_LIMIT);
164 for (
size_t i = 0; i < nEvict; i++) {
167 BOOST_ASSERT(m_queue.size() >= m_capacity);
169 NFD_LOG_TRACE(
"evicted=" << nEvict <<
" size=" <<
size() <<
" capacity=" << m_capacity);
Represents the Dead Nonce List.
#define NFD_LOG_INIT(name)
static constexpr time::nanoseconds MIN_LIFETIME
Minimum entry lifetime.
DeadNonceList(time::nanoseconds lifetime=DEFAULT_LIFETIME)
Constructs the Dead Nonce List.
void add(const Name &name, Interest::Nonce nonce)
Adds name+nonce to the list.
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
Copyright (c) 2011-2015 Regents of the University of California.
static constexpr time::nanoseconds DEFAULT_LIFETIME
Default entry lifetime.
bool has(const Name &name, Interest::Nonce nonce) const
Determines if name+nonce is in the list.
uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed)
Represents an absolute name.
boost::multi_index_container< Policy::EntryRef, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::ordered_unique< boost::multi_index::identity< Policy::EntryRef > > > > Queue
size_t size() const
Returns the number of stored nonces.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
boost::chrono::nanoseconds nanoseconds