NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
ndn-limits-rate.cc
1 /* -*- 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 "ndn-limits-rate.h"
22 
23 #include "ns3/log.h"
24 #include "ns3/simulator.h"
25 #include "ns3/random-variable.h"
26 #include "ns3/ndn-face.h"
27 #include "ns3/node.h"
28 
29 NS_LOG_COMPONENT_DEFINE ("ndn.Limits.Rate");
30 
31 namespace ns3 {
32 namespace ndn {
33 
34 NS_OBJECT_ENSURE_REGISTERED (LimitsRate);
35 
36 TypeId
37 LimitsRate::GetTypeId ()
38 {
39  static TypeId tid = TypeId ("ns3::ndn::Limits::Rate")
40  .SetGroupName ("Ndn")
41  .SetParent <Limits> ()
42  .AddConstructor <LimitsRate> ()
43 
44  .AddAttribute ("RandomizeLeak", "Randomize start time for token bucket leakage. May be helpful to prevent leak synchronizations",
45  TimeValue (Seconds (0.001)),
46  MakeTimeAccessor (&LimitsRate::m_leakRandomizationInteral),
47  MakeTimeChecker ())
48 
49  ;
50  return tid;
51 }
52 
53 void
54 LimitsRate::NotifyNewAggregate ()
55 {
56  super::NotifyNewAggregate ();
57 
58  if (!m_isLeakScheduled)
59  {
60  if (GetObject<Face> () != 0)
61  {
62  NS_ASSERT_MSG (GetObject<Face> ()->GetNode () != 0, "Node object should exist on the face");
63 
64  m_isLeakScheduled = true;
65 
66  if (!m_leakRandomizationInteral.IsZero ())
67  {
68  UniformVariable r (0.0, m_leakRandomizationInteral.ToDouble (Time::S));
69  Simulator::ScheduleWithContext (GetObject<Face> ()->GetNode ()->GetId (),
70  Seconds (r.GetValue ()), &LimitsRate::LeakBucket, this, 0.0);
71  }
72  else
73  {
74  Simulator::ScheduleWithContext (GetObject<Face> ()->GetNode ()->GetId (),
75  Seconds (0), &LimitsRate::LeakBucket, this, 0.0);
76  }
77 
78  }
79  }
80 }
81 
82 void
83 LimitsRate::SetLimits (double rate, double delay)
84 {
85  super::SetLimits (rate, delay);
86 
87  // maximum allowed burst
88  m_bucketMax = GetMaxRate () * GetMaxDelay ();
89 
90  // amount of packets allowed every second (leak rate)
91  m_bucketLeak = GetMaxRate ();
92 }
93 
94 
95 void
97 {
98  NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
99 
100  m_bucketLeak = std::min (limit, GetMaxRate ());
101  m_bucketMax = m_bucketLeak * GetMaxDelay ();
102 }
103 
104 bool
106 {
107  if (!IsEnabled ()) return true;
108 
109  return (m_bucketMax - m_bucket >= 1.0);
110 }
111 
112 void
114 {
115  if (!IsEnabled ()) return;
116 
117  NS_ASSERT_MSG (m_bucketMax - m_bucket >= 1.0, "Should not be possible, unless we IsBelowLimit was not checked correctly");
118  m_bucket += 1;
119 }
120 
121 void
123 {
124  // do nothing
125 }
126 
127 void
128 LimitsRate::LeakBucket (double interval)
129 {
130  const double leak = m_bucketLeak * interval;
131 
132 #ifdef NS3_LOG_ENABLE
133  if (m_bucket>1)
134  {
135  NS_LOG_DEBUG ("Leak from " << m_bucket << " to " << std::max (0.0, m_bucket - leak));
136  }
137 #endif
138 
139  double bucketOld = m_bucket;
140 
141  m_bucket = std::max (0.0, m_bucket - leak);
142 
143  // calculate interval so next time we will leak by 1.001, unless such interval would be more than 1 second
144  double newInterval = 1.0;
145  if (m_bucketLeak > 1.0)
146  {
147  newInterval = 1.001 / m_bucketLeak;
148  }
149 
150  if (m_bucketMax - bucketOld < 1.0 &&
151  m_bucketMax - m_bucket >= 1.0) // limit number of times this stuff is called
152  {
153  this->FireAvailableSlotCallback ();
154  }
155 
156  Simulator::Schedule (Seconds (newInterval), &LimitsRate::LeakBucket, this, newInterval);
157 }
158 
159 } // namespace ndn
160 } // namespace ns3
virtual bool IsBelowLimit()
Check if Interest limit is reached (token bucket is not empty)
virtual void BorrowLimit()
Get token from the bucket.
virtual bool IsEnabled() const
Check whether limits are enabled or not.
Definition: ndn-limits.h:96
virtual void SetLimits(double rate, double delay)
Set limit for the number of outstanding interests.
Limits()
Default constructor.
Definition: ndn-limits.cc:43
virtual double GetMaxDelay() const
Get maximum delay for BDP product for window-based limits.
Definition: ndn-limits.h:80
virtual void SetLimits(double rate, double delay)
Set limit for the number of outstanding interests.
Definition: ndn-limits.h:61
virtual double GetMaxRate() const
Get maximum rate that needs to be enforced.
Definition: ndn-limits.h:71
virtual void ReturnLimit()
Does nothing (token bucket leakage is time-dependent only)
virtual void UpdateCurrentLimit(double limit)
Update normalized amount that should be leaked every second (token bucket leak rate) and leak rate...