NFD: Named Data Networking Forwarding Daemon 24.07-28-gdcc0e6e0
Loading...
Searching...
No Matches
cs.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014-2025, 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 "cs.hpp"
27#include "common/logger.hpp"
28
29#include <ndn-cxx/lp/tags.hpp>
30#include <ndn-cxx/util/concepts.hpp>
31
32namespace nfd::cs {
33
34NFD_LOG_INIT(ContentStore);
35
36static unique_ptr<Policy>
38{
39 return Policy::create("lru");
40}
41
42Cs::Cs(size_t nMaxPackets)
43{
44 setPolicyImpl(makeDefaultPolicy());
45 m_policy->setLimit(nMaxPackets);
46}
47
48void
49Cs::insert(const Data& data, bool isUnsolicited)
50{
51 if (!m_shouldAdmit || m_policy->getLimit() == 0) {
52 return;
53 }
54 NFD_LOG_DEBUG("insert " << data.getName());
55
56 // recognize CachePolicy
57 auto tag = data.getTag<lp::CachePolicyTag>();
58 if (tag != nullptr) {
59 lp::CachePolicyType policy = tag->get().getPolicy();
60 if (policy == lp::CachePolicyType::NO_CACHE) {
61 return;
62 }
63 }
64
65 auto [it, isNewEntry] = m_table.emplace(data.shared_from_this(), isUnsolicited);
66 auto& entry = const_cast<Entry&>(*it);
67
68 entry.updateFreshUntil();
69
70 if (!isNewEntry) { // existing entry
71 // XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
72 if (entry.isUnsolicited() && !isUnsolicited) {
73 entry.clearUnsolicited();
74 }
75 m_policy->afterRefresh(it);
76 }
77 else {
78 m_policy->afterInsert(it);
79 }
80}
81
82std::pair<Cs::const_iterator, Cs::const_iterator>
83Cs::findPrefixRange(const Name& prefix) const
84{
85 auto first = m_table.lower_bound(prefix);
86 auto last = m_table.end();
87 if (!prefix.empty()) {
88 last = m_table.lower_bound(prefix.getSuccessor());
89 }
90 return {first, last};
91}
92
93size_t
94Cs::eraseImpl(const Name& prefix, size_t limit)
95{
96 const_iterator i, last;
97 std::tie(i, last) = findPrefixRange(prefix);
98
99 size_t nErased = 0;
100 while (i != last && nErased < limit) {
101 m_policy->beforeErase(i);
102 i = m_table.erase(i);
103 ++nErased;
104 }
105 return nErased;
106}
107
109Cs::findImpl(const Interest& interest) const
110{
111 if (!m_shouldServe || m_policy->getLimit() == 0) {
112 return m_table.end();
113 }
114
115 const Name& prefix = interest.getName();
116 auto range = findPrefixRange(prefix);
117 auto match = std::find_if(range.first, range.second,
118 [&interest] (const auto& entry) { return entry.canSatisfy(interest); });
119
120 if (match == range.second) {
121 NFD_LOG_DEBUG("find " << prefix << " no-match");
122 return m_table.end();
123 }
124 NFD_LOG_DEBUG("find " << prefix << " matching " << match->getName());
125 m_policy->beforeUse(match);
126 return match;
127}
128
129void
130Cs::setPolicy(unique_ptr<Policy> policy)
131{
132 BOOST_ASSERT(policy != nullptr);
133 BOOST_ASSERT(m_policy != nullptr);
134 size_t limit = m_policy->getLimit();
135 this->setPolicyImpl(std::move(policy));
136 m_policy->setLimit(limit);
137}
138
139void
140Cs::setPolicyImpl(unique_ptr<Policy> policy)
141{
142 NFD_LOG_DEBUG("set-policy " << policy->getName());
143 m_policy = std::move(policy);
144 m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (auto it) { m_table.erase(it); });
145
146 m_policy->setCs(this);
147 BOOST_ASSERT(m_policy->getCs() == this);
148}
149
150void
151Cs::enableAdmit(bool shouldAdmit) noexcept
152{
153 if (m_shouldAdmit == shouldAdmit) {
154 return;
155 }
156 m_shouldAdmit = shouldAdmit;
157 NFD_LOG_INFO((shouldAdmit ? "Enabling" : "Disabling") << " Data admittance");
158}
159
160void
161Cs::enableServe(bool shouldServe) noexcept
162{
163 if (m_shouldServe == shouldServe) {
164 return;
165 }
166 m_shouldServe = shouldServe;
167 NFD_LOG_INFO((shouldServe ? "Enabling" : "Disabling") << " Data serving");
168}
169
170} // namespace nfd::cs
Table::const_iterator const_iterator
Definition cs.hpp:161
void enableAdmit(bool shouldAdmit) noexcept
Set CS_ENABLE_ADMIT flag.
Definition cs.cpp:151
void setPolicy(unique_ptr< Policy > policy)
Change replacement policy.
Definition cs.cpp:130
Cs(size_t nMaxPackets=10)
Definition cs.cpp:42
void insert(const Data &data, bool isUnsolicited=false)
Inserts a Data packet.
Definition cs.cpp:49
void enableServe(bool shouldServe) noexcept
Set CS_ENABLE_SERVE flag.
Definition cs.cpp:161
A ContentStore entry.
Definition cs-entry.hpp:38
void updateFreshUntil()
Recalculate when the entry would become non-fresh, relative to current time.
Definition cs-entry.cpp:44
static unique_ptr< Policy > create(const std::string &policyName)
Returns a cs::Policy identified by policyName, or nullptr if policyName is unknown.
Definition cs-policy.cpp:45
#define NFD_LOG_INFO
Definition logger.hpp:39
#define NFD_LOG_INIT(name)
Definition logger.hpp:31
#define NFD_LOG_DEBUG
Definition logger.hpp:38
static unique_ptr< Policy > makeDefaultPolicy()
Definition cs.cpp:37