blob: 86484efec1e8a8076cf33f72a14c15f5cfcd5765 [file] [log] [blame]
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -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.h"
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ccnx-interest-header.h"
25#include "ccnx-content-object-header.h"
26
27NS_LOG_COMPONENT_DEFINE ("CcnxPit");
28
29namespace ns3 {
30
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -080031NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070032
33using namespace __ccnx_private;
34
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070035TypeId
36CcnxPit::GetTypeId ()
37{
38 static TypeId tid = TypeId ("ns3::CcnxPit")
39 .SetGroupName ("Ccnx")
40 .SetParent<Object> ()
41 .AddConstructor<CcnxPit> ()
42 .AddAttribute ("CleanupTimeout",
43 "Timeout defining how frequent RIT should be cleaned up",
44 TimeValue (Seconds (1)),
45 MakeTimeAccessor (&CcnxPit::GetCleanupTimeout, &CcnxPit::SetCleanupTimeout),
46 MakeTimeChecker ())
47 ;
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070048
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070049 return tid;
50}
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070051
52CcnxPit::CcnxPit ()
53{
54}
55
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -080056CcnxPit::~CcnxPit ()
57{
58 if (m_cleanupEvent.IsRunning ())
59 m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
60
61 clear ();
62}
63
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070064void
65CcnxPit::SetCleanupTimeout (const Time &timeout)
66{
67 m_cleanupTimeout = timeout;
68 if (m_cleanupEvent.IsRunning ())
69 m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
70
71 // schedule even with new timeout
72 m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
73 &CcnxPit::CleanExpired, this);
74}
75
76Time
77CcnxPit::GetCleanupTimeout () const
78{
79 return m_cleanupTimeout;
80}
81
82void CcnxPit::CleanExpired ()
83{
84 NS_LOG_LOGIC ("Cleaning PIT");
85 Time now = Simulator::Now ();
86
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070087 while( !empty() )
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070088 {
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070089 if( get<i_timestamp> ().front ().GetExpireTime () <= now ) // is the record stale?
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070090 {
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070091 get<i_timestamp> ().pop_front( );
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070092 }
93 else
94 break; // nothing else to do. All later records will not be stale
95 }
96
97 // schedule next even
98 m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
99 &CcnxPit::CleanExpired, this);
100}
101
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700102void
103CcnxPit::SetFib (Ptr<CcnxFib> fib)
104{
105 m_fib = fib;
106}
107
Ilya Moiseenko60491402011-10-28 13:10:16 -0700108/*CcnxPitEntryContainer::type::iterator
109CcnxPit::Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face)
110{
111 if( m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] )
112 {
113 // printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
114 return end();
115 }
116
117 CcnxPitEntryContainer::type::iterator entry = insert (end (),
118 CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
119 *fibEntry));
120 return entry;
121}*/
122
123
124
125bool
126CcnxPit::TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face)
127{
128 NS_LOG_INFO ("Face has " << m_bucketsPerFace[face->GetId()] << " packets with max allowance " << maxBucketsPerFace[face->GetId()]);
129
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800130 if((face->IsLocal() == false)
Ilya Moiseenko60491402011-10-28 13:10:16 -0700131 && (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] ))
132 {
Ilya Moiseenkoaa1154b2011-11-16 16:30:11 -0800133 NS_LOG_INFO("********LIMIT**************");
Ilya Moiseenko60491402011-10-28 13:10:16 -0700134 return false;
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800135 }
Ilya Moiseenko60491402011-10-28 13:10:16 -0700136
Ilya Moiseenko00b30482011-11-15 17:58:00 -0800137 m_bucketsPerFace[face->GetId()] = m_bucketsPerFace[face->GetId()] + 1.0;
Ilya Moiseenko60491402011-10-28 13:10:16 -0700138
139 NS_LOG_INFO(this->size());
140 NS_LOG_INFO("before modify");
141 NS_LOG_INFO(pitEntry->GetPrefix());
142 modify (pitEntry, CcnxPitEntry::AddOutgoing(face));
143 NS_LOG_INFO("after modify");
144 return true;
145}
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700146
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700147const CcnxPitEntry&
148CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
149{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700150 NS_LOG_FUNCTION_NOARGS ();
151
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700152 CcnxPitEntryContainer::type::iterator entry =
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700153 get<i_prefix> ().find (header.GetName ());
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700154
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700155 if (entry == end ())
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700156 throw CcnxPitEntryNotFound();
157
158 return *entry;
159}
160
Ilya Moiseenko60491402011-10-28 13:10:16 -0700161CcnxPitEntryContainer::type::iterator
162CcnxPit::Lookup (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator &outFibEntry)
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700163{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700164 NS_LOG_FUNCTION_NOARGS ();
165 NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
166
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700167 CcnxPitEntryContainer::type::iterator entry =
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700168 get<i_prefix> ().find (header.GetName ());
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700169
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700170 CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
171 if (fibEntry == m_fib->end ())
172 {
173 NS_LOG_WARN ("FIB entry wasn't found. Creating an empty record");
174 fibEntry = m_fib->insert (m_fib->end (), CcnxFibEntry (header.GetName ()));
175 }
176
177 if (entry == end ())
Ilya Moiseenko60491402011-10-28 13:10:16 -0700178 {
179 NS_LOG_INFO("entry == end");
180 NS_LOG_INFO(this->size());
181 entry = insert (end (),
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700182 CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
183 *fibEntry));
Ilya Moiseenko60491402011-10-28 13:10:16 -0700184 NS_LOG_INFO(this->size());
185 }
186 outFibEntry = fibEntry;
187 return entry;
188}
189
190void
191CcnxPit::LeakBuckets( )
192{
193 for( PitBucketIterator it=m_bucketsPerFace.begin();
194 it != m_bucketsPerFace.end();
195 it++ )
196 {
197 it->second = std::max( 0.0, it->second - leakSize[it->first] );
198 }
199}
200
201void
202CcnxPit::LeakBucket(Ptr<CcnxFace> face, int amount )
203{
204 m_bucketsPerFace[face->GetId()] = std::max( 0.0, m_bucketsPerFace[face->GetId()] - amount );
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700205}
206
207
208} // namespace ns3