blob: c1867f054b1b0a9970594a91db8dccb682bbdee5 [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
21#include "ccnx-pit-impl.h"
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070022
23#include "ns3/ccnx-interest-header.h"
24#include "ns3/ccnx-content-object-header.h"
25
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070026#include "ns3/log.h"
27#include "ns3/string.h"
28#include "ns3/uinteger.h"
29#include "ns3/simulator.h"
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070030
31#include <boost/lambda/bind.hpp>
32#include <boost/lambda/lambda.hpp>
33
34NS_LOG_COMPONENT_DEFINE ("CcnxPitImpl");
35
36using namespace boost::tuples;
37using namespace boost;
38namespace ll = boost::lambda;
39
40namespace ns3 {
41
42NS_OBJECT_ENSURE_REGISTERED (CcnxPitImpl);
43
Alexander Afanasyev36b45772012-07-10 16:57:42 -070044
45// CcnxPitEntryImpl::CcnxPitEntryImpl (CcnxPit &pit,
46// Ptr<const CcnxInterestHeader> header,
47// Ptr<CcnxFibEntry> fibEntry)
48// : CcnxPitEntry (pit, header, fibEntry)
49// , item_ (0)
50// {
51// static_cast<CcnxPitImpl&> (m_container).i_time.insert (*this);
52// }
53
54// CcnxPitEntryImpl::~CcnxPitEntryImpl ()
55// {
56// static_cast<CcnxPitImpl&> (m_container).i_time.erase (*this);
57// }
58
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070059TypeId
60CcnxPitImpl::GetTypeId ()
61{
62 static TypeId tid = TypeId ("ns3::CcnxPit")
63 .SetGroupName ("Ccnx")
64 .SetParent<CcnxPit> ()
65 .AddConstructor<CcnxPitImpl> ()
66 .AddAttribute ("MaxSize",
67 "Set maximum number of entries in PIT. If 0, limit is not enforced",
68 StringValue ("0"),
69 MakeUintegerAccessor (&CcnxPitImpl::GetMaxSize, &CcnxPitImpl::SetMaxSize),
70 MakeUintegerChecker<uint32_t> ())
71 ;
72
73 return tid;
74}
75
76CcnxPitImpl::CcnxPitImpl ()
77{
78}
79
80CcnxPitImpl::~CcnxPitImpl ()
81{
82}
83
84uint32_t
85CcnxPitImpl::GetMaxSize () const
86{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070087 return getPolicy ().get_max_size ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070088}
89
90void
91CcnxPitImpl::SetMaxSize (uint32_t maxSize)
92{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070093 getPolicy ().set_max_size (maxSize);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070094}
95
96void
97CcnxPitImpl::NotifyNewAggregate ()
98{
99 if (m_fib == 0)
100 {
101 m_fib = GetObject<CcnxFib> ();
102 }
103}
104
105void
106CcnxPitImpl::DoDispose ()
107{
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700108 super::clear ();
109}
110
111void CcnxPitImpl::RescheduleCleaning ()
112{
113 m_cleanEvent.Cancel ();
114 if (i_time.empty ())
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700115 {
116 NS_LOG_DEBUG ("No items in PIT");
117 return;
118 }
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700119
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700120 Time nextEvent = i_time.begin ()->GetExpireTime () - Simulator::Now ();
121 if (nextEvent < 0) nextEvent = Seconds (0);
122
123 NS_LOG_DEBUG ("Schedule next cleaning in " <<
124 nextEvent.ToDouble (Time::S) << "s (at " <<
125 i_time.begin ()->GetExpireTime () << "s abs time");
126 m_cleanEvent = Simulator::Schedule (nextEvent,
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700127 &CcnxPitImpl::CleanExpired, this);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700128}
129
130void
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700131CcnxPitImpl::CleanExpired ()
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700132{
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700133 NS_LOG_LOGIC ("Cleaning PIT. Total: " << i_time.size ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700134 Time now = Simulator::Now ();
135
Alexander Afanasyev413c7f12012-07-10 17:35:16 -0700136 // uint32_t count = 0;
137 while (!i_time.empty ())
138 {
139 time_index::iterator entry = i_time.begin ();
140 if (entry->GetExpireTime () <= now) // is the record stale?
141 {
142 super::erase (entry->to_iterator ());
143 // // count ++;
144 }
145 else
146 break; // nothing else to do. All later records will not be stale
147 }
148
149 RescheduleCleaning ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700150}
151
152Ptr<CcnxPitEntry>
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700153CcnxPitImpl::Lookup (const CcnxContentObjectHeader &header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700154{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700155 /// @todo use predicate to search with exclude filters
156 super::iterator item = super::longest_prefix_match (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700157
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700158 if (item == super::end ())
159 return 0;
160 else
161 return item->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700162}
163
164Ptr<CcnxPitEntry>
165CcnxPitImpl::Lookup (const CcnxInterestHeader &header)
166{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700167 NS_LOG_FUNCTION (header.GetName ());
168 NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700169
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700170 super::iterator foundItem, lastItem;
171 bool reachLast;
172 boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700173
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700174 if (!reachLast || lastItem == super::end ())
175 return 0;
176 else
177 return lastItem->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700178}
179
180Ptr<CcnxPitEntry>
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700181CcnxPitImpl::Create (Ptr<const CcnxInterestHeader> header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700182{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700183 Ptr<CcnxFibEntry> fibEntry = m_fib->LongestPrefixMatch (*header);
184 NS_ASSERT_MSG (fibEntry != 0,
185 "There should be at least default route set" <<
186 " Prefix = "<< header->GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700187
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700188
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700189 Ptr< entry > newEntry = ns3::Create< entry > (boost::ref (*this), header, fibEntry);
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700190 std::pair< super::iterator, bool > result = super::insert (header->GetName (), newEntry);
191 if (result.first != super::end ())
192 {
193 if (result.second)
194 {
195 newEntry->SetTrie (result.first);
196 return newEntry;
197 }
198 else
199 {
200 // should we do anything?
201 // update payload? add new payload?
202 return result.first->payload ();
203 }
204 }
205 else
206 return 0;
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700207}
208
209
210void
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700211CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> item)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700212{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700213 // entry->SetExpireTime (Simulator::Now () + m_PitEntryPruningTimout);
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700214 super::erase (StaticCast< entry > (item)->to_iterator ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700215}
216
217
218void
219CcnxPitImpl::Print (std::ostream& os) const
220{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700221 // !!! unordered_set imposes "random" order of item in the same level !!!
222 super::parent_trie::const_recursive_iterator item (super::getTrie ()), end (0);
223 for (; item != end; item++)
224 {
225 if (item->payload () == 0) continue;
226
227 os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
228 }
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700229}
230
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700231uint32_t
232CcnxPitImpl::GetSize () const
233{
234 return super::getPolicy ().size ();
235}
236
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700237Ptr<CcnxPitEntry>
238CcnxPitImpl::Begin ()
239{
240 super::parent_trie::recursive_iterator item (super::getTrie ()), end (0);
241 for (; item != end; item++)
242 {
243 if (item->payload () == 0) continue;
244 break;
245 }
246
247 if (item == end)
248 return End ();
249 else
250 return item->payload ();
251}
252
253Ptr<CcnxPitEntry>
254CcnxPitImpl::End ()
255{
256 return 0;
257}
258
259Ptr<CcnxPitEntry>
260CcnxPitImpl::Next (Ptr<CcnxPitEntry> from)
261{
262 if (from == 0) return 0;
263
264 super::parent_trie::recursive_iterator
Alexander Afanasyev36b45772012-07-10 16:57:42 -0700265 item (*StaticCast< entry > (from)->to_iterator ()),
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700266 end (0);
267
268 for (item++; item != end; item++)
269 {
270 if (item->payload () == 0) continue;
271 break;
272 }
273
274 if (item == end)
275 return End ();
276 else
277 return item->payload ();
278}
279
280
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700281} // namespace ns3