blob: 08ef66bb2ef582c5ddf58610ff33b1d2f300bac7 [file] [log] [blame]
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -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 * Ilya Moiseenko <iliamo@cs.ucla.edu>
20 */
21
22#include "per-fib-limits.h"
23
24#include "ns3/ndn-interest-header.h"
25#include "ns3/ndn-content-object-header.h"
26#include "ns3/ndn-pit.h"
27#include "ns3/ndn-pit-entry.h"
28
29#include "ns3/assert.h"
30#include "ns3/log.h"
31#include "ns3/simulator.h"
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -070032#include "ns3/random-variable.h"
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -070033
34#include <boost/foreach.hpp>
35#include <boost/lambda/lambda.hpp>
36#include <boost/lambda/bind.hpp>
37namespace ll = boost::lambda;
38
39NS_LOG_COMPONENT_DEFINE ("ndn.fw.PerFibLimits");
40
41namespace ns3 {
42namespace ndn {
43namespace fw {
44
45NS_OBJECT_ENSURE_REGISTERED (PerFibLimits);
46
47TypeId
48PerFibLimits::GetTypeId (void)
49{
50 static TypeId tid = TypeId ("ns3::ndn::fw::PerFibLimits")
51 .SetGroupName ("Ndn")
52 .SetParent <FwStats> ()
53 .AddConstructor <PerFibLimits> ()
54 ;
55 return tid;
56}
57
58PerFibLimits::PerFibLimits ()
59{
60}
61
62void
63PerFibLimits::DoDispose ()
64{
65 BestRoute::DoDispose ();
66 m_decayLimitsEvent.Cancel ();
67}
68
69bool
70PerFibLimits::WillSendOutInterest (const Ptr<Face> &outgoingFace,
71 Ptr<InterestHeader> header,
72 Ptr<pit::Entry> pitEntry)
73{
74 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
75 // override all (if any) parent processing
76
77 pit::Entry::out_iterator outgoing =
78 pitEntry->GetOutgoing ().find (outgoingFace);
79
80 if (outgoing != pitEntry->GetOutgoing ().end ())
81 {
82 return false;
83 }
84
Alexander Afanasyev70426a02012-08-15 15:39:18 -070085 // check stats
86 Ptr<Face> inFace = pitEntry->GetIncoming ().begin ()->m_face;
87 // const ndnSIM::LoadStatsFace &stats = GetStatsTree ()[header->GetName ()].incoming ().find (inFace)->second;
88 const ndnSIM::LoadStatsFace &stats = GetStatsTree ()["/"].incoming ().find (inFace)->second;
89
90 if (stats.count ().GetStats ().get<0> () >= 0.5 * pitEntry->GetFibEntry ()->GetLimits ().GetMaxLimit ())
91 {
92 double ratio = std::min (1.0, stats.GetSatisfiedRatio ().get<0> ());
93 // NS_ASSERT_MSG (ratio > 0, "If count is a reasonable value, ratio cannot be negative");
94 UniformVariable randAccept (0, 1);
95 double dice = randAccept.GetValue ();
96 if (ratio < 0 || dice < ratio + 0.1)
97 {
98 // ok, accepting the interests
99 }
100 else
101 {
102 // boo. bad luck
103 return false;
104 }
105 }
106
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700107 if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
108 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700109 if (outgoingFace->GetLimits ().IsBelowLimit ())
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700110 {
111 pitEntry->AddOutgoing (outgoingFace);
112 return true;
113 }
114 else
115 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700116 NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700117 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
118 }
119 }
120
121 return false;
122}
123
124void
125PerFibLimits::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
126{
127 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
128
129 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
130 face != pitEntry->GetOutgoing ().end ();
131 face ++)
132 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700133 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700134 // face->m_face->GetLimits ()->DecreaseLimit (); !!! do not decrease per-face limit. it doesn't make sense !!!
135 }
136
137 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
Alexander Afanasyev70426a02012-08-15 15:39:18 -0700138 // pitEntry->GetFibEntry ()->GetLimits ().DecreaseLimit (); // multiplicative decrease
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700139
140 if (!m_decayLimitsEvent.IsRunning ())
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700141 {
142 UniformVariable rand (0,5);
143 m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0) + Seconds (0.001 * rand.GetValue ()), &PerFibLimits::DecayLimits, this);
144 }
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700145}
146
147
148void
149PerFibLimits::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
150 Ptr<pit::Entry> pitEntry)
151{
152 NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
153
154 super::WillSatisfyPendingInterest (incomingFace, pitEntry);
155
156 for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
157 face != pitEntry->GetOutgoing ().end ();
158 face ++)
159 {
Alexander Afanasyev6a3bb132012-08-15 09:47:35 -0700160 face->m_face->GetLimits ().RemoveOutstanding ();
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700161 // face->m_face->GetLimits ()->IncreaseLimit (); !!! do not increase (as do not decrease) per-face limit. again, it doesn't make sense
162 }
163
164 pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
Alexander Afanasyev70426a02012-08-15 15:39:18 -0700165 // pitEntry->GetFibEntry ()->GetLimits ().IncreaseLimit (); // additive increase
Alexander Afanasyevea9b3e62012-08-13 19:02:54 -0700166}
167
168
169// void
170// PerFibLimits::DidReceiveValidNack (const Ptr<Face> &incomingFace,
171// uint32_t nackCode,
172// Ptr<pit::Entry> pitEntry)
173// {
174// // super::DidReceiveValidNack (incomingFace, nackCode, pitEntry);
175
176// // ??
177// }
178
179void
180PerFibLimits::DecayLimits ()
181{
182 for (Ptr<fib::Entry> entry = m_fib->Begin ();
183 entry != m_fib->End ();
184 entry = m_fib->Next (entry))
185 {
186 entry->GetLimits ().DecayCurrentLimit ();
187 }
188
189 m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0), &PerFibLimits::DecayLimits, this);
190}
191
192
193} // namespace fw
194} // namespace ndn
195} // namespace ns3