blob: 5765120b12d8bf000e6c932b3b01fd2f06e97d95 [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -07004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -07007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070019
20#ifndef NDN_CONTENT_STORE_IMPL_H_
21#define NDN_CONTENT_STORE_IMPL_H_
22
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -070023#include "ns3/ndnSIM/model/ndn-common.hpp"
24
Alexander Afanasyev0c395372014-12-20 15:54:02 -080025#include "ndn-content-store.hpp"
26
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070027#include "ns3/packet.h"
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070028#include <boost/foreach.hpp>
29
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -080030#include "ns3/log.h"
31#include "ns3/uinteger.h"
32#include "ns3/string.h"
33
Alexander Afanasyev0c395372014-12-20 15:54:02 -080034#include "../../utils/trie/trie-with-policy.hpp"
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070035
36namespace ns3 {
37namespace ndn {
38namespace cs {
39
Alexander Afanasyev79206512013-07-27 16:49:12 -070040/**
41 * @ingroup ndn-cs
42 * @brief Cache entry implementation with additional references to the base container
43 */
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070044template<class CS>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045class EntryImpl : public Entry {
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070046public:
Alexander Afanasyev8566f452012-12-10 15:21:51 -080047 typedef Entry base_type;
Alexander Afanasyev25093a32013-02-01 13:00:13 -080048
Alexander Afanasyev8566f452012-12-10 15:21:51 -080049public:
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -070050 EntryImpl(Ptr<ContentStore> cs, shared_ptr<const Data> data)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080051 : Entry(cs, data)
52 , item_(0)
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070053 {
54 }
55
56 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 SetTrie(typename CS::super::iterator item)
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070058 {
59 item_ = item;
60 }
61
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080062 typename CS::super::iterator
63 to_iterator()
64 {
65 return item_;
66 }
67 typename CS::super::const_iterator
68 to_iterator() const
69 {
70 return item_;
71 }
Alexander Afanasyev25093a32013-02-01 13:00:13 -080072
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070073private:
74 typename CS::super::iterator item_;
75};
76
Alexander Afanasyev79206512013-07-27 16:49:12 -070077/**
78 * @ingroup ndn-cs
79 * @brief Base implementation of NDN content store
80 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070081template<class Policy>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082class ContentStoreImpl
83 : public ContentStore,
84 protected ndnSIM::
85 trie_with_policy<Name,
86 ndnSIM::smart_pointer_payload_traits<EntryImpl<ContentStoreImpl<Policy>>,
87 Entry>,
88 Policy> {
Alexander Afanasyev29c19b92012-09-03 23:46:41 -070089public:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080090 typedef ndnSIM::
91 trie_with_policy<Name, ndnSIM::smart_pointer_payload_traits<EntryImpl<ContentStoreImpl<Policy>>,
92 Entry>,
93 Policy> super;
Alexander Afanasyev25093a32013-02-01 13:00:13 -080094
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095 typedef EntryImpl<ContentStoreImpl<Policy>> entry;
Alexander Afanasyev25093a32013-02-01 13:00:13 -080096
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070097 static TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098 GetTypeId();
Alexander Afanasyev25093a32013-02-01 13:00:13 -080099
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800100 ContentStoreImpl(){};
101 virtual ~ContentStoreImpl(){};
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800102
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700103 // from ContentStore
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800104
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700105 virtual inline shared_ptr<Data>
106 Lookup(shared_ptr<const Interest> interest);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800107
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700108 virtual inline bool
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700109 Add(shared_ptr<const Data> data);
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700110
111 // virtual bool
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700112 // Remove (shared_ptr<Interest> header);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800113
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700114 virtual inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 Print(std::ostream& os) const;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700116
Alexander Afanasyev29c19b92012-09-03 23:46:41 -0700117 virtual uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800118 GetSize() const;
Alexander Afanasyev29c19b92012-09-03 23:46:41 -0700119
120 virtual Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800121 Begin();
Alexander Afanasyev29c19b92012-09-03 23:46:41 -0700122
123 virtual Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124 End();
Alexander Afanasyev29c19b92012-09-03 23:46:41 -0700125
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 virtual Ptr<Entry> Next(Ptr<Entry>);
Alexander Afanasyev29c19b92012-09-03 23:46:41 -0700127
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 const typename super::policy_container&
129 GetPolicy() const
130 {
131 return super::getPolicy();
132 }
Alexander Afanasyevf21bfc12013-11-17 11:58:33 -0800133
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800134 typename super::policy_container&
135 GetPolicy()
136 {
137 return super::getPolicy();
138 }
139
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700140public:
141 typedef void (*CsEntryCallback)(Ptr<const Entry>);
142
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700143private:
144 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145 SetMaxSize(uint32_t maxSize);
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700146
147 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148 GetMaxSize() const;
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800149
150private:
151 static LogComponent g_log; ///< @brief Logging variable
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800152
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800153 /// @brief trace of for entry additions (fired every time entry is successfully added to the
154 /// cache): first parameter is pointer to the CS entry
155 TracedCallback<Ptr<const Entry>> m_didAddEntry;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700156};
157
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800158//////////////////////////////////////////
159////////// Implementation ////////////////
160//////////////////////////////////////////
161
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800162template<class Policy>
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700163LogComponent ContentStoreImpl<Policy>::g_log = LogComponent(("ndn.cs." + Policy::GetName()).c_str(), __FILE__);
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800164
165template<class Policy>
166TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800167ContentStoreImpl<Policy>::GetTypeId()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800168{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800169 static TypeId tid =
170 TypeId(("ns3::ndn::cs::" + Policy::GetName()).c_str())
171 .SetGroupName("Ndn")
172 .SetParent<ContentStore>()
173 .AddConstructor<ContentStoreImpl<Policy>>()
174 .AddAttribute("MaxSize",
175 "Set maximum number of entries in ContentStore. If 0, limit is not enforced",
176 StringValue("100"), MakeUintegerAccessor(&ContentStoreImpl<Policy>::GetMaxSize,
177 &ContentStoreImpl<Policy>::SetMaxSize),
178 MakeUintegerChecker<uint32_t>())
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800179
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800180 .AddTraceSource("DidAddEntry",
181 "Trace fired every time entry is successfully added to the cache",
Alexander Afanasyevd6453cd2015-08-20 21:45:36 -0700182 MakeTraceSourceAccessor(&ContentStoreImpl<Policy>::m_didAddEntry),
183 "ns3::ndn::cs::ContentStoreImpl::CsEntryCallback");
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800184
185 return tid;
186}
187
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800188struct isNotExcluded {
189 inline isNotExcluded(const Exclude& exclude)
190 : m_exclude(exclude)
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700191 {
192 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800193
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700194 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800195 operator()(const name::Component& comp) const
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700196 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197 return !m_exclude.isExcluded(comp);
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700198 }
199
200private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 const Exclude& m_exclude;
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700202};
203
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800204template<class Policy>
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700205shared_ptr<Data>
206ContentStoreImpl<Policy>::Lookup(shared_ptr<const Interest> interest)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800207{
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800208 NS_LOG_FUNCTION(this << interest->getName());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800209
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700210 typename super::const_iterator node;
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800211 if (interest->getExclude().empty()) {
212 node = this->deepest_prefix_match(interest->getName());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800213 }
214 else {
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800215 node = this->deepest_prefix_match_if_next_level(interest->getName(),
216 isNotExcluded(interest->getExclude()));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800217 }
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800218
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219 if (node != this->end()) {
220 this->m_cacheHitsTrace(interest, node->payload()->GetData());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800221
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700222 shared_ptr<Data> copy = make_shared<Data>(*node->payload()->GetData());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800223 return copy;
224 }
225 else {
226 this->m_cacheMissesTrace(interest);
227 return 0;
228 }
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800229}
230
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800231template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800232bool
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700233ContentStoreImpl<Policy>::Add(shared_ptr<const Data> data)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800234{
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800235 NS_LOG_FUNCTION(this << data->getName());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800236
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800237 Ptr<entry> newEntry = Create<entry>(this, data);
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800238 std::pair<typename super::iterator, bool> result = super::insert(data->getName(), newEntry);
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800239
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800240 if (result.first != super::end()) {
241 if (result.second) {
242 newEntry->SetTrie(result.first);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800243
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800244 m_didAddEntry(newEntry);
245 return true;
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800246 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800247 else {
248 // should we do anything?
249 // update payload? add new payload?
250 return false;
251 }
252 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800253 else
254 return false; // cannot insert entry
255}
256
257template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800258void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800259ContentStoreImpl<Policy>::Print(std::ostream& os) const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800260{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261 for (typename super::policy_container::const_iterator item = this->getPolicy().begin();
262 item != this->getPolicy().end(); item++) {
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800263 os << item->payload ()->GetName () << std::endl;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800264 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800265}
266
267template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800268void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800269ContentStoreImpl<Policy>::SetMaxSize(uint32_t maxSize)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800270{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800271 this->getPolicy().set_max_size(maxSize);
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800272}
273
274template<class Policy>
275uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800276ContentStoreImpl<Policy>::GetMaxSize() const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800277{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800278 return this->getPolicy().get_max_size();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800279}
280
281template<class Policy>
282uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800283ContentStoreImpl<Policy>::GetSize() const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800284{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800285 return this->getPolicy().size();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800286}
287
288template<class Policy>
289Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800290ContentStoreImpl<Policy>::Begin()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800291{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800292 typename super::parent_trie::recursive_iterator item(super::getTrie()), end(0);
293 for (; item != end; item++) {
294 if (item->payload() == 0)
295 continue;
296 break;
297 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800298
299 if (item == end)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800300 return End();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800301 else
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800302 return item->payload();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800303}
304
305template<class Policy>
306Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800307ContentStoreImpl<Policy>::End()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800308{
309 return 0;
310}
311
312template<class Policy>
313Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800314ContentStoreImpl<Policy>::Next(Ptr<Entry> from)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800315{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800316 if (from == 0)
317 return 0;
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800318
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800319 typename super::parent_trie::recursive_iterator item(*StaticCast<entry>(from)->to_iterator()),
320 end(0);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800321
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800322 for (item++; item != end; item++) {
323 if (item->payload() == 0)
324 continue;
325 break;
326 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800327
328 if (item == end)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800329 return End();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800330 else
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800331 return item->payload();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800332}
333
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700334} // namespace cs
335} // namespace ndn
336} // namespace ns3
337
338#endif // NDN_CONTENT_STORE_IMPL_H_