limits: one more update and small interface changes
diff --git a/helper/ndn-global-routing-helper.cc b/helper/ndn-global-routing-helper.cc
index 7acf7d6..3d18042 100644
--- a/helper/ndn-global-routing-helper.cc
+++ b/helper/ndn-global-routing-helper.cc
@@ -288,7 +288,7 @@
limitsFactory.SetTypeId (limits->GetInstanceTypeId ());
Ptr<Limits> entryLimits = limitsFactory.Create<Limits> ();
- entryLimits->SetMaxLimit (limits->GetMaxLimit ());
+ entryLimits->SetLimits (limits->GetMaxRate (), limits->GetMaxDelay ());
entry->AggregateObject (entryLimits);
}
diff --git a/helper/ndn-stack-helper.cc b/helper/ndn-stack-helper.cc
index 9c29bf9..5dade78 100644
--- a/helper/ndn-stack-helper.cc
+++ b/helper/ndn-stack-helper.cc
@@ -279,7 +279,7 @@
NS_LOG_INFO ("MaxLimit: " << (int)(m_avgRtt.ToDouble (Time::S) * maxInterestPackets));
// Set max to BDP
- limits->SetMaxLimit (m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
+ limits->SetLimits (maxInterestPackets, m_avgRtt.ToDouble (Time::S));
}
}
diff --git a/model/fw/simple-window-limits.h b/model/fw/simple-window-limits.h
index 69fcd19..7e844ba 100644
--- a/model/fw/simple-window-limits.h
+++ b/model/fw/simple-window-limits.h
@@ -26,11 +26,11 @@
#include "ns3/ndn-pit.h"
#include "ns3/ndn-pit-entry.h"
#include "ns3/simulator.h"
+#include "ns3/string.h"
#include "ns3/ndn-forwarding-strategy.h"
-#include "../../utils/ndn-limits-window.h"
-
+#include "ns3/ndn-limits.h"
namespace ns3 {
namespace ndn {
@@ -63,7 +63,8 @@
virtual void
AddFace (Ptr<Face> face)
{
- Ptr<Limits> limits = CreateObject<LimitsWindow> ();
+ ObjectFactory factory (m_limitType);
+ Ptr<Limits> limits = factory.template Create<Limits> ();
face->AggregateObject (limits);
super::AddFace (face);
@@ -81,6 +82,8 @@
WillSatisfyPendingInterest (Ptr<Face> inFace,
Ptr<pit::Entry> pitEntry);
+private:
+ std::string m_limitType;
};
template<class Parent>
@@ -91,6 +94,11 @@
.SetGroupName ("Ndn")
.template SetParent <super> ()
.template AddConstructor <SimpleWindowLimits> ()
+
+ .template AddAttribute ("Limit", "Limit type to be used (e.g., ns3::ndn::Limits::Window or ns3::ndn::Limits::Rate)",
+ StringValue ("ns3::ndn::Limits::Window"),
+ MakeStringAccessor (&SimpleWindowLimits<Parent>::m_limitType),
+ MakeStringChecker ())
;
return tid;
}
@@ -115,8 +123,10 @@
return false;
}
- if (outFace->template GetObject<LimitsWindow> ()->IsBelowLimit ())
+ Ptr<Limits> faceLimits = outFace->template GetObject<Limits> ();
+ if (faceLimits->IsBelowLimit ())
{
+ faceLimits->BorrowLimit ();
pitEntry->AddOutgoing (outFace);
//transmission
@@ -144,7 +154,8 @@
face != pitEntry->GetOutgoing ().end ();
face ++)
{
- face->m_face->GetObject<LimitsWindow> ()->RemoveOutstanding ();
+ Ptr<Limits> faceLimits = face->m_face->GetObject<Limits> ();
+ faceLimits->ReturnLimit ();
}
super::WillEraseTimedOutPendingInterest (pitEntry);
@@ -162,7 +173,8 @@
face != pitEntry->GetOutgoing ().end ();
face ++)
{
- face->m_face->GetObject<LimitsWindow> ()->RemoveOutstanding ();
+ Ptr<Limits> faceLimits = face->m_face->GetObject<Limits> ();
+ faceLimits->ReturnLimit ();
}
super::WillSatisfyPendingInterest (inFace, pitEntry);
diff --git a/utils/ndn-limits-rate.cc b/utils/ndn-limits-rate.cc
new file mode 100644
index 0000000..215250e
--- /dev/null
+++ b/utils/ndn-limits-rate.cc
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "ndn-limits-rate.h"
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/random-variable.h"
+
+NS_LOG_COMPONENT_DEFINE ("ndn.Limits.Rate");
+
+namespace ns3 {
+namespace ndn {
+
+NS_OBJECT_ENSURE_REGISTERED (LimitsRate);
+
+TypeId
+LimitsRate::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::ndn::Limits::Rate")
+ .SetGroupName ("Ndn")
+ .SetParent <Limits> ()
+ .AddConstructor <LimitsRate> ()
+
+ ;
+ return tid;
+}
+
+void
+LimitsRate::UpdateCurrentLimit (double limit)
+{
+ NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
+
+ m_bucketLeak = std::min (limit, GetMaxRate ());
+ m_bucketMax = m_bucketLeak * GetMaxDelay ();
+}
+
+bool
+LimitsRate::IsBelowLimit ()
+{
+ if (!IsEnabled ()) return true;
+
+ return (m_bucketMax - m_bucket >= 1.0);
+}
+
+void
+LimitsRate::BorrowLimit ()
+{
+ if (!IsEnabled ()) return;
+
+ NS_ASSERT_MSG (m_bucketMax - m_bucket >= 1.0, "Should not be possible, unless we IsBelowLimit was not checked correctly");
+ m_bucket += 1;
+}
+
+void
+LimitsRate::ReturnLimit ()
+{
+ // do nothing
+}
+
+void
+LimitsRate::LeakBucket (double interval)
+{
+ const double leak = m_bucketLeak * interval;
+
+ m_bucket = std::max (0.0, m_bucket - leak);
+}
+
+} // namespace ndn
+} // namespace ns3
diff --git a/utils/ndn-limits-rate.h b/utils/ndn-limits-rate.h
new file mode 100644
index 0000000..4050bb2
--- /dev/null
+++ b/utils/ndn-limits-rate.h
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2011 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef _NDN_LIMITS_RATE_H_
+#define _NDN_LIMITS_RATE_H_
+
+#include "ndn-limits.h"
+
+namespace ns3 {
+namespace ndn {
+
+/**
+ * \ingroup ndn
+ * \brief Structure to manage limits for outstanding interests
+ */
+class LimitsRate :
+ public Limits
+{
+public:
+ typedef Limits super;
+
+ static TypeId
+ GetTypeId ();
+
+ /**
+ * \brief Constructor
+ * \param prefix smart pointer to the prefix for the FIB entry
+ */
+ LimitsRate ()
+ : m_bucketMax (0)
+ , m_bucketLeak (0)
+ , m_bucket (0)
+ { }
+
+ virtual
+ ~LimitsRate () { }
+
+ virtual void
+ SetLimits (double rate, double delay)
+ {
+ super::SetLimits (rate, delay);
+
+ // maximum allowed burst
+ m_bucketMax = GetMaxRate () * GetMaxDelay ();
+
+ // amount of packets allowed every second (leak rate)
+ m_bucketLeak = GetMaxRate ();
+ }
+
+ /**
+ * @brief Check if Interest limit is reached (token bucket is not empty)
+ */
+ virtual bool
+ IsBelowLimit ();
+
+ /**
+ * @brief Get token from the bucket
+ */
+ virtual void
+ BorrowLimit ();
+
+ /**
+ * @brief Does nothing (token bucket leakage is time-dependent only)
+ */
+ virtual void
+ ReturnLimit ();
+
+ /**
+ * @brief Update current leak ratio and maximum burst
+ */
+ virtual void
+ UpdateCurrentLimit (double limit);
+
+ /**
+ */
+ virtual double
+ GetCurrentLimit () const
+ {
+ return m_bucketLeak;
+ }
+
+private:
+ /**
+ * @brief Leak bucket, assuming `interval' seconds between leakages
+ *
+ * @param interval Time interval for leakage. Used to calculate size of the leak
+ */
+ void
+ LeakBucket (double interval);
+
+private:
+ 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)
+};
+
+
+} // namespace ndn
+} // namespace ns3
+
+#endif // _NDN_LIMITS_RATE_H_
diff --git a/utils/ndn-limits-window.cc b/utils/ndn-limits-window.cc
index 6f371b4..95c221b 100644
--- a/utils/ndn-limits-window.cc
+++ b/utils/ndn-limits-window.cc
@@ -21,15 +21,13 @@
#include "ndn-limits-window.h"
#include "ns3/log.h"
-#include "ns3/simulator.h"
-#include "ns3/random-variable.h"
NS_LOG_COMPONENT_DEFINE ("ndn.Limits.Window");
namespace ns3 {
namespace ndn {
-NS_OBJECT_ENSURE_REGISTERED (Limits);
+NS_OBJECT_ENSURE_REGISTERED (LimitsWindow);
TypeId
LimitsWindow::GetTypeId ()
@@ -39,6 +37,10 @@
.SetParent <Limits> ()
.AddConstructor <LimitsWindow> ()
+ .AddTraceSource ("CurMaxLimit",
+ "Current maximum limit",
+ MakeTraceSourceAccessor (&LimitsWindow::m_curMaxLimit))
+
.AddTraceSource ("Outstanding",
"Number of outstanding interests",
MakeTraceSourceAccessor (&LimitsWindow::m_outstanding))
@@ -46,35 +48,36 @@
return tid;
}
+void
+LimitsWindow::UpdateCurrentLimit (double limit)
+{
+ NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
+
+ m_curMaxLimit = std::min (limit, GetMaxRate () * GetMaxDelay ());
+}
+
bool
LimitsWindow::IsBelowLimit ()
{
if (!IsEnabled ()) return true;
- if (m_curMaxLimit - m_outstanding >= 1.0)
- {
- // static UniformVariable acceptanceProbability (0, m_curMaxLimit);
- // double value = acceptanceProbability.GetValue ();
- double value = m_outstanding + 1;
-
- if (m_outstanding < value)
- {
- m_outstanding += 1.0;
- return true;
- }
- else
- return false;
- }
- else
- return false;
+ return (m_curMaxLimit - m_outstanding >= 1.0);
}
void
-LimitsWindow::RemoveOutstanding ()
+LimitsWindow::BorrowLimit ()
{
if (!IsEnabled ()) return;
- NS_LOG_DEBUG (m_outstanding);
+ NS_ASSERT_MSG (m_curMaxLimit - m_outstanding >= 1.0, "Should not be possible, unless we IsBelowLimit was not checked correctly");
+ m_outstanding += 1;
+}
+
+void
+LimitsWindow::ReturnLimit ()
+{
+ if (!IsEnabled ()) return;
+
NS_ASSERT_MSG (m_outstanding >= (uint32_t)1, "Should not be possible, unless we decreasing this number twice somewhere");
m_outstanding -= 1;
}
diff --git a/utils/ndn-limits-window.h b/utils/ndn-limits-window.h
index b1f2208..5b93b6e 100644
--- a/utils/ndn-limits-window.h
+++ b/utils/ndn-limits-window.h
@@ -28,7 +28,7 @@
/**
* \ingroup ndn
- * \brief Structure to manage limits for outstanding interests
+ * \brief Structure to manage limits for outstanding interests (window-based limiting)
*/
class LimitsWindow :
public Limits
@@ -40,40 +40,57 @@
GetTypeId ();
/**
- * \brief Constructor
- * \param prefix smart pointer to the prefix for the FIB entry
+ * @brief Default Constructor
*/
LimitsWindow ()
: m_outstanding (0)
{ }
+ /**
+ * @brief Virtual destructor
+ */
virtual
~LimitsWindow () { }
+ // from ndn::Limits
- // from limits
+ virtual void
+ SetLimits (double rate, double delay)
+ {
+ super::SetLimits (rate, delay);
+
+ m_curMaxLimit = GetMaxRate () * GetMaxDelay ();
+ }
+
+ virtual void
+ UpdateCurrentLimit (double limit);
+
+ virtual double
+ GetCurrentLimit () const
+ {
+ return m_curMaxLimit;
+ }
+
+ /**
+ * @brief Check if current interest window (number of pending interests) if less than maximum
+ */
virtual bool
IsBelowLimit ();
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
-
- // specific to window-based limits
-
/**
- * @brief Remove outstanding interests
+ * @brief Increase current window of outstanding interests
*/
- void
- RemoveOutstanding ();
+ virtual void
+ BorrowLimit ();
- double
- GetOutstanding () const
- {
- return m_outstanding;
- }
+ /**
+ * @brief Decrease current window of outstanding interests
+ */
+ virtual void
+ ReturnLimit ();
-protected:
+private:
+ TracedValue< double > m_curMaxLimit;
TracedValue< double > m_outstanding;
};
diff --git a/utils/ndn-limits.cc b/utils/ndn-limits.cc
index 4e5f48f..338d195 100644
--- a/utils/ndn-limits.cc
+++ b/utils/ndn-limits.cc
@@ -36,21 +36,9 @@
.SetGroupName ("Ndn")
.SetParent <Object> ()
- .AddTraceSource ("CurMaxLimit",
- "Current maximum limit",
- MakeTraceSourceAccessor (&Limits::m_curMaxLimit))
-
;
return tid;
}
-void
-Limits::UpdateCurrentLimit (double limit)
-{
- NS_ASSERT_MSG (limit >= 0.0, "Limit should be greater or equal to zero");
-
- m_curMaxLimit = std::min (limit, m_maxLimit);
-}
-
} // namespace ndn
} // namespace ns3
diff --git a/utils/ndn-limits.h b/utils/ndn-limits.h
index 14aec50..cf5c039 100644
--- a/utils/ndn-limits.h
+++ b/utils/ndn-limits.h
@@ -30,7 +30,7 @@
/**
* \ingroup ndn
- * \brief Structure to manage limits for outstanding interests
+ * \brief Abstract class to manage Interest limits
*/
class Limits :
public Object
@@ -39,31 +39,48 @@
static TypeId
GetTypeId ();
+ /**
+ * @brief Default constructor
+ */
Limits ()
- : m_maxLimit (-1)
- , m_curMaxLimit (0)
+ : m_maxRate (-1)
+ , m_maxDelay (1.0)
{ }
+ /**
+ * @brief Virtual destructor
+ */
virtual
~Limits () {}
/**
* @brief Set limit for the number of outstanding interests
+ * @param rate Maximum rate that needs to be enforced
+ * @param delay Maximum delay for BDP product for window-based limits
*/
virtual void
- SetMaxLimit (double max)
+ SetLimits (double rate, double delay)
{
- m_maxLimit = max;
- m_curMaxLimit = max;
+ m_maxRate = rate;
+ m_maxDelay = delay;
}
/**
- * @brief Get limit for the number of outstanding interests
+ * @brief Get maximum rate that needs to be enforced
*/
virtual double
- GetMaxLimit () const
+ GetMaxRate () const
{
- return m_maxLimit;
+ return m_maxRate;
+ }
+
+ /**
+ * @brief Get maximum delay for BDP product for window-based limits
+ */
+ virtual double
+ GetMaxDelay () const
+ {
+ return m_maxDelay;
}
/**
@@ -72,37 +89,56 @@
virtual inline bool
IsEnabled () const
{
- return m_maxLimit > 0.0;
+ return m_maxRate > 0.0;
}
/**
* @brief Update a current value of the limit
+ * @param limit Value of current limit.
*
- * If limit is larger than previously set value of maximum limit (SetMaxLimit), then the current limit will
- * be limited to that maximum value
+ * Note that interpretation of this value may be different in different ndn::Limit realizations
+ *
+ * All realizations will try to guarantee that if limit is larger than previously set value of maximum limit,
+ * then the current limit will be limited to that maximum value
*/
- void
- UpdateCurrentLimit (double limit);
+ virtual void
+ UpdateCurrentLimit (double limit) = 0;
- double
- GetCurrentLimit () const
- {
- return m_curMaxLimit;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////
-
/**
- * @brief Check if new interest can be send out, if yes, number of outstanding will be increased
+ * @brief Get value of the current limit
+ *
+ * Note that interpretation of this value may be different in different ndn::Limit realizations
+ */
+ virtual double
+ GetCurrentLimit () const = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Realization-specific method called to check availability of the limit
*/
virtual bool
IsBelowLimit () = 0;
+
+ /**
+ * @brief "Borrow" limit
+ *
+ * IsBelowLimit **must** be true, otherwise assert fail
+ */
+ virtual void
+ BorrowLimit () = 0;
+
+ /**
+ * @brief "Return" limit
+ */
+ virtual void
+ ReturnLimit () = 0;
-protected:
- double m_maxLimit;
- TracedValue< double > m_curMaxLimit;
+private:
+ double m_maxRate;
+ double m_maxDelay;
};