blob: 090f1d6d276b7b33900a55d71f74483a44ac25c7 [file] [log] [blame]
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070021#include "ndn-pit-impl.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070022
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070023#include "ns3/ndn-interest-header.h"
24#include "ns3/ndn-content-object-header.h"
25#include "ns3/ndn-forwarding-strategy.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070026
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070027#include "../../utils/empty-policy.h"
28#include "../../utils/persistent-policy.h"
29#include "../../utils/random-policy.h"
30#include "../../utils/lru-policy.h"
31
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070032#include "ns3/log.h"
33#include "ns3/string.h"
34#include "ns3/uinteger.h"
35#include "ns3/simulator.h"
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070036
37#include <boost/lambda/bind.hpp>
38#include <boost/lambda/lambda.hpp>
39
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070040NS_LOG_COMPONENT_DEFINE ("NdnPitImpl");
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070041
42using namespace boost::tuples;
43using namespace boost;
44namespace ll = boost::lambda;
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070045
46#define NS_OBJECT_ENSURE_REGISTERED_TEMPL(type, templ) \
47 static struct X ## type ## templ ## RegistrationClass \
48 { \
49 X ## type ## templ ## RegistrationClass () { \
50 ns3::TypeId tid = type<templ>::GetTypeId (); \
51 tid.GetParent (); \
52 } \
53 } x_ ## type ## templ ## RegistrationVariable
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070054
55namespace ns3 {
56
Alexander Afanasyeve77db792012-08-09 11:10:58 -070057using namespace ndnSIM;
58
59
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070060template<>
61TypeId
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070062NdnPitImpl<persistent_policy_traits>::GetTypeId ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070063{
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070064 static TypeId tid = TypeId ("ns3::NdnPit")
65 .SetGroupName ("Ndn")
66 .SetParent<NdnPit> ()
67 .AddConstructor< NdnPitImpl< persistent_policy_traits > > ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070068 .AddAttribute ("MaxSize",
69 "Set maximum number of entries in PIT. If 0, limit is not enforced",
70 StringValue ("0"),
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070071 MakeUintegerAccessor (&NdnPitImpl< persistent_policy_traits >::GetMaxSize,
72 &NdnPitImpl< persistent_policy_traits >::SetMaxSize),
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070073 MakeUintegerChecker<uint32_t> ())
74 ;
75
Alexander Afanasyev0a0dc392012-07-27 13:41:49 -070076 return tid;
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070077}
78
79template<>
80TypeId
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070081NdnPitImpl<random_policy_traits>::GetTypeId ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070082{
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070083 static TypeId tid = TypeId ("ns3::NdnPitRandom")
84 .SetGroupName ("Ndn")
85 .SetParent<NdnPit> ()
86 .AddConstructor< NdnPitImpl< random_policy_traits > > ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070087 .AddAttribute ("MaxSize",
88 "Set maximum number of entries in PIT. If 0, limit is not enforced",
89 StringValue ("0"),
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070090 MakeUintegerAccessor (&NdnPitImpl< random_policy_traits >::GetMaxSize,
91 &NdnPitImpl< random_policy_traits >::SetMaxSize),
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070092 MakeUintegerChecker<uint32_t> ())
93 ;
94
Alexander Afanasyev0a0dc392012-07-27 13:41:49 -070095 return tid;
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -070096}
97
98template<>
99TypeId
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700100NdnPitImpl<lru_policy_traits>::GetTypeId ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700101{
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700102 static TypeId tid = TypeId ("ns3::NdnPitLru")
103 .SetGroupName ("Ndn")
104 .SetParent<NdnPit> ()
105 .AddConstructor< NdnPitImpl< lru_policy_traits > > ()
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700106 .AddAttribute ("MaxSize",
107 "Set maximum number of entries in PIT. If 0, limit is not enforced",
108 StringValue ("0"),
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700109 MakeUintegerAccessor (&NdnPitImpl< lru_policy_traits >::GetMaxSize,
110 &NdnPitImpl< lru_policy_traits >::SetMaxSize),
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700111 MakeUintegerChecker<uint32_t> ())
112 ;
113
Alexander Afanasyev0a0dc392012-07-27 13:41:49 -0700114 return tid;
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700115}
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700116
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700117template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700118NdnPitImpl<Policy>::NdnPitImpl ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700119{
120}
121
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700122template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700123NdnPitImpl<Policy>::~NdnPitImpl ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700124{
125}
126
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700127template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700128uint32_t
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700129NdnPitImpl<Policy>::GetMaxSize () const
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700130{
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700131 return super::getPolicy ().get_max_size ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700132}
133
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700134template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700135void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700136NdnPitImpl<Policy>::SetMaxSize (uint32_t maxSize)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700137{
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700138 super::getPolicy ().set_max_size (maxSize);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700139}
140
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700141template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700142void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700143NdnPitImpl<Policy>::NotifyNewAggregate ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700144{
145 if (m_fib == 0)
146 {
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700147 m_fib = GetObject<NdnFib> ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700148 }
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700149 if (m_forwardingStrategy == 0)
150 {
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700151 m_forwardingStrategy = GetObject<NdnForwardingStrategy> ();
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700152 }
153
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700154 NdnPit::NotifyNewAggregate ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700155}
156
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700157template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700158void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700159NdnPitImpl<Policy>::DoDispose ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700160{
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700161 super::clear ();
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700162
163 m_forwardingStrategy = 0;
164 m_fib = 0;
165
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700166 NdnPit::DoDispose ();
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700167}
168
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700169template<class Policy>
170void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700171NdnPitImpl<Policy>::RescheduleCleaning ()
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700172{
173 m_cleanEvent.Cancel ();
174 if (i_time.empty ())
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700175 {
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700176 // NS_LOG_DEBUG ("No items in PIT");
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700177 return;
178 }
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700179
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700180 Time nextEvent = i_time.begin ()->GetExpireTime () - Simulator::Now ();
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700181 if (nextEvent <= 0) nextEvent = Seconds (0);
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700182
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700183 // NS_LOG_DEBUG ("Schedule next cleaning in " <<
184 // nextEvent.ToDouble (Time::S) << "s (at " <<
185 // i_time.begin ()->GetExpireTime () << "s abs time");
186
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700187 m_cleanEvent = Simulator::Schedule (nextEvent,
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700188 &NdnPitImpl<Policy>::CleanExpired, this);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700189}
190
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700191template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700192void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700193NdnPitImpl<Policy>::CleanExpired ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700194{
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700195 NS_LOG_LOGIC ("Cleaning PIT. Total: " << i_time.size ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700196 Time now = Simulator::Now ();
197
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700198 // uint32_t count = 0;
199 while (!i_time.empty ())
200 {
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700201 typename time_index::iterator entry = i_time.begin ();
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700202 if (entry->GetExpireTime () <= now) // is the record stale?
203 {
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700204 m_forwardingStrategy->WillErasePendingInterest (entry->to_iterator ()->payload ());
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700205 super::erase (entry->to_iterator ());
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700206 // count ++;
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700207 }
208 else
209 break; // nothing else to do. All later records will not be stale
210 }
211
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700212 if (super::getPolicy ().size ())
213 {
214 NS_LOG_DEBUG ("Size: " << super::getPolicy ().size ());
Alexander Afanasyev6b51b082012-07-27 16:28:34 -0700215 NS_LOG_DEBUG ("i_time size: " << i_time.size ());
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700216 }
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700217 RescheduleCleaning ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700218}
219
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700220template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700221Ptr<NdnPitEntry>
222NdnPitImpl<Policy>::Lookup (const NdnContentObjectHeader &header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700223{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700224 /// @todo use predicate to search with exclude filters
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700225 typename super::iterator item = super::longest_prefix_match (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700226
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700227 if (item == super::end ())
228 return 0;
229 else
230 return item->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700231}
232
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700233template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700234Ptr<NdnPitEntry>
235NdnPitImpl<Policy>::Lookup (const NdnInterestHeader &header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700236{
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700237 // NS_LOG_FUNCTION (header.GetName ());
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700238 NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
Alexander Afanasyevf249a192012-07-18 16:52:51 -0700239 NS_ASSERT_MSG (m_forwardingStrategy != 0, "Forwarding strategy should be set");
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700240
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700241 typename super::iterator foundItem, lastItem;
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700242 bool reachLast;
243 boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700244
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700245 if (!reachLast || lastItem == super::end ())
246 return 0;
247 else
248 return lastItem->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700249}
250
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700251template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700252Ptr<NdnPitEntry>
253NdnPitImpl<Policy>::Create (Ptr<const NdnInterestHeader> header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700254{
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700255 Ptr<NdnFibEntry> fibEntry = m_fib->LongestPrefixMatch (*header);
Alexander Afanasyev3c5b6a72012-07-20 15:35:48 -0700256 if (fibEntry == 0)
257 return 0;
258
259 // NS_ASSERT_MSG (fibEntry != 0,
260 // "There should be at least default route set" <<
261 // " Prefix = "<< header->GetName() << ", NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700262
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700263 Ptr< entry > newEntry = ns3::Create< entry > (boost::ref (*this), header, fibEntry);
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700264 std::pair< typename super::iterator, bool > result = super::insert (header->GetName (), newEntry);
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700265 if (result.first != super::end ())
266 {
267 if (result.second)
268 {
269 newEntry->SetTrie (result.first);
270 return newEntry;
271 }
272 else
273 {
274 // should we do anything?
275 // update payload? add new payload?
276 return result.first->payload ();
277 }
278 }
279 else
280 return 0;
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700281}
282
283
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700284template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700285void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700286NdnPitImpl<Policy>::MarkErased (Ptr<NdnPitEntry> item)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700287{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700288 // entry->SetExpireTime (Simulator::Now () + m_PitEntryPruningTimout);
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700289 super::erase (StaticCast< entry > (item)->to_iterator ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700290}
291
292
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700293template<class Policy>
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700294void
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700295NdnPitImpl<Policy>::Print (std::ostream& os) const
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700296{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700297 // !!! unordered_set imposes "random" order of item in the same level !!!
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700298 typename super::parent_trie::const_recursive_iterator item (super::getTrie ()), end (0);
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700299 for (; item != end; item++)
300 {
301 if (item->payload () == 0) continue;
302
303 os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
304 }
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700305}
306
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700307template<class Policy>
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700308uint32_t
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700309NdnPitImpl<Policy>::GetSize () const
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700310{
311 return super::getPolicy ().size ();
312}
313
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700314template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700315Ptr<NdnPitEntry>
316NdnPitImpl<Policy>::Begin ()
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700317{
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700318 typename super::parent_trie::recursive_iterator item (super::getTrie ()), end (0);
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700319 for (; item != end; item++)
320 {
321 if (item->payload () == 0) continue;
322 break;
323 }
324
325 if (item == end)
326 return End ();
327 else
328 return item->payload ();
329}
330
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700331template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700332Ptr<NdnPitEntry>
333NdnPitImpl<Policy>::End ()
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700334{
335 return 0;
336}
337
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700338template<class Policy>
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700339Ptr<NdnPitEntry>
340NdnPitImpl<Policy>::Next (Ptr<NdnPitEntry> from)
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700341{
342 if (from == 0) return 0;
343
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700344 typename super::parent_trie::recursive_iterator
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700345 item (*StaticCast< entry > (from)->to_iterator ()),
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700346 end (0);
347
348 for (item++; item != end; item++)
349 {
350 if (item->payload () == 0) continue;
351 break;
352 }
353
354 if (item == end)
355 return End ();
356 else
357 return item->payload ();
358}
359
360
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700361// explicit instantiation and registering
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700362template class NdnPitImpl<persistent_policy_traits>;
363template class NdnPitImpl<random_policy_traits>;
364template class NdnPitImpl<lru_policy_traits>;
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700365
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700366NS_OBJECT_ENSURE_REGISTERED_TEMPL(NdnPitImpl, persistent_policy_traits);
367NS_OBJECT_ENSURE_REGISTERED_TEMPL(NdnPitImpl, random_policy_traits);
368NS_OBJECT_ENSURE_REGISTERED_TEMPL(NdnPitImpl, lru_policy_traits);
Alexander Afanasyevbd6f3f42012-07-26 17:50:17 -0700369
370
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700371} // namespace ns3