NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
cs.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "cs.hpp"
27 #include "core/logger.hpp"
28 #include "core/algorithm.hpp"
29 #include <ndn-cxx/lp/tags.hpp>
30 
31 NFD_LOG_INIT("ContentStore");
32 
33 namespace nfd {
34 namespace cs {
35 
36 // http://en.cppreference.com/w/cpp/concept/ForwardIterator
37 BOOST_CONCEPT_ASSERT((boost::ForwardIterator<Cs::const_iterator>));
38 // boost::ForwardIterator follows SGI standard http://www.sgi.com/tech/stl/ForwardIterator.html,
39 // which doesn't require DefaultConstructible
40 #ifdef HAVE_IS_DEFAULT_CONSTRUCTIBLE
41 static_assert(std::is_default_constructible<Cs::const_iterator>::value,
42  "Cs::const_iterator must be default-constructible");
43 #else
44 BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Cs::const_iterator>));
45 #endif // HAVE_IS_DEFAULT_CONSTRUCTIBLE
46 
47 unique_ptr<Policy>
49 {
50  const std::string DEFAULT_POLICY = "priority_fifo";
51  return Policy::create(DEFAULT_POLICY);
52 }
53 
54 Cs::Cs(size_t nMaxPackets, unique_ptr<Policy> policy)
55 {
56  this->setPolicyImpl(std::move(policy));
57  m_policy->setLimit(nMaxPackets);
58 }
59 
60 void
61 Cs::setLimit(size_t nMaxPackets)
62 {
63  m_policy->setLimit(nMaxPackets);
64 }
65 
66 size_t
67 Cs::getLimit() const
68 {
69  return m_policy->getLimit();
70 }
71 
72 void
73 Cs::setPolicy(unique_ptr<Policy> policy)
74 {
75  BOOST_ASSERT(policy != nullptr);
76  BOOST_ASSERT(m_policy != nullptr);
77  size_t limit = m_policy->getLimit();
78  this->setPolicyImpl(std::move(policy));
79  m_policy->setLimit(limit);
80 }
81 
82 void
83 Cs::insert(const Data& data, bool isUnsolicited)
84 {
85  NFD_LOG_DEBUG("insert " << data.getName());
86 
87  if (m_policy->getLimit() == 0) {
88  // shortcut for disabled CS
89  return;
90  }
91 
92  // recognize CachePolicy
93  shared_ptr<lp::CachePolicyTag> tag = data.getTag<lp::CachePolicyTag>();
94  if (tag != nullptr) {
95  lp::CachePolicyType policy = tag->get().getPolicy();
96  if (policy == lp::CachePolicyType::NO_CACHE) {
97  return;
98  }
99  }
100 
101  bool isNewEntry = false;
102  iterator it;
103  // use .insert because gcc46 does not support .emplace
104  std::tie(it, isNewEntry) = m_table.insert(EntryImpl(data.shared_from_this(), isUnsolicited));
105  EntryImpl& entry = const_cast<EntryImpl&>(*it);
106 
107  entry.updateStaleTime();
108 
109  if (!isNewEntry) { // existing entry
110  // XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
111  if (entry.isUnsolicited() && !isUnsolicited) {
112  entry.unsetUnsolicited();
113  }
114 
115  m_policy->afterRefresh(it);
116  }
117  else {
118  m_policy->afterInsert(it);
119  }
120 }
121 
122 void
123 Cs::find(const Interest& interest,
124  const HitCallback& hitCallback,
125  const MissCallback& missCallback) const
126 {
127  BOOST_ASSERT(static_cast<bool>(hitCallback));
128  BOOST_ASSERT(static_cast<bool>(missCallback));
129 
130  const Name& prefix = interest.getName();
131  bool isRightmost = interest.getChildSelector() == 1;
132  NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
133 
134  iterator first = m_table.lower_bound(prefix);
135  iterator last = m_table.end();
136  if (prefix.size() > 0) {
137  last = m_table.lower_bound(prefix.getSuccessor());
138  }
139 
140  iterator match = last;
141  if (isRightmost) {
142  match = this->findRightmost(interest, first, last);
143  }
144  else {
145  match = this->findLeftmost(interest, first, last);
146  }
147 
148  if (match == last) {
149  NFD_LOG_DEBUG(" no-match");
150  missCallback(interest);
151  return;
152  }
153  NFD_LOG_DEBUG(" matching " << match->getName());
154  m_policy->beforeUse(match);
155  hitCallback(interest, match->getData());
156 }
157 
158 iterator
159 Cs::findLeftmost(const Interest& interest, iterator first, iterator last) const
160 {
161  return std::find_if(first, last, bind(&cs::EntryImpl::canSatisfy, _1, interest));
162 }
163 
164 iterator
165 Cs::findRightmost(const Interest& interest, iterator first, iterator last) const
166 {
167  // Each loop visits a sub-namespace under a prefix one component longer than Interest Name.
168  // If there is a match in that sub-namespace, the leftmost match is returned;
169  // otherwise, loop continues.
170 
171  size_t interestNameLength = interest.getName().size();
172  for (iterator right = last; right != first;) {
173  iterator prev = std::prev(right);
174 
175  // special case: [first,prev] have exact Names
176  if (prev->getName().size() == interestNameLength) {
177  NFD_LOG_TRACE(" find-among-exact " << prev->getName());
178  iterator matchExact = this->findRightmostAmongExact(interest, first, right);
179  return matchExact == right ? last : matchExact;
180  }
181 
182  Name prefix = prev->getName().getPrefix(interestNameLength + 1);
183  iterator left = m_table.lower_bound(prefix);
184 
185  // normal case: [left,right) are under one-component-longer prefix
186  NFD_LOG_TRACE(" find-under-prefix " << prefix);
187  iterator match = this->findLeftmost(interest, left, right);
188  if (match != right) {
189  return match;
190  }
191  right = left;
192  }
193  return last;
194 }
195 
196 iterator
197 Cs::findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const
198 {
199  return find_last_if(first, last, bind(&EntryImpl::canSatisfy, _1, interest));
200 }
201 
202 void
203 Cs::setPolicyImpl(unique_ptr<Policy> policy)
204 {
205  NFD_LOG_DEBUG("set-policy " << policy->getName());
206  m_policy = std::move(policy);
207  m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (iterator it) {
208  m_table.erase(it);
209  });
210 
211  m_policy->setCs(this);
212  BOOST_ASSERT(m_policy->getCs() == this);
213 }
214 
215 void
216 Cs::dump()
217 {
218  NFD_LOG_DEBUG("dump table");
219  for (const EntryImpl& entry : m_table) {
220  NFD_LOG_TRACE(entry.getFullName());
221  }
222 }
223 
224 } // namespace cs
225 } // namespace nfd
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
Definition: name.hpp:241
shared_ptr< T > getTag() const
get a tag item
Definition: tag-host.hpp:67
int getChildSelector() const
Definition: interest.hpp:356
bool isUnsolicited() const
Definition: cs-entry.hpp:73
Cs(size_t nMaxPackets=10, unique_ptr< Policy > policy=makeDefaultPolicy())
Definition: cs.cpp:54
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
size_t getLimit() const
Definition: cs.cpp:67
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:318
Name getSuccessor() const
Get the successor of a name.
Definition: name.cpp:281
It find_last_if(It first, It last, Pred p)
Definition: algorithm.hpp:49
represents an Interest packet
Definition: interest.hpp:42
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:55
an Entry in ContentStore implementation
provides a tag type for simple types
Definition: tag.hpp:58
Table::const_iterator iterator
Definition: cs-internal.hpp:41
#define NFD_LOG_TRACE(expression)
Definition: logger.hpp:54
void insert(const Data &data, bool isUnsolicited=false)
inserts a Data packet
Definition: cs.cpp:83
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
unique_ptr< Policy > makeDefaultPolicy()
Definition: cs.cpp:48
void setPolicy(unique_ptr< Policy > policy)
changes cs replacement policy
Definition: cs.cpp:73
void setLimit(size_t nMaxPackets)
changes capacity (in number of packets)
Definition: cs.cpp:61
static unique_ptr< Policy > create(const std::string &key)
Definition: cs-policy.cpp:43
CachePolicyType
indicates the cache policy applied to a Data packet
Name abstraction to represent an absolute name.
Definition: name.hpp:46
void find(const Interest &interest, const HitCallback &hitCallback, const MissCallback &missCallback) const
finds the best matching Data packet
Definition: cs.cpp:123
std::function< void(const Interest &, const Data &data)> HitCallback
Definition: cs.hpp:76
std::function< void(const Interest &)> MissCallback
Definition: cs.hpp:77
size_t size() const
Get the number of components.
Definition: name.hpp:400
void updateStaleTime()
refreshes stale time relative to current time
Definition: cs-entry.cpp:48
const T & get() const
Definition: tag.hpp:86
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
represents a Data packet
Definition: data.hpp:37
bool canSatisfy(const Interest &interest) const
determines whether Interest can be satisified by the stored Data
Definition: cs-entry.cpp:60
const Name & getName() const
Definition: interest.hpp:215