fix: qsccp compile error
This commit is contained in:
1 parent
507c60422f
commit
785cfde06d
9 files changed
+44
-705
No files matched your search
@@ -78,7 +78,7 @@ namespace ndn
|
||||
po::options_description visibleOptDesc("Options");
|
||||
visibleOptDesc.add_options()("help,h", "print this message and exit")("version,V", "display version and exit");
|
||||
visibleOptDesc.add_options()(
|
||||
"startSeq", po::value<uint32_t>(&options.startSeq)->default_value(0), "start sequence number");
|
||||
"startSeq", po::value<uint64_t>(&options.startSeq)->default_value(0), "start sequence number");
|
||||
visibleOptDesc.add_options()(
|
||||
"seqMax", po::value<int64_t>(&options.seqMax)->default_value(-1), "maximum sequence number");
|
||||
visibleOptDesc.add_options()(
|
||||
|
||||
@@ -16,19 +16,15 @@ namespace ndn
|
||||
m_scheduler(m_face.getIoService()),
|
||||
m_stopFlag(false),
|
||||
m_recvBytes(0),
|
||||
m_traceTimes(0),
|
||||
m_firstTime(true)
|
||||
m_traceTimes(0)
|
||||
{
|
||||
if (m_options.seqMax < 0)
|
||||
{
|
||||
m_seqMax = std::numeric_limits<uint32_t>::max();
|
||||
m_seqMax = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
m_scheduler.schedule(
|
||||
time::milliseconds(500),
|
||||
bind(&Consumer::traceRate, this));
|
||||
m_scheduler.schedule(
|
||||
time::milliseconds(50),
|
||||
bind(&Consumer::checkRetxTimeout, this));
|
||||
}
|
||||
|
||||
void Consumer::traceRate()
|
||||
@@ -56,39 +52,9 @@ namespace ndn
|
||||
void Consumer::stop()
|
||||
{
|
||||
m_nextInterestEvent.cancel();
|
||||
m_retxEvent.cancel();
|
||||
m_stopFlag = true;
|
||||
}
|
||||
|
||||
void Consumer::checkRetxTimeout()
|
||||
{
|
||||
auto now = time::steady_clock::now();
|
||||
|
||||
auto rto = m_rtt.RetransmitTimeout();
|
||||
|
||||
std::cout << "RTO: " << m_rtt.duration_to_second_double(rto) << std::endl;
|
||||
|
||||
while (!m_seqTimeouts.empty())
|
||||
{
|
||||
SeqTimeoutsContainer::index<i_timestamp>::type::iterator entry =
|
||||
m_seqTimeouts.get<i_timestamp>().begin();
|
||||
if (entry->time + rto <= now) // timeout expired?
|
||||
{
|
||||
// std::cout << "RTOTIMEOUT: " << entry->seq << std::endl;
|
||||
uint32_t seqNo = entry->seq;
|
||||
if (m_seqRetxCounts.find(seqNo) != m_seqRetxCounts.end())
|
||||
{
|
||||
m_seqTimeouts.get<i_timestamp>().erase(entry);
|
||||
onTimeout(seqNo);
|
||||
}
|
||||
}
|
||||
else
|
||||
break; // nothing else to do. All later packets need not be retransmitted
|
||||
}
|
||||
|
||||
m_retxEvent = m_scheduler.schedule(time::milliseconds(50), bind(&Consumer::checkRetxTimeout, this));
|
||||
}
|
||||
|
||||
void Consumer::sendPacket()
|
||||
{
|
||||
uint32_t seq = std::numeric_limits<uint32_t>::max(); // invalid
|
||||
@@ -114,7 +80,6 @@ namespace ndn
|
||||
Interest interest(makeInterestName(seq));
|
||||
interest.setCanBePrefix(false);
|
||||
interest.setMustBeFresh(true);
|
||||
interest.setServiceClass(5);
|
||||
interest.setInterestLifetime(m_options.lifetime);
|
||||
|
||||
auto now = time::steady_clock::now();
|
||||
@@ -123,47 +88,41 @@ namespace ndn
|
||||
bind(&Consumer::onNack, this, _2, seq, now),
|
||||
bind(&Consumer::onTimeout, this, seq));
|
||||
|
||||
willSendInterest(seq);
|
||||
++m_nSent;
|
||||
++m_nOutstanding;
|
||||
|
||||
scheduleNextPacket();
|
||||
|
||||
// if (m_nSent < m_seqMax)
|
||||
// {
|
||||
// m_nextInterestEvent = m_scheduler.schedule(m_options.interval, [this]
|
||||
// { scheduleNextInterest(); });
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// finish();
|
||||
// }
|
||||
}
|
||||
|
||||
void Consumer::onTimeout(uint32_t seq)
|
||||
void Consumer::onTimeout(uint64_t seq)
|
||||
{
|
||||
std::cout << "onTimeout: " << seq << std::endl;
|
||||
afterTimeout(seq);
|
||||
|
||||
m_rtt.IncreaseMultiplier(); // Double the next RTO
|
||||
m_rtt.SentSeq(seq, 1); // make sure to disable RTT calculation for this sample
|
||||
m_retxSeqs.insert(seq);
|
||||
|
||||
afterTimeout(seq);
|
||||
scheduleNextPacket();
|
||||
// finish();
|
||||
}
|
||||
|
||||
void Consumer::onData(const Data &data, uint32_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
void Consumer::onData(const Data &data, uint64_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
{
|
||||
auto now = time::steady_clock::now();
|
||||
std::cout << "cc:delay:<" << (now - m_startTime).count() << "," << seq << "," << (now - sendTime).count() << ">" << std::endl;
|
||||
|
||||
afterData(seq, now - sendTime);
|
||||
if (m_seqRetxCounts.find(seq) != m_seqRetxCounts.end())
|
||||
{
|
||||
m_recvBytes += data.wireEncode().size();
|
||||
m_seqRetxCounts.erase(seq);
|
||||
}
|
||||
|
||||
m_seqFullDelay.erase(seq);
|
||||
m_seqLastDelay.erase(seq);
|
||||
|
||||
m_seqTimeouts.erase(seq);
|
||||
m_retxSeqs.erase(seq);
|
||||
|
||||
m_rtt.AckSeq(seq);
|
||||
m_recvBytes += data.wireEncode().size();
|
||||
// finish();
|
||||
}
|
||||
|
||||
void Consumer::onNack(const lp::Nack &nack, uint32_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
void Consumer::onNack(const lp::Nack &nack, uint64_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
{
|
||||
std::cout << "onNack: " << nack.getReason() << std::endl;
|
||||
afterNack(seq, time::steady_clock::now() - sendTime, nack.getHeader());
|
||||
@@ -171,24 +130,11 @@ namespace ndn
|
||||
// finish();
|
||||
}
|
||||
|
||||
Name Consumer::makeInterestName(uint32_t seq)
|
||||
Name Consumer::makeInterestName(uint64_t seq)
|
||||
{
|
||||
return Name(m_options.prefix).appendNumber(seq);
|
||||
}
|
||||
|
||||
void Consumer::willSendInterest(uint32_t seq)
|
||||
{
|
||||
++m_nSent;
|
||||
m_seqTimeouts.insert(SeqTimeout(seq, time::steady_clock::now()));
|
||||
m_seqFullDelay.insert(SeqTimeout(seq, time::steady_clock::now()));
|
||||
|
||||
m_seqLastDelay.erase(seq);
|
||||
m_seqLastDelay.insert(SeqTimeout(seq, time::steady_clock::now()));
|
||||
|
||||
m_seqRetxCounts[seq]++;
|
||||
|
||||
m_rtt.SentSeq(seq, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,4 @@
|
||||
#ifndef NDN_CONSUMER_H
|
||||
#define NDN_CONSUMER_H
|
||||
#include "core/common.hpp"
|
||||
#include "ndn-rtt-mean-deviation.hpp"
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
|
||||
namespace ndn
|
||||
{
|
||||
@@ -18,41 +8,22 @@ namespace ndn
|
||||
{
|
||||
typedef time::duration<double, time::milliseconds::period> Rtt;
|
||||
|
||||
enum CcAlgorithm
|
||||
{
|
||||
AIMD,
|
||||
BIC,
|
||||
CUBIC
|
||||
};
|
||||
|
||||
class Options
|
||||
{
|
||||
public:
|
||||
Name prefix;
|
||||
uint32_t startSeq; // Initial sequence number
|
||||
uint64_t startSeq; // Initial sequence number
|
||||
time::milliseconds lifetime; // Lifetime of Interest
|
||||
int64_t seqMax; // Max sequence number
|
||||
uint32_t tos; // Type of Service
|
||||
uint32_t dsz; // Data size
|
||||
int32_t reqNum; // Request Data Num(-1 indicator infinity)
|
||||
uint32_t initialSendRate; // Initial Send Rate
|
||||
int32_t fixedRate; // Fixed Send Rate
|
||||
int32_t fixedRate; // Fixed Send Rate
|
||||
int32_t timingStop; // Timing Stop(-1 indicator infinity)
|
||||
int32_t delayGreedy; // Start greedy after the specified time (ms)
|
||||
int32_t greedyRate; // Greedy Send Rate(-1 indicator no greedy)
|
||||
uint32_t delayStart; // Delay Start(ms)
|
||||
|
||||
std::string schema; // QSCCP or PCON
|
||||
uint32_t initialWindowSize = 1; // Initial Window Size
|
||||
bool setInitialWindowOnTimeout = false; // Set initial window size on timeout
|
||||
|
||||
CcAlgorithm ccAlgorithm = AIMD; // Specify which window adaptation algorithm to use (AIMD, BIC, or CUBIC)
|
||||
double beta = 0.5; // TCP Multiplicative Decrease factor
|
||||
double cubicBeta = 0.8; // TCP CUBIC Multiplicative Decrease factor
|
||||
double addRttSuppress = 0.5; // Minimum number of RTTs (1 + this factor) between window decreases
|
||||
bool reactToCongestionMarks = true; // React to congestion marks (ECN, CE)
|
||||
bool useCwa = true; // Use Congestion Window Acceleration (CWA) algorithm
|
||||
bool useCubicFastConv = true; // Use CUBIC fast convergence algorithm
|
||||
};
|
||||
|
||||
class Consumer : noncopyable
|
||||
@@ -60,13 +31,13 @@ namespace ndn
|
||||
public:
|
||||
Consumer(Face &face, const Options &options);
|
||||
|
||||
virtual ~Consumer() {}
|
||||
virtual ~Consumer(){}
|
||||
|
||||
signal::Signal<Consumer, uint32_t, Rtt> afterData;
|
||||
signal::Signal<Consumer, uint64_t, Rtt> afterData;
|
||||
|
||||
signal::Signal<Consumer, uint32_t, Rtt, lp::NackHeader> afterNack;
|
||||
signal::Signal<Consumer, uint64_t, Rtt, lp::NackHeader> afterNack;
|
||||
|
||||
signal::Signal<Consumer, uint32_t> afterTimeout;
|
||||
signal::Signal<Consumer, uint64_t> afterTimeout;
|
||||
|
||||
signal::Signal<Consumer> afterFinish;
|
||||
|
||||
@@ -75,34 +46,26 @@ namespace ndn
|
||||
void stop();
|
||||
|
||||
public:
|
||||
Name makeInterestName(uint32_t seq);
|
||||
Name makeInterestName(uint64_t seq);
|
||||
|
||||
virtual void sendPacket();
|
||||
|
||||
virtual void onTimeout(uint32_t seq);
|
||||
virtual void onTimeout(uint64_t seq);
|
||||
|
||||
virtual void onData(const Data &data, uint32_t seq, const time::steady_clock::TimePoint &sendTime);
|
||||
virtual void onData(const Data& data, uint64_t seq, const time::steady_clock::TimePoint &sendTime);
|
||||
|
||||
virtual void onNack(const lp::Nack &nack, uint32_t seq, const time::steady_clock::TimePoint &sendTime);
|
||||
|
||||
virtual void willSendInterest(uint32_t seq);
|
||||
virtual void onNack(const lp::Nack &nack, uint64_t seq, const time::steady_clock::TimePoint &sendTime);
|
||||
|
||||
protected:
|
||||
virtual void scheduleNextPacket() = 0;
|
||||
|
||||
/**
|
||||
* \brief Checks if the packet need to be retransmitted becuase of retransmission timer expiration
|
||||
*/
|
||||
void
|
||||
checkRetxTimeout();
|
||||
|
||||
private:
|
||||
void traceRate();
|
||||
|
||||
protected:
|
||||
const Options &m_options;
|
||||
int m_nSent;
|
||||
uint32_t m_nextSeq;
|
||||
uint64_t m_nextSeq;
|
||||
int64_t m_seqMax;
|
||||
int m_nOutstanding;
|
||||
Face &m_face;
|
||||
@@ -112,9 +75,6 @@ namespace ndn
|
||||
uint64_t m_recvBytes;
|
||||
uint64_t m_traceTimes;
|
||||
time::steady_clock::TimePoint m_startTime;
|
||||
scheduler::EventId m_nextInterestEvent;
|
||||
bool m_firstTime = true;
|
||||
|
||||
/// @cond include_hidden
|
||||
/**
|
||||
* \struct This struct contains sequence numbers of packets to be retransmitted
|
||||
@@ -122,65 +82,9 @@ namespace ndn
|
||||
struct RetxSeqsContainer : public std::set<uint32_t>
|
||||
{
|
||||
};
|
||||
|
||||
RetxSeqsContainer m_retxSeqs; ///< \brief ordered set of sequence numbers to be retransmitted
|
||||
|
||||
RttMeanDeviation m_rtt;
|
||||
scheduler::EventId m_retxEvent;
|
||||
// RttEstimator m_rtt;
|
||||
/**
|
||||
* \struct This struct contains a pair of packet sequence number and its timeout
|
||||
*/
|
||||
struct SeqTimeout
|
||||
{
|
||||
SeqTimeout(uint32_t _seq, time::steady_clock::TimePoint _time)
|
||||
: seq(_seq), time(_time)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t seq;
|
||||
time::steady_clock::TimePoint time;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
/// @cond include_hidden
|
||||
class i_seq
|
||||
{
|
||||
};
|
||||
class i_timestamp
|
||||
{
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
/// @cond include_hidden
|
||||
/**
|
||||
* \struct This struct contains a multi-index for the set of SeqTimeout structs
|
||||
*/
|
||||
struct SeqTimeoutsContainer
|
||||
: public boost::multi_index::
|
||||
multi_index_container<SeqTimeout,
|
||||
boost::multi_index::
|
||||
indexed_by<boost::multi_index::
|
||||
ordered_unique<boost::multi_index::tag<i_seq>,
|
||||
boost::multi_index::
|
||||
member<SeqTimeout, uint32_t,
|
||||
&SeqTimeout::seq>>,
|
||||
boost::multi_index::
|
||||
ordered_non_unique<boost::multi_index::
|
||||
tag<i_timestamp>,
|
||||
boost::multi_index::
|
||||
member<SeqTimeout, time::steady_clock::TimePoint,
|
||||
&SeqTimeout::time>>>>
|
||||
{
|
||||
};
|
||||
|
||||
SeqTimeoutsContainer m_seqTimeouts; ///< \brief multi-index for the set of SeqTimeout structs
|
||||
|
||||
SeqTimeoutsContainer m_seqLastDelay;
|
||||
SeqTimeoutsContainer m_seqFullDelay;
|
||||
std::map<uint32_t, uint32_t> m_seqRetxCounts;
|
||||
scheduler::EventId m_nextInterestEvent;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* RTT_ESTIMATOR_H */
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
#include "ndn-rtt-estimator.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace ndn
|
||||
{
|
||||
namespace cc
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
void
|
||||
RttEstimator::SetMinRto(time::steady_clock::duration minRto)
|
||||
{
|
||||
m_minRto = minRto;
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttEstimator::GetMinRto(void) const
|
||||
{
|
||||
return m_minRto;
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::SetMaxRto(time::steady_clock::duration maxRto)
|
||||
{
|
||||
m_maxRto = maxRto;
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttEstimator::GetMaxRto(void) const
|
||||
{
|
||||
return m_maxRto;
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::SetCurrentEstimate(time::steady_clock::duration estimate)
|
||||
{
|
||||
m_currentEstimatedRtt = estimate;
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttEstimator::GetCurrentEstimate(void) const
|
||||
{
|
||||
return m_currentEstimatedRtt;
|
||||
}
|
||||
|
||||
// RttHistory methods
|
||||
RttHistory::RttHistory(uint32_t s, uint32_t c, time::steady_clock::TimePoint t)
|
||||
: seq(s), count(c), time(t), retx(false)
|
||||
{
|
||||
}
|
||||
|
||||
RttHistory::RttHistory(const RttHistory &h)
|
||||
: seq(h.seq), count(h.count), time(h.time), retx(h.retx)
|
||||
{
|
||||
}
|
||||
|
||||
// Base class methods
|
||||
RttEstimator::RttEstimator()
|
||||
: m_next(1),
|
||||
m_maxMultiplier(64),
|
||||
m_initialEstimatedRtt(second_double_to_duration(1)), // 1 seconds
|
||||
m_minRto(second_double_to_duration(0.2)), // 0.2 seconds
|
||||
m_maxRto(second_double_to_duration(200)), // 200 seconds
|
||||
m_nSamples(0),
|
||||
m_multiplier(1),
|
||||
m_history()
|
||||
{
|
||||
m_currentEstimatedRtt = m_initialEstimatedRtt;
|
||||
}
|
||||
|
||||
RttEstimator::RttEstimator(const RttEstimator &c)
|
||||
: m_next(c.m_next), m_maxMultiplier(c.m_maxMultiplier), m_initialEstimatedRtt(c.m_initialEstimatedRtt), m_currentEstimatedRtt(c.m_currentEstimatedRtt), m_minRto(c.m_minRto), m_maxRto(c.m_maxRto), m_nSamples(c.m_nSamples), m_multiplier(c.m_multiplier), m_history(c.m_history)
|
||||
{
|
||||
}
|
||||
|
||||
RttEstimator::~RttEstimator()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::SentSeq(uint32_t seq, uint32_t size)
|
||||
{
|
||||
// Note that a particular sequence has been sent
|
||||
if (seq == m_next)
|
||||
{ // This is the next expected one, just log at end
|
||||
m_history.push_back(RttHistory(seq, size, time::steady_clock::now()));
|
||||
m_next = seq + uint32_t(size); // Update next expected
|
||||
}
|
||||
else
|
||||
{ // This is a retransmit, find in list and mark as re-tx
|
||||
for (RttHistory_t::iterator i = m_history.begin(); i != m_history.end(); ++i)
|
||||
{
|
||||
if ((seq >= i->seq) && (seq < (i->seq + uint32_t(i->count))))
|
||||
{ // Found it
|
||||
i->retx = true;
|
||||
// One final test..be sure this re-tx does not extend "next"
|
||||
if ((seq + uint32_t(size)) > m_next)
|
||||
{
|
||||
m_next = seq + uint32_t(size);
|
||||
i->count = ((seq + uint32_t(size)) - i->seq); // And update count in hist
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttEstimator::AckSeq(uint32_t ackSeq)
|
||||
{
|
||||
// An ack has been received, calculate rtt and log this measurement
|
||||
// Note we use a linear search (O(n)) for this since for the common
|
||||
// case the ack'ed packet will be at the head of the list
|
||||
time::steady_clock::duration m = time::steady_clock::duration::zero();
|
||||
if (m_history.size() == 0)
|
||||
{
|
||||
return (m); // No pending history, just exit
|
||||
}
|
||||
RttHistory &h = m_history.front();
|
||||
if (!h.retx && ackSeq >= (h.seq + uint32_t(h.count)))
|
||||
{ // Ok to use this sample
|
||||
m = time::steady_clock::now() - h.time; // Elapsed time::nanoseconds
|
||||
Measurement(m); // Log the measurement
|
||||
ResetMultiplier(); // Reset multiplier on valid measurement
|
||||
}
|
||||
// Now delete all ack history with seq <= ack
|
||||
while (m_history.size() > 0)
|
||||
{
|
||||
RttHistory &h = m_history.front();
|
||||
if ((h.seq + uint32_t(h.count)) > ackSeq)
|
||||
break; // Done removing
|
||||
m_history.pop_front(); // Remove
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::ClearSent()
|
||||
{
|
||||
// Clear all history entries
|
||||
m_next = 1;
|
||||
m_history.clear();
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::IncreaseMultiplier()
|
||||
{
|
||||
m_multiplier = (m_multiplier * 2 < m_maxMultiplier) ? m_multiplier * 2 : m_maxMultiplier;
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::ResetMultiplier()
|
||||
{
|
||||
m_multiplier = 1;
|
||||
}
|
||||
|
||||
void
|
||||
RttEstimator::Reset()
|
||||
{
|
||||
// Reset to initial state
|
||||
m_next = 1;
|
||||
m_currentEstimatedRtt = m_initialEstimatedRtt;
|
||||
m_history.clear(); // Remove all info from the history
|
||||
m_nSamples = 0;
|
||||
ResetMultiplier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
#ifndef NDN_RTT_ESTIMATOR_H
|
||||
#define NDN_RTT_ESTIMATOR_H
|
||||
#include "core/common.hpp"
|
||||
#include <deque>
|
||||
|
||||
namespace ndn
|
||||
{
|
||||
namespace cc
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
/**
|
||||
* \ingroup ndn-apps
|
||||
*
|
||||
* \brief Helper class to store RTT measurements
|
||||
*/
|
||||
class RttHistory
|
||||
{
|
||||
public:
|
||||
RttHistory(uint32_t seq, uint32_t size, time::steady_clock::TimePoint time);
|
||||
RttHistory(const RttHistory &h); // Copy constructor
|
||||
public:
|
||||
uint32_t seq; // First sequence number in packet sent
|
||||
uint32_t count; // Number of bytes sent
|
||||
time::steady_clock::TimePoint time; // Time this one was sent
|
||||
bool retx; // True if this has been retransmitted
|
||||
};
|
||||
|
||||
typedef std::deque<RttHistory> RttHistory_t;
|
||||
|
||||
/**
|
||||
* \ingroup tcp
|
||||
*
|
||||
* \brief Base class for all RTT Estimators
|
||||
*/
|
||||
class RttEstimator
|
||||
{
|
||||
public:
|
||||
RttEstimator();
|
||||
RttEstimator(const RttEstimator &);
|
||||
|
||||
virtual ~RttEstimator();
|
||||
|
||||
/**
|
||||
* \brief Note that a particular sequence has been sent
|
||||
* \param seq the packet sequence number.
|
||||
* \param size the packet size.
|
||||
*/
|
||||
virtual void
|
||||
SentSeq(uint32_t seq, uint32_t size);
|
||||
|
||||
/**
|
||||
* \brief Note that a particular ack sequence has been received
|
||||
* \param ackSeq the ack sequence number.
|
||||
* \return The measured RTT for this ack.
|
||||
*/
|
||||
virtual time::steady_clock::duration
|
||||
AckSeq(uint32_t ackSeq);
|
||||
|
||||
/**
|
||||
* \brief Clear all history entries
|
||||
*/
|
||||
virtual void
|
||||
ClearSent();
|
||||
|
||||
/**
|
||||
* \brief Add a new measurement to the estimator. Pure virtual function.
|
||||
* \param t the new RTT measure.
|
||||
*/
|
||||
virtual void
|
||||
Measurement(time::steady_clock::duration t) = 0;
|
||||
|
||||
/**
|
||||
* \brief Returns the estimated RTO. Pure virtual function.
|
||||
* \return the estimated RTO.
|
||||
*/
|
||||
virtual time::steady_clock::duration
|
||||
RetransmitTimeout() = 0;
|
||||
|
||||
/**
|
||||
* \brief Increase the estimation multiplier up to MaxMultiplier.
|
||||
*/
|
||||
virtual void
|
||||
IncreaseMultiplier();
|
||||
|
||||
/**
|
||||
* \brief Resets the estimation multiplier to 1.
|
||||
*/
|
||||
virtual void
|
||||
ResetMultiplier();
|
||||
|
||||
/**
|
||||
* \brief Resets the estimation to its initial state.
|
||||
*/
|
||||
virtual void
|
||||
Reset();
|
||||
|
||||
/**
|
||||
* \brief Sets the Minimum RTO.
|
||||
* \param minRto The minimum RTO returned by the estimator.
|
||||
*/
|
||||
void
|
||||
SetMinRto(time::steady_clock::duration minRto);
|
||||
|
||||
/**
|
||||
* \brief Get the Minimum RTO.
|
||||
* \return The minimum RTO returned by the estimator.
|
||||
*/
|
||||
time::steady_clock::duration
|
||||
GetMinRto(void) const;
|
||||
|
||||
/**
|
||||
* \brief Sets the Maximum RTO.
|
||||
* \param minRto The maximum RTO returned by the estimator.
|
||||
*/
|
||||
void
|
||||
SetMaxRto(time::steady_clock::duration maxRto);
|
||||
|
||||
/**
|
||||
* \brief Get the Maximum RTO.
|
||||
* \return The maximum RTO returned by the estimator.
|
||||
*/
|
||||
time::steady_clock::duration
|
||||
GetMaxRto(void) const;
|
||||
|
||||
/**
|
||||
* \brief Sets the current RTT estimate (forcefully).
|
||||
* \param estimate The current RTT estimate.
|
||||
*/
|
||||
void
|
||||
SetCurrentEstimate(time::steady_clock::duration estimate);
|
||||
|
||||
/**
|
||||
* \brief gets the current RTT estimate.
|
||||
* \return The current RTT estimate.
|
||||
*/
|
||||
time::steady_clock::duration
|
||||
GetCurrentEstimate(void) const;
|
||||
|
||||
double
|
||||
duration_to_second_double(time::steady_clock::duration d) {
|
||||
return d.count() / 1000000000.0;
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
second_double_to_duration(double d) {
|
||||
return time::steady_clock::duration(static_cast<long long>(d * 1000000000.0));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_next; // Next expected sequence to be sent
|
||||
uint16_t m_maxMultiplier;
|
||||
time::steady_clock::duration m_initialEstimatedRtt;
|
||||
|
||||
protected:
|
||||
time::steady_clock::duration m_currentEstimatedRtt; // Current estimate
|
||||
time::steady_clock::duration m_minRto; // minimum value of the timeout
|
||||
time::steady_clock::duration m_maxRto; // maximum value of the timeout
|
||||
uint32_t m_nSamples; // Number of samples
|
||||
uint16_t m_multiplier; // RTO Multiplier
|
||||
RttHistory_t m_history; // List of sent packet
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* RTT_ESTIMATOR_H */
|
||||
@@ -1,119 +0,0 @@
|
||||
#include "ndn-rtt-mean-deviation.hpp"
|
||||
|
||||
namespace ndn
|
||||
{
|
||||
namespace cc
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
RttMeanDeviation::RttMeanDeviation()
|
||||
: m_gain(0.125),
|
||||
m_gain2(0.25),
|
||||
m_variance(0)
|
||||
{
|
||||
}
|
||||
|
||||
RttMeanDeviation::RttMeanDeviation(const RttMeanDeviation &c)
|
||||
: RttEstimator(c), m_gain(c.m_gain), m_gain2(c.m_gain2), m_variance(c.m_variance)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RttMeanDeviation::Measurement(time::steady_clock::duration m)
|
||||
{
|
||||
if (m_nSamples)
|
||||
{ // Not first
|
||||
time::steady_clock::duration err(m - m_currentEstimatedRtt);
|
||||
double gErr = duration_to_second_double(err) * m_gain;
|
||||
|
||||
m_currentEstimatedRtt += second_double_to_duration(gErr);
|
||||
|
||||
auto abs_err = err > time::steady_clock::duration::zero() ? err : -err;
|
||||
|
||||
time::steady_clock::duration difference = abs_err - m_variance;
|
||||
m_variance += second_double_to_duration(m_gain2 * duration_to_second_double(difference));
|
||||
}
|
||||
else
|
||||
{ // First sample
|
||||
m_currentEstimatedRtt = m; // Set estimate to current
|
||||
// variance = sample / 2; // And variance to current / 2
|
||||
// m_variance = m; // try this why????
|
||||
m_variance = second_double_to_duration(duration_to_second_double(m) / 2);
|
||||
}
|
||||
m_nSamples++;
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttMeanDeviation::RetransmitTimeout()
|
||||
{
|
||||
// std::cout << "RTO -> m_currentEstimatedRtt:" << duration_to_second_double(m_currentEstimatedRtt) << ", m_variance:" << duration_to_second_double(m_variance) << std::endl;
|
||||
double retval = std::min(
|
||||
duration_to_second_double(m_maxRto),
|
||||
std::max(
|
||||
m_multiplier * duration_to_second_double(m_minRto),
|
||||
m_multiplier * (duration_to_second_double(m_currentEstimatedRtt) + 4 * duration_to_second_double(m_variance))));
|
||||
return second_double_to_duration(retval);
|
||||
}
|
||||
|
||||
void
|
||||
RttMeanDeviation::Reset()
|
||||
{
|
||||
// Reset to initial state
|
||||
m_variance = time::steady_clock::duration::zero();
|
||||
RttEstimator::Reset();
|
||||
}
|
||||
|
||||
void
|
||||
RttMeanDeviation::Gain(double g)
|
||||
{
|
||||
m_gain = g;
|
||||
}
|
||||
|
||||
void
|
||||
RttMeanDeviation::SentSeq(uint32_t seq, uint32_t size)
|
||||
{
|
||||
RttHistory_t::iterator i;
|
||||
for (i = m_history.begin(); i != m_history.end(); ++i)
|
||||
{
|
||||
if (seq == i->seq)
|
||||
{ // Found it
|
||||
i->retx = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that a particular sequence has been sent
|
||||
if (i == m_history.end())
|
||||
m_history.push_back(RttHistory(seq, size, time::steady_clock::now()));
|
||||
}
|
||||
|
||||
time::steady_clock::duration
|
||||
RttMeanDeviation::AckSeq(uint32_t ackSeq)
|
||||
{
|
||||
// An ack has been received, calculate rtt and log this measurement
|
||||
// Note we use a linear search (O(n)) for this since for the common
|
||||
// case the ack'ed packet will be at the head of the list
|
||||
auto m = time::steady_clock::duration::zero();
|
||||
if (m_history.size() == 0)
|
||||
return (m); // No pending history, just exit
|
||||
|
||||
for (RttHistory_t::iterator i = m_history.begin(); i != m_history.end(); ++i)
|
||||
{
|
||||
if (ackSeq == i->seq)
|
||||
{ // Found it
|
||||
if (!i->retx)
|
||||
{
|
||||
m = time::steady_clock::now() - i->time; // Elapsed time
|
||||
Measurement(m); // Log the measurement
|
||||
ResetMultiplier(); // Reset multiplier on valid measurement
|
||||
}
|
||||
m_history.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef NDN_RTT_MEAN_DEVIATION_H
|
||||
#define NDN_RTT_MEAN_DEVIATION_H
|
||||
|
||||
#include "ndn-rtt-estimator.hpp"
|
||||
|
||||
#endif /* NDN_RTT_MEAN_DEVIATION_H */
|
||||
namespace ndn
|
||||
{
|
||||
namespace cc
|
||||
{
|
||||
namespace client
|
||||
{
|
||||
|
||||
/**
|
||||
* \ingroup ndn-apps
|
||||
*
|
||||
* \brief The modified version of "Mean--Deviation" RTT estimator, as discussed by Van Jacobson that
|
||||
*better suits NDN communication model
|
||||
*
|
||||
* This class implements the "Mean--Deviation" RTT estimator, as discussed
|
||||
* by Van Jacobson and Michael J. Karels, in
|
||||
* "Congestion Avoidance and Control", SIGCOMM 88, Appendix A
|
||||
*
|
||||
*/
|
||||
class RttMeanDeviation : public RttEstimator
|
||||
{
|
||||
public:
|
||||
RttMeanDeviation();
|
||||
|
||||
RttMeanDeviation(const RttMeanDeviation &);
|
||||
|
||||
void
|
||||
SentSeq(uint32_t seq, uint32_t size);
|
||||
|
||||
time::steady_clock::duration
|
||||
AckSeq(uint32_t ackSeq);
|
||||
|
||||
void
|
||||
Measurement(time::steady_clock::duration measure);
|
||||
|
||||
time::steady_clock::duration
|
||||
RetransmitTimeout();
|
||||
|
||||
void
|
||||
Reset();
|
||||
|
||||
void
|
||||
Gain(double g);
|
||||
|
||||
private:
|
||||
double m_gain; // Filter gain
|
||||
double m_gain2; // Filter gain
|
||||
time::steady_clock::duration m_variance; // Current variance
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace ndn
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t QsccpConsumer::updateRate(uint32_t newRate)
|
||||
uint64_t QsccpConsumer::updateRate(uint64_t newRate)
|
||||
{
|
||||
if (this->fixedRate > 0)
|
||||
{
|
||||
@@ -46,7 +46,7 @@ namespace ndn
|
||||
this->sendRate = this->greedyRate;
|
||||
}
|
||||
|
||||
void QsccpConsumer::onData(const Data &data, uint32_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
void QsccpConsumer::onData(const Data &data, uint64_t seq, const time::steady_clock::TimePoint &sendTime)
|
||||
{
|
||||
// print tags
|
||||
auto targetRate = data.getTargetRate();
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace ndn
|
||||
|
||||
void sendPacket() override;
|
||||
|
||||
void onData(const Data& data, uint32_t seq, const time::steady_clock::TimePoint &sendTime) override;
|
||||
void onData(const Data& data, uint64_t seq, const time::steady_clock::TimePoint &sendTime) override;
|
||||
|
||||
protected:
|
||||
void scheduleNextPacket() override;
|
||||
@@ -21,20 +21,20 @@ namespace ndn
|
||||
void startGreedy();
|
||||
|
||||
private:
|
||||
uint32_t updateRate(uint32_t newRate);
|
||||
uint64_t updateRate(uint64_t newRate);
|
||||
|
||||
private:
|
||||
bool m_firstTime = true;
|
||||
// private attribute here
|
||||
uint32_t tos;
|
||||
uint32_t delayStart;
|
||||
uint32_t dsz;
|
||||
uint32_t sendRate;
|
||||
uint64_t tos;
|
||||
uint64_t delayStart;
|
||||
uint64_t dsz;
|
||||
uint64_t sendRate;
|
||||
int32_t fixedRate;
|
||||
int32_t timingStop;
|
||||
int32_t delayGreedy;
|
||||
int32_t greedyRate;
|
||||
uint32_t m_recvDataNum;
|
||||
uint64_t m_recvDataNum;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user