blob: 1bf0af4fe26a4a9ffc01be0c7375a8926ebaeffa [file] [log] [blame]
Alexander Afanasyev6f95e702012-10-31 16:27:31 -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 "ndn-limits-rate.h"
22
23#include "ns3/log.h"
24#include "ns3/simulator.h"
25#include "ns3/random-variable.h"
Alexander Afanasyev7e4235a2012-10-31 16:58:44 -070026#include "ns3/ndn-face.h"
27#include "ns3/node.h"
Alexander Afanasyev6f95e702012-10-31 16:27:31 -070028
29NS_LOG_COMPONENT_DEFINE ("ndn.Limits.Rate");
30
31namespace ns3 {
32namespace ndn {
33
34NS_OBJECT_ENSURE_REGISTERED (LimitsRate);
35
36TypeId
37LimitsRate::GetTypeId ()
38{
39 static TypeId tid = TypeId ("ns3::ndn::Limits::Rate")
40 .SetGroupName ("Ndn")
41 .SetParent <Limits> ()
42 .AddConstructor <LimitsRate> ()
43
44 ;
45 return tid;
46}
47
48void
Alexander Afanasyev7e4235a2012-10-31 16:58:44 -070049LimitsRate::NotifyNewAggregate ()
50{
51 super::NotifyNewAggregate ();
52
53 if (!m_isLeakScheduled)
54 {
55 if (GetObject<Face> () != 0)
56 {
57 NS_ASSERT_MSG (GetObject<Face> ()->GetNode () != 0, "Node object should exist on the face");
58
59 m_isLeakScheduled = true;
60 UniformVariable r (0,1);
61 Simulator::ScheduleWithContext (GetObject<Face> ()->GetNode ()->GetId (),
62 Seconds (r.GetValue ()), &LimitsRate::LeakBucket, this, 0.0);
63 }
64 }
65}
66
67
68void
Alexander Afanasyev6f95e702012-10-31 16:27:31 -070069LimitsRate::UpdateCurrentLimit (double limit)
70{
71 NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
72
73 m_bucketLeak = std::min (limit, GetMaxRate ());
74 m_bucketMax = m_bucketLeak * GetMaxDelay ();
75}
76
77bool
78LimitsRate::IsBelowLimit ()
79{
80 if (!IsEnabled ()) return true;
81
82 return (m_bucketMax - m_bucket >= 1.0);
83}
84
85void
86LimitsRate::BorrowLimit ()
87{
88 if (!IsEnabled ()) return;
89
90 NS_ASSERT_MSG (m_bucketMax - m_bucket >= 1.0, "Should not be possible, unless we IsBelowLimit was not checked correctly");
91 m_bucket += 1;
92}
93
94void
95LimitsRate::ReturnLimit ()
96{
97 // do nothing
98}
99
100void
101LimitsRate::LeakBucket (double interval)
102{
103 const double leak = m_bucketLeak * interval;
104
Alexander Afanasyev7e4235a2012-10-31 16:58:44 -0700105#ifdef NS3_LOG_ENABLE
106 if (m_bucket>1)
107 {
108 NS_LOG_DEBUG ("Leak from " << m_bucket << " to " << std::max (0.0, m_bucket - leak));
109 }
110#endif
111
Alexander Afanasyev6f95e702012-10-31 16:27:31 -0700112 m_bucket = std::max (0.0, m_bucket - leak);
Alexander Afanasyev7e4235a2012-10-31 16:58:44 -0700113
114 // calculate interval so next time we will leak by 1.001, unless such interval would be more than 1 second
115 double newInterval = 1.0;
116 if (m_bucketLeak > 1.0)
117 {
118 newInterval = 1.001 / m_bucketLeak;
119 }
120
121 Simulator::Schedule (Seconds (newInterval), &LimitsRate::LeakBucket, this, newInterval);
Alexander Afanasyev6f95e702012-10-31 16:27:31 -0700122}
123
124} // namespace ndn
125} // namespace ns3