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 
32 namespace nfd::measurements {
33 
35  : m_nameTree(nameTree)
36 {
37 }
38 
39 Entry&
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 
57 Entry&
58 Measurements::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 
64 Entry&
65 Measurements::get(const fib::Entry& fibEntry)
66 {
67  name_tree::Entry& nte = m_nameTree.lookup(fibEntry);
68  return this->get(nte);
69 }
70 
71 Entry&
72 Measurements::get(const pit::Entry& pitEntry)
73 {
74  name_tree::Entry& nte = m_nameTree.lookup(pitEntry);
75  return this->get(nte);
76 }
77 
78 Entry*
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 
91 template<typename K>
92 Entry*
93 Measurements::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 
106 Entry*
107 Measurements::findLongestPrefixMatch(const Name& name, const EntryPredicate& pred) const
108 {
109  return this->findLongestPrefixMatchImpl(name.getPrefix(NameTree::getMaxDepth()), pred);
110 }
111 
112 Entry*
114 {
115  return this->findLongestPrefixMatch(pitEntry.getName(), pred);
116 }
117 
118 Entry*
119 Measurements::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 
125 void
126 Measurements::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 
141 void
142 Measurements::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:54
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)
measurements::Entry * getMeasurementsEntry() const
Entry * getParent() const noexcept
const Name & getName() 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.
Definition: name-tree.cpp:122
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.
Definition: name-tree.cpp:149
Entry * findLongestPrefixMatch(const Name &name, const EntrySelector &entrySelector=AnyEntry()) const
Longest prefix matching.
Definition: name-tree.cpp:161
Represents an entry in the Interest table (PIT).
Definition: pit-entry.hpp:62
const Name & getName() const
Definition: pit-entry.hpp:81
std::function< bool(const Entry &)> EntryPredicate
A predicate that accepts or rejects an entry.
Scheduler & getScheduler()
Returns the global Scheduler instance for the calling thread.
Definition: global.cpp:45