blob: 5e353a9341dac70fee4b2be068c7ff88fb93d7e3 [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"
22#include "ns3/log.h"
23#include "ns3/string.h"
24#include "ns3/uinteger.h"
25#include "ns3/simulator.h"
26#include "ccnx-interest-header.h"
27#include "ccnx-content-object-header.h"
28
29#include <boost/lambda/bind.hpp>
30#include <boost/lambda/lambda.hpp>
31
32NS_LOG_COMPONENT_DEFINE ("CcnxPitImpl");
33
34using namespace boost::tuples;
35using namespace boost;
36namespace ll = boost::lambda;
37
38namespace ns3 {
39
40NS_OBJECT_ENSURE_REGISTERED (CcnxPitImpl);
41
42TypeId
43CcnxPitImpl::GetTypeId ()
44{
45 static TypeId tid = TypeId ("ns3::CcnxPit")
46 .SetGroupName ("Ccnx")
47 .SetParent<CcnxPit> ()
48 .AddConstructor<CcnxPitImpl> ()
49 .AddAttribute ("MaxSize",
50 "Set maximum number of entries in PIT. If 0, limit is not enforced",
51 StringValue ("0"),
52 MakeUintegerAccessor (&CcnxPitImpl::GetMaxSize, &CcnxPitImpl::SetMaxSize),
53 MakeUintegerChecker<uint32_t> ())
54 ;
55
56 return tid;
57}
58
59CcnxPitImpl::CcnxPitImpl ()
60{
61}
62
63CcnxPitImpl::~CcnxPitImpl ()
64{
65}
66
67uint32_t
68CcnxPitImpl::GetMaxSize () const
69{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070070 return getPolicy ().get_max_size ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070071}
72
73void
74CcnxPitImpl::SetMaxSize (uint32_t maxSize)
75{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070076 getPolicy ().set_max_size (maxSize);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070077}
78
79void
80CcnxPitImpl::NotifyNewAggregate ()
81{
82 if (m_fib == 0)
83 {
84 m_fib = GetObject<CcnxFib> ();
85 }
86}
87
88void
89CcnxPitImpl::DoDispose ()
90{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070091 clear ();
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070092}
93
94void
95CcnxPitImpl::DoCleanExpired ()
96{
97 // NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
98 Time now = Simulator::Now ();
99
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700100 NS_LOG_ERROR ("Need to be repaired");
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700101 // // uint32_t count = 0;
102 // while (!empty ())
103 // {
104 // CcnxPit::index<i_timestamp>::type::iterator entry = get<i_timestamp> ().begin ();
105 // if (entry->GetExpireTime () <= now) // is the record stale?
106 // {
107 // get<i_timestamp> ().erase (entry);
108 // // count ++;
109 // }
110 // else
111 // break; // nothing else to do. All later records will not be stale
112 // }
113}
114
115Ptr<CcnxPitEntry>
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700116CcnxPitImpl::Lookup (const CcnxContentObjectHeader &header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700117{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700118 /// @todo use predicate to search with exclude filters
119 super::iterator item = super::longest_prefix_match (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700120
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700121 if (item == super::end ())
122 return 0;
123 else
124 return item->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700125}
126
127Ptr<CcnxPitEntry>
128CcnxPitImpl::Lookup (const CcnxInterestHeader &header)
129{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700130 NS_LOG_FUNCTION (header.GetName ());
131 NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700132
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700133 super::iterator foundItem, lastItem;
134 bool reachLast;
135 boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (header.GetName ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700136
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700137 if (!reachLast || lastItem == super::end ())
138 return 0;
139 else
140 return lastItem->payload (); // which could also be 0
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700141}
142
143Ptr<CcnxPitEntry>
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700144CcnxPitImpl::Create (Ptr<const CcnxInterestHeader> header)
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700145{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700146 Ptr<CcnxFibEntry> fibEntry = m_fib->LongestPrefixMatch (*header);
147 NS_ASSERT_MSG (fibEntry != 0,
148 "There should be at least default route set" <<
149 " Prefix = "<< header->GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700150
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700151
152 Ptr<CcnxPitEntryImpl> newEntry = ns3::Create<CcnxPitEntryImpl> (header, fibEntry);
153 std::pair< super::iterator, bool > result = super::insert (header->GetName (), newEntry);
154 if (result.first != super::end ())
155 {
156 if (result.second)
157 {
158 newEntry->SetTrie (result.first);
159 return newEntry;
160 }
161 else
162 {
163 // should we do anything?
164 // update payload? add new payload?
165 return result.first->payload ();
166 }
167 }
168 else
169 return 0;
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700170}
171
172
173void
174CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> entry)
175{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700176 // entry->SetExpireTime (Simulator::Now () + m_PitEntryPruningTimout);
177 super::erase (StaticCast<CcnxPitEntryImpl> (entry)->to_iterator ());
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700178}
179
180
181void
182CcnxPitImpl::Print (std::ostream& os) const
183{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700184 // !!! unordered_set imposes "random" order of item in the same level !!!
185 super::parent_trie::const_recursive_iterator item (super::getTrie ()), end (0);
186 for (; item != end; item++)
187 {
188 if (item->payload () == 0) continue;
189
190 os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
191 }
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700192}
193
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700194Ptr<CcnxPitEntry>
195CcnxPitImpl::Begin ()
196{
197 super::parent_trie::recursive_iterator item (super::getTrie ()), end (0);
198 for (; item != end; item++)
199 {
200 if (item->payload () == 0) continue;
201 break;
202 }
203
204 if (item == end)
205 return End ();
206 else
207 return item->payload ();
208}
209
210Ptr<CcnxPitEntry>
211CcnxPitImpl::End ()
212{
213 return 0;
214}
215
216Ptr<CcnxPitEntry>
217CcnxPitImpl::Next (Ptr<CcnxPitEntry> from)
218{
219 if (from == 0) return 0;
220
221 super::parent_trie::recursive_iterator
222 item (*StaticCast<CcnxPitEntryImpl> (from)->to_iterator ()),
223 end (0);
224
225 for (item++; item != end; item++)
226 {
227 if (item->payload () == 0) continue;
228 break;
229 }
230
231 if (item == end)
232 return End ();
233 else
234 return item->payload ();
235}
236
237
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700238} // namespace ns3