blob: 9c55053a964d1ef345454a141ded9e9c9e1387f3 [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 Afanasyev2b4c9472012-08-09 15:00:38 -0700140private:
141 void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 SetMaxSize(uint32_t maxSize);
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700143
144 uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800145 GetMaxSize() const;
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800146
147private:
148 static LogComponent g_log; ///< @brief Logging variable
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800149
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150 /// @brief trace of for entry additions (fired every time entry is successfully added to the
151 /// cache): first parameter is pointer to the CS entry
152 TracedCallback<Ptr<const Entry>> m_didAddEntry;
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700153};
154
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800155//////////////////////////////////////////
156////////// Implementation ////////////////
157//////////////////////////////////////////
158
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800159template<class Policy>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160LogComponent
161 ContentStoreImpl<Policy>::g_log = LogComponent(("ndn.cs." + Policy::GetName()).c_str());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800162
163template<class Policy>
164TypeId
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800165ContentStoreImpl<Policy>::GetTypeId()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800166{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800167 static TypeId tid =
168 TypeId(("ns3::ndn::cs::" + Policy::GetName()).c_str())
169 .SetGroupName("Ndn")
170 .SetParent<ContentStore>()
171 .AddConstructor<ContentStoreImpl<Policy>>()
172 .AddAttribute("MaxSize",
173 "Set maximum number of entries in ContentStore. If 0, limit is not enforced",
174 StringValue("100"), MakeUintegerAccessor(&ContentStoreImpl<Policy>::GetMaxSize,
175 &ContentStoreImpl<Policy>::SetMaxSize),
176 MakeUintegerChecker<uint32_t>())
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800177
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800178 .AddTraceSource("DidAddEntry",
179 "Trace fired every time entry is successfully added to the cache",
180 MakeTraceSourceAccessor(&ContentStoreImpl<Policy>::m_didAddEntry));
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800181
182 return tid;
183}
184
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800185struct isNotExcluded {
186 inline isNotExcluded(const Exclude& exclude)
187 : m_exclude(exclude)
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700188 {
189 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800190
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700191 bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800192 operator()(const name::Component& comp) const
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700193 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800194 return !m_exclude.isExcluded(comp);
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700195 }
196
197private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800198 const Exclude& m_exclude;
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700199};
200
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800201template<class Policy>
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700202shared_ptr<Data>
203ContentStoreImpl<Policy>::Lookup(shared_ptr<const Interest> interest)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800204{
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800205 NS_LOG_FUNCTION(this << interest->getName());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800206
Alexander Afanasyeveec89ba2013-07-19 16:34:30 -0700207 typename super::const_iterator node;
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800208 if (interest->getExclude().empty()) {
209 node = this->deepest_prefix_match(interest->getName());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800210 }
211 else {
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800212 node = this->deepest_prefix_match_if_next_level(interest->getName(),
213 isNotExcluded(interest->getExclude()));
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 }
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800215
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800216 if (node != this->end()) {
217 this->m_cacheHitsTrace(interest, node->payload()->GetData());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800218
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700219 shared_ptr<Data> copy = make_shared<Data>(*node->payload()->GetData());
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800220 return copy;
221 }
222 else {
223 this->m_cacheMissesTrace(interest);
224 return 0;
225 }
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800226}
227
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800228template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800229bool
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -0700230ContentStoreImpl<Policy>::Add(shared_ptr<const Data> data)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800231{
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800232 NS_LOG_FUNCTION(this << data->getName());
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800233
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800234 Ptr<entry> newEntry = Create<entry>(this, data);
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800235 std::pair<typename super::iterator, bool> result = super::insert(data->getName(), newEntry);
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800236
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800237 if (result.first != super::end()) {
238 if (result.second) {
239 newEntry->SetTrie(result.first);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800240
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800241 m_didAddEntry(newEntry);
242 return true;
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800243 }
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800244 else {
245 // should we do anything?
246 // update payload? add new payload?
247 return false;
248 }
249 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800250 else
251 return false; // cannot insert entry
252}
253
254template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800255void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800256ContentStoreImpl<Policy>::Print(std::ostream& os) const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800257{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800258 for (typename super::policy_container::const_iterator item = this->getPolicy().begin();
259 item != this->getPolicy().end(); item++) {
Spyridon Mastorakis1f1cd5e2014-12-04 11:12:40 -0800260 os << item->payload ()->GetName () << std::endl;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800261 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800262}
263
264template<class Policy>
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800265void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800266ContentStoreImpl<Policy>::SetMaxSize(uint32_t maxSize)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800267{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800268 this->getPolicy().set_max_size(maxSize);
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800269}
270
271template<class Policy>
272uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800273ContentStoreImpl<Policy>::GetMaxSize() const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800274{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800275 return this->getPolicy().get_max_size();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800276}
277
278template<class Policy>
279uint32_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800280ContentStoreImpl<Policy>::GetSize() const
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800281{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800282 return this->getPolicy().size();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800283}
284
285template<class Policy>
286Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800287ContentStoreImpl<Policy>::Begin()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800288{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800289 typename super::parent_trie::recursive_iterator item(super::getTrie()), end(0);
290 for (; item != end; item++) {
291 if (item->payload() == 0)
292 continue;
293 break;
294 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800295
296 if (item == end)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800297 return End();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800298 else
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800299 return item->payload();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800300}
301
302template<class Policy>
303Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800304ContentStoreImpl<Policy>::End()
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800305{
306 return 0;
307}
308
309template<class Policy>
310Ptr<Entry>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800311ContentStoreImpl<Policy>::Next(Ptr<Entry> from)
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800312{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800313 if (from == 0)
314 return 0;
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800315
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800316 typename super::parent_trie::recursive_iterator item(*StaticCast<entry>(from)->to_iterator()),
317 end(0);
Alexander Afanasyev25093a32013-02-01 13:00:13 -0800318
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800319 for (item++; item != end; item++) {
320 if (item->payload() == 0)
321 continue;
322 break;
323 }
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800324
325 if (item == end)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800326 return End();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800327 else
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800328 return item->payload();
Alexander Afanasyev991a0cc2012-12-10 11:38:19 -0800329}
330
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700331} // namespace cs
332} // namespace ndn
333} // namespace ns3
334
335#endif // NDN_CONTENT_STORE_IMPL_H_