NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: 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"
28 #include "core/logger.hpp"
29 #include "core/algorithm.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  return make_unique<PriorityFifoPolicy>();
51 }
52 
53 Cs::Cs(size_t nMaxPackets, unique_ptr<Policy> policy)
54 {
55  this->setPolicyImpl(policy);
56  m_policy->setLimit(nMaxPackets);
57 }
58 
59 void
60 Cs::setLimit(size_t nMaxPackets)
61 {
62  m_policy->setLimit(nMaxPackets);
63 }
64 
65 size_t
66 Cs::getLimit() const
67 {
68  return m_policy->getLimit();
69 }
70 
71 void
72 Cs::setPolicy(unique_ptr<Policy> policy)
73 {
74  BOOST_ASSERT(policy != nullptr);
75  BOOST_ASSERT(m_policy != nullptr);
76  size_t limit = m_policy->getLimit();
77  this->setPolicyImpl(policy);
78  m_policy->setLimit(limit);
79 }
80 
81 void
82 Cs::insert(const Data& data, bool isUnsolicited)
83 {
84  NFD_LOG_DEBUG("insert " << data.getName());
85 
86  if (m_policy->getLimit() == 0) {
87  // shortcut for disabled CS
88  return;
89  }
90 
91  // recognize CachePolicy
92  shared_ptr<lp::CachePolicyTag> tag = data.getTag<lp::CachePolicyTag>();
93  if (tag != nullptr) {
94  lp::CachePolicyType policy = tag->get().getPolicy();
95  if (policy == lp::CachePolicyType::NO_CACHE) {
96  return;
97  }
98  }
99 
100  bool isNewEntry = false;
101  iterator it;
102  // use .insert because gcc46 does not support .emplace
103  std::tie(it, isNewEntry) = m_table.insert(EntryImpl(data.shared_from_this(), isUnsolicited));
104  EntryImpl& entry = const_cast<EntryImpl&>(*it);
105 
106  entry.updateStaleTime();
107 
108  if (!isNewEntry) { // existing entry
109  // XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
110  if (entry.isUnsolicited() && !isUnsolicited) {
111  entry.unsetUnsolicited();
112  }
113 
114  m_policy->afterRefresh(it);
115  }
116  else {
117  m_policy->afterInsert(it);
118  }
119 }
120 
121 void
122 Cs::find(const Interest& interest,
123  const HitCallback& hitCallback,
124  const MissCallback& missCallback) const
125 {
126  BOOST_ASSERT(static_cast<bool>(hitCallback));
127  BOOST_ASSERT(static_cast<bool>(missCallback));
128 
129  const Name& prefix = interest.getName();
130  bool isRightmost = interest.getChildSelector() == 1;
131  NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
132 
133  iterator first = m_table.lower_bound(prefix);
134  iterator last = m_table.end();
135  if (prefix.size() > 0) {
136  last = m_table.lower_bound(prefix.getSuccessor());
137  }
138 
139  iterator match = last;
140  if (isRightmost) {
141  match = this->findRightmost(interest, first, last);
142  }
143  else {
144  match = this->findLeftmost(interest, first, last);
145  }
146 
147  if (match == last) {
148  NFD_LOG_DEBUG(" no-match");
149  missCallback(interest);
150  return;
151  }
152  NFD_LOG_DEBUG(" matching " << match->getName());
153  m_policy->beforeUse(match);
154  hitCallback(interest, match->getData());
155 }
156 
157 iterator
158 Cs::findLeftmost(const Interest& interest, iterator first, iterator last) const
159 {
160  return std::find_if(first, last, bind(&cs::EntryImpl::canSatisfy, _1, interest));
161 }
162 
163 iterator
164 Cs::findRightmost(const Interest& interest, iterator first, iterator last) const
165 {
166  // Each loop visits a sub-namespace under a prefix one component longer than Interest Name.
167  // If there is a match in that sub-namespace, the leftmost match is returned;
168  // otherwise, loop continues.
169 
170  size_t interestNameLength = interest.getName().size();
171  for (iterator right = last; right != first;) {
172  iterator prev = std::prev(right);
173 
174  // special case: [first,prev] have exact Names
175  if (prev->getName().size() == interestNameLength) {
176  NFD_LOG_TRACE(" find-among-exact " << prev->getName());
177  iterator matchExact = this->findRightmostAmongExact(interest, first, right);
178  return matchExact == right ? last : matchExact;
179  }
180 
181  Name prefix = prev->getName().getPrefix(interestNameLength + 1);
182  iterator left = m_table.lower_bound(prefix);
183 
184  // normal case: [left,right) are under one-component-longer prefix
185  NFD_LOG_TRACE(" find-under-prefix " << prefix);
186  iterator match = this->findLeftmost(interest, left, right);
187  if (match != right) {
188  return match;
189  }
190  right = left;
191  }
192  return last;
193 }
194 
195 iterator
196 Cs::findRightmostAmongExact(const Interest& interest, iterator first, iterator last) const
197 {
198  return find_last_if(first, last, bind(&EntryImpl::canSatisfy, _1, interest));
199 }
200 
201 void
202 Cs::setPolicyImpl(unique_ptr<Policy>& policy)
203 {
204  m_policy = std::move(policy);
205  m_beforeEvictConnection = m_policy->beforeEvict.connect([this] (iterator it) {
206  m_table.erase(it);
207  });
208 
209  m_policy->setCs(this);
210  BOOST_ASSERT(m_policy->getCs() == this);
211 }
212 
213 void
214 Cs::dump()
215 {
216  NFD_LOG_DEBUG("dump table");
217  for (const EntryImpl& entry : m_table) {
218  NFD_LOG_TRACE(entry.getFullName());
219  }
220 }
221 
222 } // namespace cs
223 } // namespace nfd
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
Definition: name.hpp:249
shared_ptr< T > getTag() const
get a tag item
Definition: tag-host.hpp:67
#define NFD_LOG_DEBUG(expression)
Definition: logger.hpp:55
int getChildSelector() const
Definition: interest.hpp:398
bool isUnsolicited() const
Definition: cs-entry.hpp:73
Cs(size_t nMaxPackets=10, unique_ptr< Policy > policy=makeDefaultPolicy())
Definition: cs.cpp:53
Copyright (c) 2014-2016, Regents of the University of California, Arizona Board of Regents...
size_t getLimit() const
Definition: cs.cpp:66
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:360
Name getSuccessor() const
Get the successor of a name.
Definition: name.cpp:293
It find_last_if(It first, It last, Pred p)
Definition: algorithm.hpp:49
represents an Interest packet
Definition: interest.hpp:45
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
void insert(const Data &data, bool isUnsolicited=false)
inserts a Data packet
Definition: cs.cpp:82
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:72
void setLimit(size_t nMaxPackets)
changes capacity (in number of packets)
Definition: cs.cpp:60
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:122
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:408
void updateStaleTime()
refreshes stale time relative to current time
Definition: cs-entry.cpp:48
#define NFD_LOG_INIT(name)
Definition: logger.hpp:34
#define NFD_LOG_TRACE(expression)
Definition: logger.hpp:54
const T & get() const
Definition: tag.hpp:86
represents a Data packet
Definition: data.hpp:39
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:218