limits: finalizing rate-based limits
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 92de4db..1b1c512 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -100,8 +100,6 @@
module.add_class('Tag', import_from_module='ns.network', parent=root_module['ns3::ObjectBase'])
## tag-buffer.h (module 'network'): ns3::TagBuffer [class]
module.add_class('TagBuffer', import_from_module='ns.network')
- ## traced-value.h (module 'core'): ns3::TracedValue<double> [class]
- module.add_class('TracedValue', import_from_module='ns.core', template_parameters=['double'])
## random-variable.h (module 'core'): ns3::TriangularVariable [class]
module.add_class('TriangularVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
## type-id.h (module 'core'): ns3::TypeId [class]
@@ -516,7 +514,6 @@
register_Ns3SpringMobilityHelper_methods(root_module, root_module['ns3::SpringMobilityHelper'])
register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
- register_Ns3TracedValue__Double_methods(root_module, root_module['ns3::TracedValue< double >'])
register_Ns3TriangularVariable_methods(root_module, root_module['ns3::TriangularVariable'])
register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId'])
register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
@@ -2223,40 +2220,6 @@
[param('uint8_t', 'v')])
return
-def register_Ns3TracedValue__Double_methods(root_module, cls):
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue() [constructor]
- cls.add_constructor([])
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue(ns3::TracedValue<double> const & o) [copy constructor]
- cls.add_constructor([param('ns3::TracedValue< double > const &', 'o')])
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue(double const & v) [constructor]
- cls.add_constructor([param('double const &', 'v')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
- cls.add_method('Connect',
- 'void',
- [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::ConnectWithoutContext(ns3::CallbackBase const & cb) [member function]
- cls.add_method('ConnectWithoutContext',
- 'void',
- [param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
- cls.add_method('Disconnect',
- 'void',
- [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::DisconnectWithoutContext(ns3::CallbackBase const & cb) [member function]
- cls.add_method('DisconnectWithoutContext',
- 'void',
- [param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h (module 'core'): double ns3::TracedValue<double>::Get() const [member function]
- cls.add_method('Get',
- 'double',
- [],
- is_const=True)
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Set(double const & v) [member function]
- cls.add_method('Set',
- 'void',
- [param('double const &', 'v')])
- return
-
def register_Ns3TriangularVariable_methods(root_module, cls):
## random-variable.h (module 'core'): ns3::TriangularVariable::TriangularVariable(ns3::TriangularVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::TriangularVariable const &', 'arg0')])
@@ -5836,13 +5799,23 @@
cls.add_constructor([param('ns3::ndn::Limits const &', 'arg0')])
## ndn-limits.h (module 'ndnSIM'): ns3::ndn::Limits::Limits() [constructor]
cls.add_constructor([])
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::BorrowLimit() [member function]
+ cls.add_method('BorrowLimit',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetCurrentLimit() const [member function]
cls.add_method('GetCurrentLimit',
'double',
[],
- is_const=True)
- ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxLimit() const [member function]
- cls.add_method('GetMaxLimit',
+ is_pure_virtual=True, is_const=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxDelay() const [member function]
+ cls.add_method('GetMaxDelay',
+ 'double',
+ [],
+ is_const=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxRate() const [member function]
+ cls.add_method('GetMaxRate',
'double',
[],
is_const=True, is_virtual=True)
@@ -5861,15 +5834,21 @@
'bool',
[],
is_const=True, is_virtual=True)
- ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetMaxLimit(double max) [member function]
- cls.add_method('SetMaxLimit',
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::ReturnLimit() [member function]
+ cls.add_method('ReturnLimit',
'void',
- [param('double', 'max')],
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetLimits(double rate, double delay) [member function]
+ cls.add_method('SetLimits',
+ 'void',
+ [param('double', 'rate'), param('double', 'delay')],
is_virtual=True)
## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::UpdateCurrentLimit(double limit) [member function]
cls.add_method('UpdateCurrentLimit',
'void',
- [param('double', 'limit')])
+ [param('double', 'limit')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3NdnNameComponents_methods(root_module, cls):
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index 92de4db..1b1c512 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -100,8 +100,6 @@
module.add_class('Tag', import_from_module='ns.network', parent=root_module['ns3::ObjectBase'])
## tag-buffer.h (module 'network'): ns3::TagBuffer [class]
module.add_class('TagBuffer', import_from_module='ns.network')
- ## traced-value.h (module 'core'): ns3::TracedValue<double> [class]
- module.add_class('TracedValue', import_from_module='ns.core', template_parameters=['double'])
## random-variable.h (module 'core'): ns3::TriangularVariable [class]
module.add_class('TriangularVariable', import_from_module='ns.core', parent=root_module['ns3::RandomVariable'])
## type-id.h (module 'core'): ns3::TypeId [class]
@@ -516,7 +514,6 @@
register_Ns3SpringMobilityHelper_methods(root_module, root_module['ns3::SpringMobilityHelper'])
register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
- register_Ns3TracedValue__Double_methods(root_module, root_module['ns3::TracedValue< double >'])
register_Ns3TriangularVariable_methods(root_module, root_module['ns3::TriangularVariable'])
register_Ns3TypeId_methods(root_module, root_module['ns3::TypeId'])
register_Ns3TypeIdAttributeInformation_methods(root_module, root_module['ns3::TypeId::AttributeInformation'])
@@ -2223,40 +2220,6 @@
[param('uint8_t', 'v')])
return
-def register_Ns3TracedValue__Double_methods(root_module, cls):
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue() [constructor]
- cls.add_constructor([])
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue(ns3::TracedValue<double> const & o) [copy constructor]
- cls.add_constructor([param('ns3::TracedValue< double > const &', 'o')])
- ## traced-value.h (module 'core'): ns3::TracedValue<double>::TracedValue(double const & v) [constructor]
- cls.add_constructor([param('double const &', 'v')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Connect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
- cls.add_method('Connect',
- 'void',
- [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::ConnectWithoutContext(ns3::CallbackBase const & cb) [member function]
- cls.add_method('ConnectWithoutContext',
- 'void',
- [param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Disconnect(ns3::CallbackBase const & cb, std::basic_string<char,std::char_traits<char>,std::allocator<char> > path) [member function]
- cls.add_method('Disconnect',
- 'void',
- [param('ns3::CallbackBase const &', 'cb'), param('std::string', 'path')])
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::DisconnectWithoutContext(ns3::CallbackBase const & cb) [member function]
- cls.add_method('DisconnectWithoutContext',
- 'void',
- [param('ns3::CallbackBase const &', 'cb')])
- ## traced-value.h (module 'core'): double ns3::TracedValue<double>::Get() const [member function]
- cls.add_method('Get',
- 'double',
- [],
- is_const=True)
- ## traced-value.h (module 'core'): void ns3::TracedValue<double>::Set(double const & v) [member function]
- cls.add_method('Set',
- 'void',
- [param('double const &', 'v')])
- return
-
def register_Ns3TriangularVariable_methods(root_module, cls):
## random-variable.h (module 'core'): ns3::TriangularVariable::TriangularVariable(ns3::TriangularVariable const & arg0) [copy constructor]
cls.add_constructor([param('ns3::TriangularVariable const &', 'arg0')])
@@ -5836,13 +5799,23 @@
cls.add_constructor([param('ns3::ndn::Limits const &', 'arg0')])
## ndn-limits.h (module 'ndnSIM'): ns3::ndn::Limits::Limits() [constructor]
cls.add_constructor([])
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::BorrowLimit() [member function]
+ cls.add_method('BorrowLimit',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetCurrentLimit() const [member function]
cls.add_method('GetCurrentLimit',
'double',
[],
- is_const=True)
- ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxLimit() const [member function]
- cls.add_method('GetMaxLimit',
+ is_pure_virtual=True, is_const=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxDelay() const [member function]
+ cls.add_method('GetMaxDelay',
+ 'double',
+ [],
+ is_const=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxRate() const [member function]
+ cls.add_method('GetMaxRate',
'double',
[],
is_const=True, is_virtual=True)
@@ -5861,15 +5834,21 @@
'bool',
[],
is_const=True, is_virtual=True)
- ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetMaxLimit(double max) [member function]
- cls.add_method('SetMaxLimit',
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::ReturnLimit() [member function]
+ cls.add_method('ReturnLimit',
'void',
- [param('double', 'max')],
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetLimits(double rate, double delay) [member function]
+ cls.add_method('SetLimits',
+ 'void',
+ [param('double', 'rate'), param('double', 'delay')],
is_virtual=True)
## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::UpdateCurrentLimit(double limit) [member function]
cls.add_method('UpdateCurrentLimit',
'void',
- [param('double', 'limit')])
+ [param('double', 'limit')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3NdnNameComponents_methods(root_module, cls):
diff --git a/utils/ndn-limits-rate.cc b/utils/ndn-limits-rate.cc
index 215250e..1bf0af4 100644
--- a/utils/ndn-limits-rate.cc
+++ b/utils/ndn-limits-rate.cc
@@ -23,6 +23,8 @@
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/random-variable.h"
+#include "ns3/ndn-face.h"
+#include "ns3/node.h"
NS_LOG_COMPONENT_DEFINE ("ndn.Limits.Rate");
@@ -44,6 +46,26 @@
}
void
+LimitsRate::NotifyNewAggregate ()
+{
+ super::NotifyNewAggregate ();
+
+ if (!m_isLeakScheduled)
+ {
+ if (GetObject<Face> () != 0)
+ {
+ NS_ASSERT_MSG (GetObject<Face> ()->GetNode () != 0, "Node object should exist on the face");
+
+ m_isLeakScheduled = true;
+ UniformVariable r (0,1);
+ Simulator::ScheduleWithContext (GetObject<Face> ()->GetNode ()->GetId (),
+ Seconds (r.GetValue ()), &LimitsRate::LeakBucket, this, 0.0);
+ }
+ }
+}
+
+
+void
LimitsRate::UpdateCurrentLimit (double limit)
{
NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
@@ -80,7 +102,23 @@
{
const double leak = m_bucketLeak * interval;
+#ifdef NS3_LOG_ENABLE
+ if (m_bucket>1)
+ {
+ NS_LOG_DEBUG ("Leak from " << m_bucket << " to " << std::max (0.0, m_bucket - leak));
+ }
+#endif
+
m_bucket = std::max (0.0, m_bucket - leak);
+
+ // calculate interval so next time we will leak by 1.001, unless such interval would be more than 1 second
+ double newInterval = 1.0;
+ if (m_bucketLeak > 1.0)
+ {
+ newInterval = 1.001 / m_bucketLeak;
+ }
+
+ Simulator::Schedule (Seconds (newInterval), &LimitsRate::LeakBucket, this, newInterval);
}
} // namespace ndn
diff --git a/utils/ndn-limits-rate.h b/utils/ndn-limits-rate.h
index 4050bb2..15344c6 100644
--- a/utils/ndn-limits-rate.h
+++ b/utils/ndn-limits-rate.h
@@ -44,8 +44,9 @@
* \param prefix smart pointer to the prefix for the FIB entry
*/
LimitsRate ()
- : m_bucketMax (0)
- , m_bucketLeak (0)
+ : m_isLeakScheduled (false)
+ , m_bucketMax (0)
+ , m_bucketLeak (1)
, m_bucket (0)
{ }
@@ -96,6 +97,11 @@
return m_bucketLeak;
}
+protected:
+ // from Node
+ void
+ NotifyNewAggregate ();
+
private:
/**
* @brief Leak bucket, assuming `interval' seconds between leakages
@@ -106,6 +112,8 @@
LeakBucket (double interval);
private:
+ bool m_isLeakScheduled;
+
double m_bucketMax; ///< \brief Maximum Interest allowance for this face (maximum tokens that can be issued at the same time)
double m_bucketLeak; ///< \brief Normalized amount that should be leaked every second (token bucket leak rate)
double m_bucket; ///< \brief Value representing current size of the Interest allowance for this face (current size of token bucket)