blob: 6453bc6c0c8394c648aff1c0dda1f5e79c9cbe50 [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
23#include "ccnx.h"
24#include "ccnx-face.h"
25#include "ccnx-interest-header.h"
26
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 Afanasyev95a4fa32012-07-09 15:23:59 -070046 static TypeId tid = TypeId ("ns3::CcnxFibImpl") // cheating ns3 object system
47 .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
72CcnxFib::iterator
73CcnxFibImpl::LongestPrefixMatch (const CcnxInterestHeader &interest) const
74{
75 super::iterator item = const_cast<CcnxFibImpl*> (this)->super::longest_prefix_match (interest.GetName ());
76 // @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
85CcnxFib::iterator
86CcnxFibImpl::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
87{
88 return Add (Create<CcnxNameComponents> (prefix), face, metric);
89}
90
91CcnxFib::iterator
92CcnxFibImpl::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 Afanasyev1ba09b82012-07-09 09:16:14 -070097 Ptr<CcnxFibEntryImpl> newEntry = Create<CcnxFibEntryImpl> (prefix);
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -070098 std::pair< super::iterator, bool > result = super::insert (*prefix, newEntry);
Alexander Afanasyev1ba09b82012-07-09 09:16:14 -070099 newEntry->SetTrie (result.first);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700100
101 NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
102
103 super::modify (result.first,
104 ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
105
106 return result.first->payload ();
107}
108
109void
110CcnxFibImpl::Remove (const Ptr<const CcnxNameComponents> &prefix)
111{
112 NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
113
114 super::erase (*prefix);
115}
116
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700117// void
118// CcnxFibImpl::Invalidate (const Ptr<const CcnxNameComponents> &prefix)
119// {
120// NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700121
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700122// super::iterator foundItem, lastItem;
123// bool reachLast;
124// boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (*prefix);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700125
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700126// if (!reachLast || lastItem->payload () == 0)
127// return; // nothing to invalidate
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700128
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700129// super::modify (lastItem,
130// ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
131// }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700132
133void
134CcnxFibImpl::InvalidateAll ()
135{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700136 NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId ());
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700137
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700138 super::parent_trie::recursive_iterator item (super::getTrie ());
139 super::parent_trie::recursive_iterator end (0);
140 for (; item != end; item++)
141 {
142 if (item->payload () == 0) continue;
143
144 super::modify (&(*item),
145 ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
146 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700147}
148
149void
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700150CcnxFibImpl::Remove (super::parent_trie &item, Ptr<CcnxFace> face)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700151{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700152 if (item.payload () == 0) return;
153 NS_LOG_FUNCTION (this);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700154
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700155 super::modify (&item,
156 ll::bind (&CcnxFibEntry::RemoveFace, ll::_1, face));
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700157}
158
159void
160CcnxFibImpl::RemoveFromAll (Ptr<CcnxFace> face)
161{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700162 NS_LOG_FUNCTION (this);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700163
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700164 std::for_each (super::parent_trie::recursive_iterator (super::getTrie ()),
165 super::parent_trie::recursive_iterator (0),
166 ll::bind (static_cast< void (CcnxFib::*) (super::parent_trie &, Ptr<CcnxFace>) > (&CcnxFibImpl::Remove),
167 this, ll::_1, face));
168
169 super::parent_trie::recursive_iterator trieNode (super::getTrie ());
170 super::parent_trie::recursive_iterator end (0);
171 for (; trieNode != end; trieNode++)
172 {
173 if (trieNode->payload () == 0) continue;
174
175 if (trieNode->payload ()->m_faces.size () == 0)
176 {
177 trieNode = super::parent_trie::recursive_iterator (trieNode->erase ());
178 }
179 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700180}
181
182void
183CcnxFibImpl::Print (std::ostream &os) const
184{
Alexander Afanasyev44bb6ea2012-07-09 08:44:41 -0700185 // !!! unordered_set imposes "random" order of item in the same level !!!
186 super::parent_trie::const_recursive_iterator item (super::getTrie ());
187 super::parent_trie::const_recursive_iterator end (0);
188 for (; item != end; item++)
189 {
190 if (item->payload () == 0) continue;
191
192 os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
193 }
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700194}
195
Alexander Afanasyev95a4fa32012-07-09 15:23:59 -0700196CcnxFib::const_iterator
197CcnxFibImpl::Begin ()
198{
199 super::parent_trie::const_recursive_iterator item (super::getTrie ());
200 super::parent_trie::const_recursive_iterator end (0);
201 for (; item != end; item++)
202 {
203 if (item->payload () == 0) continue;
204 break;
205 }
206
207 if (item == end)
208 return End ();
209 else
210 return item->payload ();
211}
212
213CcnxFib::const_iterator
214CcnxFibImpl::End ()
215{
216 return 0;
217}
218
219CcnxFib::const_iterator
220CcnxFibImpl::Next (CcnxFib::const_iterator from)
221{
222 if (from == 0) return 0;
223
224 super::parent_trie::const_recursive_iterator item (*StaticCast<const CcnxFibEntryImpl> (from)->to_iterator ());
225 super::parent_trie::const_recursive_iterator end (0);
226 for (item++; item != end; item++)
227 {
228 if (item->payload () == 0) continue;
229 break;
230 }
231
232 if (item == end)
233 return End ();
234 else
235 return item->payload ();
236}
237
238
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700239} // namespace ns3