blob: 90f0cd88c136e396cf3412b216a25cdeae74a42b [file] [log] [blame]
Alexander Afanasyev78057c32012-07-06 15:18:46 -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-fib-impl.h"
22
Alexander Afanasyeve3d126f2012-07-16 17:07:31 -070023#include "ns3/ccnx.h"
24#include "ns3/ccnx-face.h"
25#include "ns3/ccnx-interest-header.h"
Alexander Afanasyev78057c32012-07-06 15:18:46 -070026
27#include "ns3/node.h"
28#include "ns3/assert.h"
29#include "ns3/names.h"
30#include "ns3/log.h"
31
32#include <boost/ref.hpp>
33#include <boost/lambda/lambda.hpp>
34#include <boost/lambda/bind.hpp>
35namespace ll = boost::lambda;
36
37NS_LOG_COMPONENT_DEFINE ("CcnxFibImpl");
38
39namespace ns3 {
40
41NS_OBJECT_ENSURE_REGISTERED (CcnxFibImpl);
42
43TypeId
44CcnxFibImpl::GetTypeId (void)
45{
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070046 static TypeId tid = TypeId ("ns3::CcnxFib") // cheating ns3 object system
Alexander Afanasyev95a4fa32012-07-09 15:23:59 -070047 .SetParent<CcnxFib> ()
Alexander Afanasyev78057c32012-07-06 15:18:46 -070048 .SetGroupName ("Ccnx")
49 .AddConstructor<CcnxFibImpl> ()
50 ;
51 return tid;
52}
53
54CcnxFibImpl::CcnxFibImpl ()
55{
56}
57
58void
59CcnxFibImpl::NotifyNewAggregate ()
60{
61 Object::NotifyNewAggregate ();
62}
63
64void
65CcnxFibImpl::DoDispose (void)
66{
67 clear ();
68 Object::DoDispose ();
69}
70
71
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070072Ptr<CcnxFibEntry>
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070073CcnxFibImpl::LongestPrefixMatch (const CcnxInterestHeader &interest)
Alexander Afanasyev78057c32012-07-06 15:18:46 -070074{
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070075 super::iterator item = super::longest_prefix_match (interest.GetName ());
Alexander Afanasyev78057c32012-07-06 15:18:46 -070076 // @todo use predicate to search with exclude filters
77
78 if (item == super::end ())
79 return 0;
80 else
81 return item->payload ();
82}
83
84
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070085Ptr<CcnxFibEntry>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070086CcnxFibImpl::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
87{
88 return Add (Create<CcnxNameComponents> (prefix), face, metric);
89}
90
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -070091Ptr<CcnxFibEntry>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070092CcnxFibImpl::Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric)
93{
Alexander Afanasyev1ba09b82012-07-09 09:16:14 -070094 NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix) << boost::cref(*face) << metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -070095
96 // will add entry if doesn't exists, or just return an iterator to the existing entry
Alexander Afanasyev30f60e32012-07-10 14:21:16 -070097 std::pair< super::iterator, bool > result = super::insert (*prefix, 0);
98 if (result.first != super::end ())
99 {
100 if (result.second)
101 {
102 Ptr<CcnxFibEntryImpl> newEntry = Create<CcnxFibEntryImpl> (prefix);
103 newEntry->SetTrie (result.first);
104 result.first->set_payload (newEntry);
105 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700106
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700107 super::modify (result.first,
108 ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700109
Alexander Afanasyev30f60e32012-07-10 14:21:16 -0700110 return result.first->payload ();
111 }
112 else
113 return 0;
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700114}
115
116void
117CcnxFibImpl::Remove (const Ptr<const CcnxNameComponents> &prefix)
118{
119 NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
120
121 super::erase (*prefix);
122}
123
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700124// void
125// CcnxFibImpl::Invalidate (const Ptr<const CcnxNameComponents> &prefix)
126// {
127// NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700128
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700129// super::iterator foundItem, lastItem;
130// bool reachLast;
131// boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (*prefix);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700132
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700133// if (!reachLast || lastItem->payload () == 0)
134// return; // nothing to invalidate
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700135
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700136// super::modify (lastItem,
137// ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
138// }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700139
140void
141CcnxFibImpl::InvalidateAll ()
142{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700143 NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId ());
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700144
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700145 super::parent_trie::recursive_iterator item (super::getTrie ());
146 super::parent_trie::recursive_iterator end (0);
147 for (; item != end; item++)
148 {
149 if (item->payload () == 0) continue;
150
151 super::modify (&(*item),
152 ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
153 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700154}
155
156void
Alexander Afanasyevb310a9a2012-07-20 15:29:56 -0700157CcnxFibImpl::RemoveFace (super::parent_trie &item, Ptr<CcnxFace> face)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700158{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700159 if (item.payload () == 0) return;
160 NS_LOG_FUNCTION (this);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700161
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700162 super::modify (&item,
163 ll::bind (&CcnxFibEntry::RemoveFace, ll::_1, face));
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700164}
165
166void
167CcnxFibImpl::RemoveFromAll (Ptr<CcnxFace> face)
168{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700169 NS_LOG_FUNCTION (this);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700170
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700171 std::for_each (super::parent_trie::recursive_iterator (super::getTrie ()),
172 super::parent_trie::recursive_iterator (0),
Alexander Afanasyevb310a9a2012-07-20 15:29:56 -0700173 ll::bind (&CcnxFibImpl::RemoveFace,
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700174 this, ll::_1, face));
175
176 super::parent_trie::recursive_iterator trieNode (super::getTrie ());
177 super::parent_trie::recursive_iterator end (0);
178 for (; trieNode != end; trieNode++)
179 {
180 if (trieNode->payload () == 0) continue;
181
182 if (trieNode->payload ()->m_faces.size () == 0)
183 {
184 trieNode = super::parent_trie::recursive_iterator (trieNode->erase ());
185 }
186 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700187}
188
189void
190CcnxFibImpl::Print (std::ostream &os) const
191{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700192 // !!! unordered_set imposes "random" order of item in the same level !!!
193 super::parent_trie::const_recursive_iterator item (super::getTrie ());
194 super::parent_trie::const_recursive_iterator end (0);
195 for (; item != end; item++)
196 {
197 if (item->payload () == 0) continue;
198
199 os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
200 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700201}
202
Alexander Afanasyevf1e013f2012-07-11 17:59:40 -0700203uint32_t
204CcnxFibImpl::GetSize () const
205{
206 return super::getPolicy ().size ();
207}
208
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700209Ptr<const CcnxFibEntry>
Alexander Afanasyev95a4fa32012-07-09 15:23:59 -0700210CcnxFibImpl::Begin ()
211{
212 super::parent_trie::const_recursive_iterator item (super::getTrie ());
213 super::parent_trie::const_recursive_iterator end (0);
214 for (; item != end; item++)
215 {
216 if (item->payload () == 0) continue;
217 break;
218 }
219
220 if (item == end)
221 return End ();
222 else
223 return item->payload ();
224}
225
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700226Ptr<const CcnxFibEntry>
Alexander Afanasyev95a4fa32012-07-09 15:23:59 -0700227CcnxFibImpl::End ()
228{
229 return 0;
230}
231
Alexander Afanasyev11f7bb42012-07-09 17:06:30 -0700232Ptr<const CcnxFibEntry>
233CcnxFibImpl::Next (Ptr<const CcnxFibEntry> from)
Alexander Afanasyev95a4fa32012-07-09 15:23:59 -0700234{
235 if (from == 0) return 0;
236
237 super::parent_trie::const_recursive_iterator item (*StaticCast<const CcnxFibEntryImpl> (from)->to_iterator ());
238 super::parent_trie::const_recursive_iterator end (0);
239 for (item++; item != end; item++)
240 {
241 if (item->payload () == 0) continue;
242 break;
243 }
244
245 if (item == end)
246 return End ();
247 else
248 return item->payload ();
249}
250
251
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700252} // namespace ns3