36 const size_t DeadNonceList::INITIAL_CAPACITY = (1 << 7);
37 const size_t DeadNonceList::MIN_CAPACITY = (1 << 3);
38 const size_t DeadNonceList::MAX_CAPACITY = (1 << 24);
39 const DeadNonceList::Entry DeadNonceList::MARK = 0;
40 const size_t DeadNonceList::EXPECTED_MARK_COUNT = 5;
41 const double DeadNonceList::CAPACITY_UP = 1.2;
42 const double DeadNonceList::CAPACITY_DOWN = 0.9;
43 const size_t DeadNonceList::EVICT_LIMIT = (1 << 6);
46 : m_lifetime(lifetime)
47 , m_queue(m_index.
get<0>())
48 , m_ht(m_index.
get<1>())
49 , m_capacity(INITIAL_CAPACITY)
50 , m_markInterval(m_lifetime / EXPECTED_MARK_COUNT)
51 , m_adjustCapacityInterval(m_lifetime)
54 BOOST_THROW_EXCEPTION(std::invalid_argument(
"lifetime is less than MIN_LIFETIME"));
57 for (
size_t i = 0; i < EXPECTED_MARK_COUNT; ++i) {
58 m_queue.push_back(MARK);
62 m_adjustCapacityEvent =
scheduler::schedule(m_adjustCapacityInterval, [
this] { adjustCapacity(); });
71 static_assert(INITIAL_CAPACITY >= MIN_CAPACITY,
"INITIAL_CAPACITY is too small");
72 static_assert(INITIAL_CAPACITY <= MAX_CAPACITY,
"INITIAL_CAPACITY is too large");
73 BOOST_ASSERT_MSG(static_cast<size_t>(MIN_CAPACITY * CAPACITY_UP) > MIN_CAPACITY,
74 "CAPACITY_UP must be able to increase from MIN_CAPACITY");
75 BOOST_ASSERT_MSG(static_cast<size_t>(MAX_CAPACITY * CAPACITY_DOWN) < MAX_CAPACITY,
76 "CAPACITY_DOWN must be able to decrease from MAX_CAPACITY");
77 BOOST_ASSERT_MSG(CAPACITY_UP > 1.0,
"CAPACITY_UP must adjust up");
78 BOOST_ASSERT_MSG(CAPACITY_DOWN < 1.0,
"CAPACITY_DOWN must adjust down");
79 static_assert(EVICT_LIMIT >= 1,
"EVICT_LIMIT must be at least 1");
85 return m_queue.size() - this->countMarks();
91 Entry entry = DeadNonceList::makeEntry(
name, nonce);
92 return m_ht.find(entry) != m_ht.end();
98 Entry entry = DeadNonceList::makeEntry(
name, nonce);
99 m_queue.push_back(entry);
101 this->evictEntries();
105 DeadNonceList::makeEntry(
const Name&
name, uint32_t nonce)
109 static_cast<uint64_t>(nonce));
113 DeadNonceList::countMarks()
const 115 return m_ht.count(MARK);
119 DeadNonceList::mark()
121 m_queue.push_back(MARK);
122 size_t nMarks = this->countMarks();
123 m_actualMarkCounts.insert(nMarks);
131 DeadNonceList::adjustCapacity()
133 auto equalRange = m_actualMarkCounts.equal_range(EXPECTED_MARK_COUNT);
134 if (equalRange.second == m_actualMarkCounts.begin()) {
136 m_capacity = std::max(MIN_CAPACITY,
137 static_cast<size_t>(m_capacity * CAPACITY_DOWN));
138 NFD_LOG_TRACE(
"adjustCapacity DOWN capacity=" << m_capacity);
140 else if (equalRange.first == m_actualMarkCounts.end()) {
142 m_capacity = std::min(MAX_CAPACITY,
143 static_cast<size_t>(m_capacity * CAPACITY_UP));
147 m_actualMarkCounts.clear();
148 this->evictEntries();
150 m_adjustCapacityEvent =
scheduler::schedule(m_adjustCapacityInterval, [
this] { adjustCapacity(); });
154 DeadNonceList::evictEntries()
156 ssize_t nOverCapacity = m_queue.size() - m_capacity;
157 if (nOverCapacity <= 0)
160 for (ssize_t nEvict = std::min<ssize_t>(nOverCapacity, EVICT_LIMIT); nEvict > 0; --nEvict) {
161 m_queue.erase(m_queue.begin());
163 BOOST_ASSERT(m_queue.size() >= m_capacity);
represents the Dead Nonce list
static const time::nanoseconds MIN_LIFETIME
minimum entry lifetime
const uint8_t * wire() const
Get pointer to encoded wire.
R & get(variant< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 > &v, nonstd_lite_in_place_type_t(R)=nonstd_lite_in_place_type(R))
Represents a TLV element of NDN packet format.
void add(const Name &name, uint32_t nonce)
records name+nonce
void cancel(EventId eventId)
Cancel a scheduled event.
size_t size() const
Get size of encoded wire, including Type-Length-Value.
Copyright (c) 2011-2015 Regents of the University of California.
static const time::nanoseconds DEFAULT_LIFETIME
default entry lifetime
DeadNonceList(const time::nanoseconds &lifetime=DEFAULT_LIFETIME)
constructs the Dead Nonce List
uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed)
Represents an absolute name.
bool has(const Name &name, uint32_t nonce) const
determines if name+nonce exists
EventId schedule(time::nanoseconds after, const EventCallback &event)
Schedule an event.
#define NFD_LOG_INIT(name)