blob: 8fd21e005bc43395f7fe697a2c3cdb29a2600247 [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 Afanasyev78cf0c92011-09-01 19:57:14 -070031// NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070032
33using namespace __ccnx_private;
34
35// size_t
36// PitEntry::numberOfPromisingInterests(e_pi ) const
37// {
38// size_t count = 0;
39
40// BOOST_FOREACH (const CcnxPitOutgoingInterest &interest, m_outgoingInterests)
41// {
42// }
43// for( PitOutgoingConstIterator i = outgoingInterests.begin();
44// i!=outgoingInterests.end();
45// i++ )
46// {
47// if( !i->waitingInVain ) count++;
48// }
49
50// return count;
51// }
52
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070053TypeId
54CcnxPit::GetTypeId ()
55{
56 static TypeId tid = TypeId ("ns3::CcnxPit")
57 .SetGroupName ("Ccnx")
58 .SetParent<Object> ()
59 .AddConstructor<CcnxPit> ()
60 .AddAttribute ("CleanupTimeout",
61 "Timeout defining how frequent RIT should be cleaned up",
62 TimeValue (Seconds (1)),
63 MakeTimeAccessor (&CcnxPit::GetCleanupTimeout, &CcnxPit::SetCleanupTimeout),
64 MakeTimeChecker ())
65 ;
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070066
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070067 return tid;
68}
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070069
70CcnxPit::CcnxPit ()
71{
72}
73
74void
75CcnxPit::SetCleanupTimeout (const Time &timeout)
76{
77 m_cleanupTimeout = timeout;
78 if (m_cleanupEvent.IsRunning ())
79 m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events
80
81 // schedule even with new timeout
82 m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
83 &CcnxPit::CleanExpired, this);
84}
85
86Time
87CcnxPit::GetCleanupTimeout () const
88{
89 return m_cleanupTimeout;
90}
91
92void CcnxPit::CleanExpired ()
93{
94 NS_LOG_LOGIC ("Cleaning PIT");
95 Time now = Simulator::Now ();
96
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070097 while( !empty() )
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070098 {
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070099 if( get<i_timestamp> ().front ().GetExpireTime () <= now ) // is the record stale?
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700100 {
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700101 get<i_timestamp> ().pop_front( );
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700102 }
103 else
104 break; // nothing else to do. All later records will not be stale
105 }
106
107 // schedule next even
108 m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
109 &CcnxPit::CleanExpired, this);
110}
111
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700112void
113CcnxPit::SetFib (Ptr<CcnxFib> fib)
114{
115 m_fib = fib;
116}
117
Ilya Moiseenko60491402011-10-28 13:10:16 -0700118/*CcnxPitEntryContainer::type::iterator
119CcnxPit::Add (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator fibEntry, Ptr<CcnxFace> face)
120{
121 if( m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] )
122 {
123 // printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
124 return end();
125 }
126
127 CcnxPitEntryContainer::type::iterator entry = insert (end (),
128 CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
129 *fibEntry));
130 return entry;
131}*/
132
133
134
135bool
136CcnxPit::TryAddOutgoing(CcnxPitEntryContainer::type::iterator pitEntry, Ptr<CcnxFace> face)
137{
138 NS_LOG_INFO ("Face has " << m_bucketsPerFace[face->GetId()] << " packets with max allowance " << maxBucketsPerFace[face->GetId()]);
139
140 if((face->IsLocal() == false)
141 && (m_bucketsPerFace[face->GetId()]+1.0 >= maxBucketsPerFace[face->GetId()] ))
142 {
143 return false;
144 }
145
146 m_bucketsPerFace[face->GetId()] = m_bucketsPerFace[face->GetId()] + 1.0;
147
148 NS_LOG_INFO(this->size());
149 NS_LOG_INFO("before modify");
150 NS_LOG_INFO(pitEntry->GetPrefix());
151 modify (pitEntry, CcnxPitEntry::AddOutgoing(face));
152 NS_LOG_INFO("after modify");
153 return true;
154}
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700155
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700156const CcnxPitEntry&
157CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
158{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700159 NS_LOG_FUNCTION_NOARGS ();
160
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700161 CcnxPitEntryContainer::type::iterator entry =
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700162 get<i_prefix> ().find (header.GetName ());
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700163
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700164 if (entry == end ())
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700165 throw CcnxPitEntryNotFound();
166
167 return *entry;
168}
169
Ilya Moiseenko60491402011-10-28 13:10:16 -0700170CcnxPitEntryContainer::type::iterator
171CcnxPit::Lookup (const CcnxInterestHeader &header, CcnxFibEntryContainer::type::iterator &outFibEntry)
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700172{
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700173 NS_LOG_FUNCTION_NOARGS ();
174 NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
175
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700176 CcnxPitEntryContainer::type::iterator entry =
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700177 get<i_prefix> ().find (header.GetName ());
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700178
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700179 CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
180 if (fibEntry == m_fib->end ())
181 {
182 NS_LOG_WARN ("FIB entry wasn't found. Creating an empty record");
183 fibEntry = m_fib->insert (m_fib->end (), CcnxFibEntry (header.GetName ()));
184 }
185
186 if (entry == end ())
Ilya Moiseenko60491402011-10-28 13:10:16 -0700187 {
188 NS_LOG_INFO("entry == end");
189 NS_LOG_INFO(this->size());
190 entry = insert (end (),
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700191 CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
192 *fibEntry));
Ilya Moiseenko60491402011-10-28 13:10:16 -0700193 NS_LOG_INFO(this->size());
194 }
195 outFibEntry = fibEntry;
196 return entry;
197}
198
199void
200CcnxPit::LeakBuckets( )
201{
202 for( PitBucketIterator it=m_bucketsPerFace.begin();
203 it != m_bucketsPerFace.end();
204 it++ )
205 {
206 it->second = std::max( 0.0, it->second - leakSize[it->first] );
207 }
208}
209
210void
211CcnxPit::LeakBucket(Ptr<CcnxFace> face, int amount )
212{
213 m_bucketsPerFace[face->GetId()] = std::max( 0.0, m_bucketsPerFace[face->GetId()] - amount );
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700214}
215
216
217} // namespace ns3