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