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-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 "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::dump()
131{
132 NFD_LOG_DEBUG("dump table");
133 for (const Entry& entry : m_table) {
134 NFD_LOG_TRACE(entry.getFullName());
135 }
136}
137
138void
139Cs::setPolicy(unique_ptr<Policy> policy)
140{
141 BOOST_ASSERT(policy != nullptr);
142 BOOST_ASSERT(m_policy != nullptr);
143 size_t limit = m_policy->getLimit();
144 this->setPolicyImpl(std::move(policy));
145 m_policy->setLimit(limit);
146}
147
148void
149Cs::setPolicyImpl(unique_ptr<Policy> policy)
150{
151 NFD_LOG_DEBUG("set-policy " << policy->getName());
152 m_policy = std::move(policy);
153 m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (auto it) { m_table.erase(it); });
154
155 m_policy->setCs(this);
156 BOOST_ASSERT(m_policy->getCs() == this);
157}
158
159void
160Cs::enableAdmit(bool shouldAdmit) noexcept
161{
162 if (m_shouldAdmit == shouldAdmit) {
163 return;
164 }
165 m_shouldAdmit = shouldAdmit;
166 NFD_LOG_INFO((shouldAdmit ? "Enabling" : "Disabling") << " Data admittance");
167}
168
169void
170Cs::enableServe(bool shouldServe) noexcept
171{
172 if (m_shouldServe == shouldServe) {
173 return;
174 }
175 m_shouldServe = shouldServe;
176 NFD_LOG_INFO((shouldServe ? "Enabling" : "Disabling") << " Data serving");
177}
178
179} // 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:160
void setPolicy(unique_ptr< Policy > policy)
Change replacement policy.
Definition cs.cpp:139
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:170
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
#define NFD_LOG_TRACE
Definition logger.hpp:37
static unique_ptr< Policy > makeDefaultPolicy()
Definition cs.cpp:37