Loading...
Searching...
No Matches
measurements.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2022, Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "measurements.hpp"
27#include "name-tree.hpp"
28#include "pit-entry.hpp"
29#include "fib-entry.hpp"
30#include "common/global.hpp"
31
32namespace nfd::measurements {
33
35 : m_nameTree(nameTree)
36{
37}
38
39Entry&
41{
42 Entry* entry = nte.getMeasurementsEntry();
43 if (entry != nullptr) {
44 return *entry;
45 }
46
47 nte.setMeasurementsEntry(make_unique<Entry>(nte.getName()));
48 ++m_nItems;
49 entry = nte.getMeasurementsEntry();
50
51 entry->m_expiry = time::steady_clock::now() + getInitialLifetime();
52 entry->m_cleanup = getScheduler().schedule(getInitialLifetime(), [=] { cleanup(*entry); });
53
54 return *entry;
55}
56
57Entry&
58Measurements::get(const Name& name)
59{
60 name_tree::Entry& nte = m_nameTree.lookup(name, std::min(name.size(), getMaxDepth()));
61 return this->get(nte);
62}
63
64Entry&
66{
67 name_tree::Entry& nte = m_nameTree.lookup(fibEntry);
68 return this->get(nte);
69}
70
71Entry&
73{
74 name_tree::Entry& nte = m_nameTree.lookup(pitEntry);
75 return this->get(nte);
76}
77
78Entry*
80{
81 if (child.getName().empty()) { // the root entry
82 return nullptr;
83 }
84
85 name_tree::Entry* nteChild = m_nameTree.getEntry(child);
86 name_tree::Entry* nte = nteChild->getParent();
87 BOOST_ASSERT(nte != nullptr);
88 return &this->get(*nte);
89}
90
91template<typename K>
92Entry*
93Measurements::findLongestPrefixMatchImpl(const K& key, const EntryPredicate& pred) const
94{
95 name_tree::Entry* match = m_nameTree.findLongestPrefixMatch(key,
96 [&pred] (const name_tree::Entry& nte) {
97 const Entry* entry = nte.getMeasurementsEntry();
98 return entry != nullptr && pred(*entry);
99 });
100 if (match != nullptr) {
101 return match->getMeasurementsEntry();
102 }
103 return nullptr;
104}
105
106Entry*
107Measurements::findLongestPrefixMatch(const Name& name, const EntryPredicate& pred) const
108{
109 return this->findLongestPrefixMatchImpl(name.getPrefix(NameTree::getMaxDepth()), pred);
110}
111
112Entry*
114{
115 return this->findLongestPrefixMatch(pitEntry.getName(), pred);
116}
117
118Entry*
119Measurements::findExactMatch(const Name& name) const
120{
121 const name_tree::Entry* nte = m_nameTree.findExactMatch(name);
122 return nte == nullptr ? nullptr : nte->getMeasurementsEntry();
123}
124
125void
126Measurements::extendLifetime(Entry& entry, const time::nanoseconds& lifetime)
127{
128 BOOST_ASSERT(m_nameTree.getEntry(entry) != nullptr);
129
130 auto expiry = time::steady_clock::now() + lifetime;
131 if (entry.m_expiry >= expiry) {
132 // has longer lifetime, not extending
133 return;
134 }
135
136 entry.m_cleanup.cancel();
137 entry.m_expiry = expiry;
138 entry.m_cleanup = getScheduler().schedule(lifetime, [&] { cleanup(entry); });
139}
140
141void
142Measurements::cleanup(Entry& entry)
143{
144 name_tree::Entry* nte = m_nameTree.getEntry(entry);
145 BOOST_ASSERT(nte != nullptr);
146
147 nte->setMeasurementsEntry(nullptr);
148 m_nameTree.eraseIfEmpty(nte);
149 --m_nItems;
150}
151
152} // namespace nfd::measurements
Represents an entry in the FIB.
Definition fib-entry.hpp:91
Represents an entry in the Measurements table.
const Name & getName() const noexcept
static constexpr size_t getMaxDepth()
Maximum depth of a Measurements entry.
Measurements(NameTree &nameTree)
void extendLifetime(Entry &entry, const time::nanoseconds &lifetime)
Extend lifetime of an entry.
Entry * getParent(const Entry &child)
Find or insert a parent entry.
Entry & get(const Name &name)
Find or insert an entry by name.
Entry * findExactMatch(const Name &name) const
Perform an exact match.
static time::nanoseconds getInitialLifetime()
Entry * findLongestPrefixMatch(const Name &name, const EntryPredicate &pred=AnyEntry()) const
Perform a longest prefix match for name.
An entry in the name tree.
void setMeasurementsEntry(unique_ptr< measurements::Entry > measurementsEntry)
const Name & getName() const noexcept
measurements::Entry * getMeasurementsEntry() const
Entry * getParent() const noexcept
A common index structure for FIB, PIT, StrategyChoice, and Measurements.
Definition name-tree.hpp:37
size_t eraseIfEmpty(Entry *entry, bool canEraseAncestors=true)
Delete the entry if it is empty.
static constexpr size_t getMaxDepth()
Maximum depth of the name tree.
Definition name-tree.hpp:51
Entry & lookup(const Name &name, size_t prefixLen)
Find or insert an entry by name.
Definition name-tree.cpp:43
Entry * getEntry(const EntryT &tableEntry) const
Definition name-tree.hpp:77
Entry * findExactMatch(const Name &name, size_t prefixLen=std::numeric_limits< size_t >::max()) const
Exact match lookup.
Entry * findLongestPrefixMatch(const Name &name, const EntrySelector &entrySelector=AnyEntry()) const
Longest prefix matching.
Represents an entry in the Interest table (PIT).
const Name & getName() const
std::function< bool(const Entry &)> EntryPredicate
A predicate that accepts or rejects an entry.
ndn::Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
Definition global.cpp:45