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 
32 namespace nfd::cs {
33 
34 NFD_LOG_INIT(ContentStore);
35 
36 static unique_ptr<Policy>
38 {
39  return Policy::create("lru");
40 }
41 
42 Cs::Cs(size_t nMaxPackets)
43 {
44  setPolicyImpl(makeDefaultPolicy());
45  m_policy->setLimit(nMaxPackets);
46 }
47 
48 void
49 Cs::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 
82 std::pair<Cs::const_iterator, Cs::const_iterator>
83 Cs::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 
93 size_t
94 Cs::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 
109 Cs::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 
129 void
130 Cs::dump()
131 {
132  NFD_LOG_DEBUG("dump table");
133  for (const Entry& entry : m_table) {
134  NFD_LOG_TRACE(entry.getFullName());
135  }
136 }
137 
138 void
139 Cs::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 
148 void
149 Cs::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 
159 void
160 Cs::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 
169 void
170 Cs::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:36
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