blob: 098883796d8eb04eb8554223b2d01a35c0e2d1ad [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD 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
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
#define NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
#include "fw/rtt-estimator.hpp"
#include "fw/strategy-info.hpp"
#include "table/measurements-accessor.hpp"
namespace nfd {
namespace fw {
namespace asf {
class RttStats
{
public:
typedef time::duration<double, boost::micro> Rtt;
RttStats();
void
addRttMeasurement(RttEstimator::Duration& durationRtt);
void
recordTimeout()
{
m_rtt = RTT_TIMEOUT;
}
Rtt
getRtt() const
{
return m_rtt;
}
Rtt
getSrtt() const
{
return m_srtt;
}
RttEstimator::Duration
computeRto() const
{
return m_rttEstimator.computeRto();
}
private:
static Rtt
computeSrtt(Rtt previousSrtt, Rtt currentRtt);
public:
static const Rtt RTT_TIMEOUT;
static const Rtt RTT_NO_MEASUREMENT;
private:
Rtt m_srtt;
Rtt m_rtt;
RttEstimator m_rttEstimator;
static const double ALPHA;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/** \brief Strategy information for each face in a namespace
*/
class FaceInfo
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
FaceInfo();
~FaceInfo();
void
setTimeoutEvent(const scheduler::EventId& id, const Name& interestName);
void
setMeasurementExpirationEventId(const scheduler::EventId& id)
{
m_measurementExpirationId = id;
}
const scheduler::EventId&
getMeasurementExpirationEventId()
{
return m_measurementExpirationId;
}
void
cancelTimeoutEvent(const Name& prefix);
bool
isTimeoutScheduled() const
{
return m_isTimeoutScheduled;
}
void
recordRtt(const shared_ptr<pit::Entry>& pitEntry, const Face& inFace);
void
recordTimeout(const Name& interestName);
bool
isTimeout() const
{
return getRtt() == RttStats::RTT_TIMEOUT;
}
RttEstimator::Duration
computeRto() const
{
return m_rttStats.computeRto();
}
RttStats::Rtt
getRtt() const
{
return m_rttStats.getRtt();
}
RttStats::Rtt
getSrtt() const
{
return m_rttStats.getSrtt();
}
bool
hasSrttMeasurement() const
{
return getSrtt() != RttStats::RTT_NO_MEASUREMENT;
}
private:
void
cancelTimeoutEvent();
bool
doesNameMatchLastInterest(const Name& name);
private:
RttStats m_rttStats;
Name m_lastInterestName;
// Timeout associated with measurement
scheduler::EventId m_measurementExpirationId;
// RTO associated with Interest
scheduler::EventId m_timeoutEventId;
bool m_isTimeoutScheduled;
};
typedef std::unordered_map<face::FaceId, FaceInfo> FaceInfoTable;
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/** \brief stores stategy information about each face in this namespace
*/
class NamespaceInfo : public StrategyInfo
{
public:
NamespaceInfo();
static constexpr int
getTypeId()
{
return 1030;
}
FaceInfo&
getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face);
FaceInfo*
getFaceInfo(const fib::Entry& fibEntry, const Face& face);
void
expireFaceInfo(nfd::face::FaceId faceId);
void
extendFaceInfoLifetime(FaceInfo& info, const Face& face);
FaceInfo&
get(nfd::face::FaceId faceId)
{
return m_fit.at(faceId);
}
FaceInfoTable::iterator
find(nfd::face::FaceId faceId)
{
return m_fit.find(faceId);
}
FaceInfoTable::iterator
end()
{
return m_fit.end();
}
const FaceInfoTable::iterator
insert(nfd::face::FaceId faceId)
{
const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
return pair.first;
}
bool
isProbingDue() const
{
return m_isProbingDue;
}
void
setIsProbingDue(bool isProbingDue)
{
m_isProbingDue = isProbingDue;
}
bool
isFirstProbeScheduled() const
{
return m_hasFirstProbeBeenScheduled;
}
void
setHasFirstProbeBeenScheduled(bool hasBeenScheduled)
{
m_hasFirstProbeBeenScheduled = hasBeenScheduled;
}
private:
FaceInfoTable m_fit;
bool m_isProbingDue;
bool m_hasFirstProbeBeenScheduled;
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/** \brief Helper class to retrieve and create strategy measurements
*/
class AsfMeasurements : noncopyable
{
public:
explicit
AsfMeasurements(MeasurementsAccessor& measurements);
FaceInfo*
getFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face);
FaceInfo&
getOrCreateFaceInfo(const fib::Entry& fibEntry, const Interest& interest, const Face& face);
NamespaceInfo*
getNamespaceInfo(const Name& prefix);
NamespaceInfo&
getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const Interest& interest);
private:
void
extendLifetime(measurements::Entry& me);
public:
static constexpr time::microseconds MEASUREMENTS_LIFETIME = time::seconds(300);
private:
MeasurementsAccessor& m_measurements;
};
} // namespace asf
} // namespace fw
} // namespace nfd
#endif // NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP