catchunks: simplify internal options handling
Change-Id: I537a281f6c996c2544c145ab9cc01a54272c8efa
This commit is contained in:
1 parent
32c0df2e9e
commit
97a33b200d
19 files changed
+169
-303
No files matched your search
@@ -136,11 +136,7 @@ BOOST_AUTO_TEST_CASE(OutputDataUnordered)
|
||||
class PipelineInterestsDummy : public PipelineInterests
|
||||
{
|
||||
public:
|
||||
PipelineInterestsDummy(Face& face)
|
||||
: PipelineInterests(face)
|
||||
, isPipelineRunning(false)
|
||||
{
|
||||
}
|
||||
using PipelineInterests::PipelineInterests;
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -155,18 +151,19 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
bool isPipelineRunning;
|
||||
bool isPipelineRunning = false;
|
||||
};
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(RunBasic, UnitTestTimeFixture)
|
||||
{
|
||||
boost::asio::io_service io;
|
||||
util::DummyClientFace face(io);
|
||||
Options options;
|
||||
Consumer consumer(security::v2::getAcceptAllValidator());
|
||||
|
||||
Name prefix = Name("/ndn/chunks/test").appendVersion(1);
|
||||
auto discover = make_unique<DiscoverVersion>(prefix, face, Options());
|
||||
auto pipeline = make_unique<PipelineInterestsDummy>(face);
|
||||
auto discover = make_unique<DiscoverVersion>(face, prefix, options);
|
||||
auto pipeline = make_unique<PipelineInterestsDummy>(face, options);
|
||||
auto pipelinePtr = pipeline.get();
|
||||
|
||||
consumer.run(std::move(discover), std::move(pipeline));
|
||||
|
||||
@@ -41,28 +41,18 @@ class DiscoverVersionFixture : public UnitTestTimeFixture,
|
||||
public IdentityManagementFixture
|
||||
{
|
||||
public:
|
||||
DiscoverVersionFixture()
|
||||
: face(io)
|
||||
, name("/ndn/chunks/test")
|
||||
, isDiscoveryFinished(false)
|
||||
, version(1449227841747)
|
||||
{
|
||||
opt.interestLifetime = ndn::DEFAULT_INTEREST_LIFETIME;
|
||||
opt.maxRetriesOnTimeoutOrNack = 15;
|
||||
opt.isVerbose = false;
|
||||
}
|
||||
|
||||
void
|
||||
run(const Name& prefix)
|
||||
{
|
||||
BOOST_REQUIRE(!prefix.empty());
|
||||
discover = make_unique<DiscoverVersion>(prefix, face, opt);
|
||||
|
||||
discover = make_unique<DiscoverVersion>(face, prefix, opt);
|
||||
discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
|
||||
isDiscoveryFinished = true;
|
||||
BOOST_REQUIRE(!versionedName.empty() && versionedName[-1].isVersion());
|
||||
discoveredVersion = versionedName[-1].toVersion();
|
||||
isDiscoveryFinished = true;
|
||||
});
|
||||
discover->onDiscoveryFailure.connect([this] (const std::string& reason) {
|
||||
discover->onDiscoveryFailure.connect([this] (const std::string&) {
|
||||
isDiscoveryFinished = true;
|
||||
});
|
||||
|
||||
@@ -72,13 +62,13 @@ public:
|
||||
|
||||
protected:
|
||||
boost::asio::io_service io;
|
||||
util::DummyClientFace face;
|
||||
Name name;
|
||||
util::DummyClientFace face{io};
|
||||
Name name = "/ndn/chunks/test";
|
||||
Options opt;
|
||||
unique_ptr<DiscoverVersion> discover;
|
||||
optional<uint64_t> discoveredVersion;
|
||||
bool isDiscoveryFinished;
|
||||
uint64_t version;
|
||||
Options opt;
|
||||
bool isDiscoveryFinished = false;
|
||||
uint64_t version = 1449227841747;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(Chunks)
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "tools/chunks/catchunks/pipeline-interests-aimd.hpp"
|
||||
#include "tools/chunks/catchunks/options.hpp"
|
||||
|
||||
#include "pipeline-interests-fixture.hpp"
|
||||
|
||||
@@ -40,9 +39,9 @@ class PipelineInterestAimdFixture : public PipelineInterestsFixture
|
||||
{
|
||||
public:
|
||||
PipelineInterestAimdFixture()
|
||||
: opt(makePipelineOptions())
|
||||
, rttEstimator(makeRttEstimatorOptions())
|
||||
: rttEstimator(makeRttEstimatorOptions())
|
||||
{
|
||||
opt.isQuiet = true;
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
@@ -55,22 +54,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static PipelineInterestsAdaptive::Options
|
||||
makePipelineOptions()
|
||||
{
|
||||
PipelineInterestsAdaptive::Options pipelineOptions;
|
||||
pipelineOptions.isQuiet = true;
|
||||
pipelineOptions.isVerbose = false;
|
||||
pipelineOptions.disableCwa = false;
|
||||
pipelineOptions.ignoreCongMarks = false;
|
||||
pipelineOptions.resetCwndToInit = false;
|
||||
pipelineOptions.initCwnd = 1.0;
|
||||
pipelineOptions.aiStep = 1.0;
|
||||
pipelineOptions.mdCoef = 0.5;
|
||||
pipelineOptions.initSsthresh = std::numeric_limits<int>::max();
|
||||
return pipelineOptions;
|
||||
}
|
||||
|
||||
static shared_ptr<RttEstimatorWithStats::Options>
|
||||
makeRttEstimatorOptions()
|
||||
{
|
||||
@@ -86,7 +69,7 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
PipelineInterestsAdaptive::Options opt;
|
||||
Options opt;
|
||||
RttEstimatorWithStats rttEstimator;
|
||||
PipelineInterestsAdaptive* pipeline;
|
||||
static constexpr double MARGIN = 0.001;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include "tools/chunks/catchunks/pipeline-interests-cubic.hpp"
|
||||
#include "tools/chunks/catchunks/options.hpp"
|
||||
|
||||
#include "pipeline-interests-fixture.hpp"
|
||||
|
||||
@@ -40,9 +39,9 @@ class PipelineInterestCubicFixture : public PipelineInterestsFixture
|
||||
{
|
||||
public:
|
||||
PipelineInterestCubicFixture()
|
||||
: opt(makePipelineOptions())
|
||||
, rttEstimator(makeRttEstimatorOptions())
|
||||
: rttEstimator(makeRttEstimatorOptions())
|
||||
{
|
||||
opt.isQuiet = true;
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
@@ -55,24 +54,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static PipelineInterestsCubic::Options
|
||||
makePipelineOptions()
|
||||
{
|
||||
PipelineInterestsCubic::Options pipelineOptions;
|
||||
pipelineOptions.isQuiet = true;
|
||||
pipelineOptions.isVerbose = false;
|
||||
pipelineOptions.disableCwa = false;
|
||||
pipelineOptions.ignoreCongMarks = false;
|
||||
pipelineOptions.resetCwndToInit = false;
|
||||
pipelineOptions.initCwnd = 1.0;
|
||||
pipelineOptions.aiStep = 1.0;
|
||||
pipelineOptions.mdCoef = 0.5;
|
||||
pipelineOptions.initSsthresh = std::numeric_limits<int>::max();
|
||||
pipelineOptions.cubicBeta = 0.7;
|
||||
pipelineOptions.enableFastConv = false;
|
||||
return pipelineOptions;
|
||||
}
|
||||
|
||||
static shared_ptr<RttEstimatorWithStats::Options>
|
||||
makeRttEstimatorOptions()
|
||||
{
|
||||
@@ -88,7 +69,7 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
PipelineInterestsCubic::Options opt;
|
||||
Options opt;
|
||||
RttEstimatorWithStats rttEstimator;
|
||||
PipelineInterestsCubic* pipeline;
|
||||
static constexpr double MARGIN = 0.001;
|
||||
|
||||
@@ -37,8 +37,11 @@ class PipelineInterestFixedFixture : public PipelineInterestsFixture
|
||||
{
|
||||
public:
|
||||
PipelineInterestFixedFixture()
|
||||
: opt(makeOptions())
|
||||
{
|
||||
opt.interestLifetime = 1_s;
|
||||
opt.maxRetriesOnTimeoutOrNack = 3;
|
||||
opt.isQuiet = true;
|
||||
opt.maxPipelineSize = 5;
|
||||
createPipeline();
|
||||
}
|
||||
|
||||
@@ -50,21 +53,8 @@ public:
|
||||
setPipeline(std::move(pline));
|
||||
}
|
||||
|
||||
private:
|
||||
static PipelineInterestsFixed::Options
|
||||
makeOptions()
|
||||
{
|
||||
PipelineInterestsFixed::Options options;
|
||||
options.isQuiet = true;
|
||||
options.isVerbose = false;
|
||||
options.interestLifetime = time::seconds(1);
|
||||
options.maxRetriesOnTimeoutOrNack = 3;
|
||||
options.maxPipelineSize = 5;
|
||||
return options;
|
||||
}
|
||||
|
||||
protected:
|
||||
PipelineInterestsFixed::Options opt;
|
||||
Options opt;
|
||||
PipelineInterestsFixed* pipeline;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
DiscoverVersion::DiscoverVersion(const Name& prefix, Face& face, const Options& options)
|
||||
: chunks::Options(options)
|
||||
DiscoverVersion::DiscoverVersion(Face& face, const Name& prefix, const Options& options)
|
||||
: m_face(face)
|
||||
, m_prefix(prefix)
|
||||
, m_face(face)
|
||||
, m_options(options)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -50,24 +50,24 @@ DiscoverVersion::run()
|
||||
}
|
||||
|
||||
Interest interest = MetadataObject::makeDiscoveryInterest(m_prefix)
|
||||
.setInterestLifetime(interestLifetime);
|
||||
.setInterestLifetime(m_options.interestLifetime);
|
||||
|
||||
m_fetcher = DataFetcher::fetch(m_face, interest,
|
||||
maxRetriesOnTimeoutOrNack, maxRetriesOnTimeoutOrNack,
|
||||
m_options.maxRetriesOnTimeoutOrNack, m_options.maxRetriesOnTimeoutOrNack,
|
||||
bind(&DiscoverVersion::handleData, this, _1, _2),
|
||||
[this] (const Interest& interest, const std::string& reason) {
|
||||
[this] (const Interest&, const std::string& reason) {
|
||||
onDiscoveryFailure(reason);
|
||||
},
|
||||
[this] (const Interest& interest, const std::string& reason) {
|
||||
[this] (const Interest&, const std::string& reason) {
|
||||
onDiscoveryFailure(reason);
|
||||
},
|
||||
isVerbose);
|
||||
m_options.isVerbose);
|
||||
}
|
||||
|
||||
void
|
||||
DiscoverVersion::handleData(const Interest& interest, const Data& data)
|
||||
{
|
||||
if (isVerbose)
|
||||
if (m_options.isVerbose)
|
||||
std::cerr << "Data: " << data << std::endl;
|
||||
|
||||
// make a metadata object from received metadata packet
|
||||
@@ -85,7 +85,7 @@ DiscoverVersion::handleData(const Interest& interest, const Data& data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVerbose) {
|
||||
if (m_options.isVerbose) {
|
||||
std::cerr << "Discovered Data version: " << mobject.getVersionedName()[-1] << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
|
||||
#define NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
|
||||
|
||||
#include "core/common.hpp"
|
||||
#include "options.hpp"
|
||||
|
||||
namespace ndn {
|
||||
@@ -38,12 +37,12 @@ namespace chunks {
|
||||
class DataFetcher;
|
||||
|
||||
/**
|
||||
* @brief Base class of services for discovering the latest Data version
|
||||
* @brief Service for discovering the latest Data version.
|
||||
*
|
||||
* DiscoverVersion's user is notified once after identifying the latest retrievable version or
|
||||
* on failure to find any Data version.
|
||||
*/
|
||||
class DiscoverVersion : virtual protected Options, noncopyable
|
||||
class DiscoverVersion
|
||||
{
|
||||
public: // signals
|
||||
/**
|
||||
@@ -57,10 +56,7 @@ public: // signals
|
||||
signal::Signal<DiscoverVersion, std::string> onDiscoveryFailure;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create a DiscoverVersion service
|
||||
*/
|
||||
DiscoverVersion(const Name& prefix, Face& face, const Options& options);
|
||||
DiscoverVersion(Face& face, const Name& prefix, const Options& options);
|
||||
|
||||
/**
|
||||
* @brief identify the latest Data version published.
|
||||
@@ -73,8 +69,9 @@ private:
|
||||
handleData(const Interest& interest, const Data& data);
|
||||
|
||||
private:
|
||||
const Name m_prefix;
|
||||
Face& m_face;
|
||||
const Name m_prefix;
|
||||
const Options& m_options;
|
||||
shared_ptr<DataFetcher> m_fetcher;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "consumer.hpp"
|
||||
#include "discover-version.hpp"
|
||||
#include "options.hpp"
|
||||
#include "pipeline-interests-aimd.hpp"
|
||||
#include "pipeline-interests-cubic.hpp"
|
||||
#include "pipeline-interests-fixed.hpp"
|
||||
@@ -48,18 +47,12 @@ static int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
std::string programName(argv[0]);
|
||||
Options options;
|
||||
std::string pipelineType("cubic");
|
||||
size_t maxPipelineSize(1);
|
||||
std::string uri;
|
||||
|
||||
// congestion control parameters
|
||||
bool disableCwa(false), resetCwndToInit(false),
|
||||
ignoreCongMarks(false), enableFastConv(false);
|
||||
int initCwnd(1), initSsthresh(std::numeric_limits<int>::max()), k(8);
|
||||
double aiStep(1.0), rtoAlpha(0.125), rtoBeta(0.25), aimdBeta(0.5), cubicBeta(0.7);
|
||||
Options options;
|
||||
std::string uri, pipelineType("cubic"), cwndPath, rttPath;
|
||||
time::milliseconds::rep minRto(200), maxRto(60000);
|
||||
std::string cwndPath, rttPath;
|
||||
double rtoAlpha(0.125), rtoBeta(0.25);
|
||||
int rtoK(8);
|
||||
|
||||
namespace po = boost::program_options;
|
||||
po::options_description basicDesc("Basic Options");
|
||||
@@ -79,33 +72,33 @@ main(int argc, char* argv[])
|
||||
|
||||
po::options_description fixedPipeDesc("Fixed pipeline options");
|
||||
fixedPipeDesc.add_options()
|
||||
("pipeline-size,s", po::value<size_t>(&maxPipelineSize)->default_value(maxPipelineSize),
|
||||
("pipeline-size,s", po::value<size_t>(&options.maxPipelineSize)->default_value(options.maxPipelineSize),
|
||||
"size of the Interest pipeline")
|
||||
;
|
||||
|
||||
po::options_description adaptivePipeDesc("Adaptive pipeline options (AIMD & CUBIC)");
|
||||
adaptivePipeDesc.add_options()
|
||||
("ignore-marks", po::bool_switch(&ignoreCongMarks),
|
||||
("ignore-marks", po::bool_switch(&options.ignoreCongMarks),
|
||||
"do not decrease the window after receiving a congestion mark")
|
||||
("disable-cwa", po::bool_switch(&disableCwa),
|
||||
("disable-cwa", po::bool_switch(&options.disableCwa),
|
||||
"disable Conservative Window Adaptation, i.e., reduce the window on "
|
||||
"each timeout or congestion mark instead of at most once per RTT")
|
||||
("reset-cwnd-to-init", po::bool_switch(&resetCwndToInit),
|
||||
("reset-cwnd-to-init", po::bool_switch(&options.resetCwndToInit),
|
||||
"after a timeout or congestion mark, reset the window "
|
||||
"to the initial value instead of resetting to ssthresh")
|
||||
("init-cwnd", po::value<int>(&initCwnd)->default_value(initCwnd),
|
||||
("init-cwnd", po::value<double>(&options.initCwnd)->default_value(options.initCwnd),
|
||||
"initial congestion window in segments")
|
||||
("init-ssthresh", po::value<int>(&initSsthresh),
|
||||
("init-ssthresh", po::value<double>(&options.initSsthresh),
|
||||
"initial slow start threshold in segments (defaults to infinity)")
|
||||
("aimd-step", po::value<double>(&aiStep)->default_value(aiStep),
|
||||
("aimd-step", po::value<double>(&options.aiStep)->default_value(options.aiStep),
|
||||
"additive-increase step")
|
||||
("aimd-beta", po::value<double>(&aimdBeta)->default_value(aimdBeta),
|
||||
("aimd-beta", po::value<double>(&options.mdCoef)->default_value(options.mdCoef),
|
||||
"multiplicative decrease factor (AIMD)")
|
||||
("rto-alpha", po::value<double>(&rtoAlpha)->default_value(rtoAlpha),
|
||||
"alpha value for RTO calculation")
|
||||
("rto-beta", po::value<double>(&rtoBeta)->default_value(rtoBeta),
|
||||
"beta value for RTO calculation")
|
||||
("rto-k", po::value<int>(&k)->default_value(k),
|
||||
("rto-k", po::value<int>(&rtoK)->default_value(rtoK),
|
||||
"k value for RTO calculation")
|
||||
("min-rto", po::value<time::milliseconds::rep>(&minRto)->default_value(minRto),
|
||||
"minimum RTO value, in milliseconds")
|
||||
@@ -117,9 +110,8 @@ main(int argc, char* argv[])
|
||||
|
||||
po::options_description cubicPipeDesc("CUBIC pipeline options");
|
||||
cubicPipeDesc.add_options()
|
||||
("fast-conv", po::bool_switch(&enableFastConv), "enable cubic fast convergence")
|
||||
("cubic-beta", po::value<double>(&cubicBeta),
|
||||
"window decrease factor for CUBIC (defaults to 0.7)")
|
||||
("cubic-beta", po::value<double>(&options.cubicBeta), "window decrease factor (defaults to 0.7)")
|
||||
("fast-conv", po::bool_switch(&options.enableFastConv), "enable fast convergence")
|
||||
;
|
||||
|
||||
po::options_description visibleDesc;
|
||||
@@ -169,7 +161,7 @@ main(int argc, char* argv[])
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (maxPipelineSize < 1 || maxPipelineSize > 1024) {
|
||||
if (options.maxPipelineSize < 1 || options.maxPipelineSize > 1024) {
|
||||
std::cerr << "ERROR: pipeline size must be between 1 and 1024" << std::endl;
|
||||
return 2;
|
||||
}
|
||||
@@ -192,7 +184,7 @@ main(int argc, char* argv[])
|
||||
|
||||
try {
|
||||
Face face;
|
||||
auto discover = make_unique<DiscoverVersion>(Name(uri), face, options);
|
||||
auto discover = make_unique<DiscoverVersion>(face, Name(uri), options);
|
||||
unique_ptr<PipelineInterests> pipeline;
|
||||
unique_ptr<StatisticsCollector> statsCollector;
|
||||
unique_ptr<RttEstimatorWithStats> rttEstimator;
|
||||
@@ -200,15 +192,13 @@ main(int argc, char* argv[])
|
||||
std::ofstream statsFileRtt;
|
||||
|
||||
if (pipelineType == "fixed") {
|
||||
PipelineInterestsFixed::Options optionsPipeline(options);
|
||||
optionsPipeline.maxPipelineSize = maxPipelineSize;
|
||||
pipeline = make_unique<PipelineInterestsFixed>(face, optionsPipeline);
|
||||
pipeline = make_unique<PipelineInterestsFixed>(face, options);
|
||||
}
|
||||
else if (pipelineType == "aimd" || pipelineType == "cubic") {
|
||||
auto optionsRttEst = make_shared<RttEstimatorWithStats::Options>();
|
||||
optionsRttEst->alpha = rtoAlpha;
|
||||
optionsRttEst->beta = rtoBeta;
|
||||
optionsRttEst->k = k;
|
||||
optionsRttEst->k = rtoK;
|
||||
optionsRttEst->initialRto = 1_s;
|
||||
optionsRttEst->minRto = time::milliseconds(minRto);
|
||||
optionsRttEst->maxRto = time::milliseconds(maxRto);
|
||||
@@ -226,24 +216,12 @@ main(int argc, char* argv[])
|
||||
}
|
||||
rttEstimator = make_unique<RttEstimatorWithStats>(std::move(optionsRttEst));
|
||||
|
||||
PipelineInterestsAdaptive::Options optionsPipeline(options);
|
||||
optionsPipeline.disableCwa = disableCwa;
|
||||
optionsPipeline.resetCwndToInit = resetCwndToInit;
|
||||
optionsPipeline.initCwnd = initCwnd;
|
||||
optionsPipeline.initSsthresh = initSsthresh;
|
||||
optionsPipeline.aiStep = aiStep;
|
||||
optionsPipeline.mdCoef = aimdBeta;
|
||||
optionsPipeline.ignoreCongMarks = ignoreCongMarks;
|
||||
|
||||
unique_ptr<PipelineInterestsAdaptive> adaptivePipeline;
|
||||
if (pipelineType == "aimd") {
|
||||
adaptivePipeline = make_unique<PipelineInterestsAimd>(face, *rttEstimator, optionsPipeline);
|
||||
adaptivePipeline = make_unique<PipelineInterestsAimd>(face, *rttEstimator, options);
|
||||
}
|
||||
else {
|
||||
PipelineInterestsCubic::Options optionsCubic(optionsPipeline);
|
||||
optionsCubic.enableFastConv = enableFastConv;
|
||||
optionsCubic.cubicBeta = cubicBeta;
|
||||
adaptivePipeline = make_unique<PipelineInterestsCubic>(face, *rttEstimator, optionsCubic);
|
||||
adaptivePipeline = make_unique<PipelineInterestsCubic>(face, *rttEstimator, options);
|
||||
}
|
||||
|
||||
if (!cwndPath.empty() || !rttPath.empty()) {
|
||||
|
||||
@@ -27,19 +27,38 @@
|
||||
#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
|
||||
#define NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
|
||||
|
||||
#include <ndn-cxx/interest.hpp>
|
||||
#include <ndn-cxx/util/time.hpp>
|
||||
#include "core/common.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
struct Options
|
||||
struct Options : noncopyable
|
||||
{
|
||||
// Common options
|
||||
time::milliseconds interestLifetime = DEFAULT_INTEREST_LIFETIME;
|
||||
int maxRetriesOnTimeoutOrNack = 15;
|
||||
bool mustBeFresh = false;
|
||||
bool isQuiet = false;
|
||||
bool isVerbose = false;
|
||||
|
||||
// Fixed pipeline options
|
||||
size_t maxPipelineSize = 1;
|
||||
|
||||
// Adaptive pipeline common options
|
||||
double initCwnd = 1.0; ///< initial congestion window size
|
||||
double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
|
||||
time::milliseconds rtoCheckInterval{10}; ///< interval for checking retransmission timer
|
||||
bool ignoreCongMarks = false; ///< disable window decrease after receiving congestion mark
|
||||
bool disableCwa = false; ///< disable conservative window adaptation
|
||||
|
||||
// AIMD pipeline options
|
||||
double aiStep = 1.0; ///< AIMD additive increase step (in segments)
|
||||
double mdCoef = 0.5; ///< AIMD multiplicative decrease factor
|
||||
bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
|
||||
|
||||
// Cubic pipeline options
|
||||
double cubicBeta = 0.7; ///< cubic multiplicative decrease factor
|
||||
bool enableFastConv = false; ///< use cubic fast convergence
|
||||
};
|
||||
|
||||
} // namespace chunks
|
||||
|
||||
@@ -39,9 +39,8 @@ constexpr double PipelineInterestsAdaptive::MIN_SSTHRESH;
|
||||
|
||||
PipelineInterestsAdaptive::PipelineInterestsAdaptive(Face& face,
|
||||
RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options)
|
||||
: PipelineInterests(face)
|
||||
, m_options(options)
|
||||
const Options& opts)
|
||||
: PipelineInterests(face, opts)
|
||||
, m_cwnd(m_options.initCwnd)
|
||||
, m_ssthresh(m_options.initSsthresh)
|
||||
, m_rttEstimator(rttEstimator)
|
||||
@@ -416,6 +415,22 @@ PipelineInterestsAdaptive::cancelInFlightSegmentsGreaterThan(uint64_t segNo)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PipelineInterestsAdaptive::printOptions() const
|
||||
{
|
||||
PipelineInterests::printOptions();
|
||||
std::cerr
|
||||
<< "\tInitial congestion window size = " << m_options.initCwnd << "\n"
|
||||
<< "\tInitial slow start threshold = " << m_options.initSsthresh << "\n"
|
||||
<< "\tAdditive increase step = " << m_options.aiStep << "\n"
|
||||
<< "\tMultiplicative decrease factor = " << m_options.mdCoef << "\n"
|
||||
<< "\tRTO check interval = " << m_options.rtoCheckInterval << "\n"
|
||||
<< "\tReact to congestion marks = " << (m_options.ignoreCongMarks ? "no" : "yes") << "\n"
|
||||
<< "\tConservative window adaptation = " << (m_options.disableCwa ? "no" : "yes") << "\n"
|
||||
<< "\tResetting window to " << (m_options.resetCwndToInit ?
|
||||
"initial value" : "ssthresh") << " upon loss event\n";
|
||||
}
|
||||
|
||||
void
|
||||
PipelineInterestsAdaptive::printSummary() const
|
||||
{
|
||||
@@ -456,22 +471,5 @@ operator<<(std::ostream& os, SegmentState state)
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const PipelineInterestsAdaptiveOptions& options)
|
||||
{
|
||||
os << "Adaptive pipeline parameters:\n"
|
||||
<< "\tInitial congestion window size = " << options.initCwnd << "\n"
|
||||
<< "\tInitial slow start threshold = " << options.initSsthresh << "\n"
|
||||
<< "\tAdditive increase step = " << options.aiStep << "\n"
|
||||
<< "\tMultiplicative decrease factor = " << options.mdCoef << "\n"
|
||||
<< "\tRTO check interval = " << options.rtoCheckInterval << "\n"
|
||||
<< "\tMax retries on timeout or Nack = " << (options.maxRetriesOnTimeoutOrNack == DataFetcher::MAX_RETRIES_INFINITE ?
|
||||
"infinite" : to_string(options.maxRetriesOnTimeoutOrNack)) << "\n"
|
||||
<< "\tReact to congestion marks = " << (options.ignoreCongMarks ? "no" : "yes") << "\n"
|
||||
<< "\tConservative window adaptation = " << (options.disableCwa ? "no" : "yes") << "\n"
|
||||
<< "\tResetting window to " << (options.resetCwndToInit ? "initCwnd" : "ssthresh") << " upon loss event\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace chunks
|
||||
} // namespace ndn
|
||||
@@ -29,7 +29,6 @@
|
||||
#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_ADAPTIVE_HPP
|
||||
#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_ADAPTIVE_HPP
|
||||
|
||||
#include "options.hpp"
|
||||
#include "pipeline-interests.hpp"
|
||||
|
||||
#include <ndn-cxx/util/rtt-estimator.hpp>
|
||||
@@ -42,29 +41,6 @@ namespace chunks {
|
||||
|
||||
using util::RttEstimatorWithStats;
|
||||
|
||||
class PipelineInterestsAdaptiveOptions : public Options
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
PipelineInterestsAdaptiveOptions(const Options& options = Options())
|
||||
: Options(options)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
double initCwnd = 1.0; ///< initial congestion window size
|
||||
double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
|
||||
double aiStep = 1.0; ///< additive increase step (in segments)
|
||||
double mdCoef = 0.5; ///< multiplicative decrease coefficient
|
||||
time::milliseconds rtoCheckInterval{10}; ///< interval for checking retransmission timer
|
||||
bool disableCwa = false; ///< disable Conservative Window Adaptation
|
||||
bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
|
||||
bool ignoreCongMarks = false; ///< disable window decrease after congestion marks
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const PipelineInterestsAdaptiveOptions& options);
|
||||
|
||||
/**
|
||||
* @brief indicates the state of the segment
|
||||
*/
|
||||
@@ -101,9 +77,6 @@ struct SegmentInfo
|
||||
*/
|
||||
class PipelineInterestsAdaptive : public PipelineInterests
|
||||
{
|
||||
public:
|
||||
using Options = PipelineInterestsAdaptiveOptions;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
@@ -111,8 +84,7 @@ public:
|
||||
* Configures the pipelining service without specifying the retrieval namespace. After this
|
||||
* configuration the method run must be called to start the Pipeline.
|
||||
*/
|
||||
PipelineInterestsAdaptive(Face& face, RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options = Options());
|
||||
PipelineInterestsAdaptive(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
|
||||
|
||||
~PipelineInterestsAdaptive() override;
|
||||
|
||||
@@ -141,6 +113,9 @@ public:
|
||||
protected:
|
||||
DECLARE_SIGNAL_EMIT(afterCwndChange)
|
||||
|
||||
void
|
||||
printOptions() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Increase congestion window.
|
||||
@@ -214,7 +189,6 @@ PUBLIC_WITH_TESTS_ELSE_PRIVATE:
|
||||
|
||||
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
|
||||
static constexpr double MIN_SSTHRESH = 2.0;
|
||||
const Options m_options;
|
||||
|
||||
double m_cwnd; ///< current congestion window size (in segments)
|
||||
double m_ssthresh; ///< current slow start threshold
|
||||
|
||||
@@ -34,11 +34,11 @@ namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
PipelineInterestsAimd::PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options)
|
||||
: PipelineInterestsAdaptive(face, rttEstimator, options)
|
||||
const Options& opts)
|
||||
: PipelineInterestsAdaptive(face, rttEstimator, opts)
|
||||
{
|
||||
if (options.isVerbose) {
|
||||
std::cerr << options;
|
||||
if (m_options.isVerbose) {
|
||||
printOptions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace chunks {
|
||||
class PipelineInterestsAimd final : public PipelineInterestsAdaptive
|
||||
{
|
||||
public:
|
||||
PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options = Options());
|
||||
PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
|
||||
|
||||
private:
|
||||
void
|
||||
|
||||
@@ -33,13 +33,14 @@ namespace chunks {
|
||||
constexpr double CUBIC_C = 0.4;
|
||||
|
||||
PipelineInterestsCubic::PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options)
|
||||
: PipelineInterestsAdaptive(face, rttEstimator, options)
|
||||
, m_cubicOptions(options)
|
||||
const Options& opts)
|
||||
: PipelineInterestsAdaptive(face, rttEstimator, opts)
|
||||
, m_lastDecrease(time::steady_clock::now())
|
||||
{
|
||||
if (options.isVerbose) {
|
||||
std::cerr << options;
|
||||
if (m_options.isVerbose) {
|
||||
printOptions();
|
||||
std::cerr << "\tCubic beta = " << m_options.cubicBeta << "\n"
|
||||
<< "\tFast convergence = " << (m_options.enableFastConv ? "yes" : "no") << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ PipelineInterestsCubic::increaseWindow()
|
||||
// 2. Time it takes to increase the window to m_wmax = the cwnd right before the last
|
||||
// window decrease.
|
||||
// K = cubic_root(wmax*(1-beta_cubic)/C) (Eq. 2)
|
||||
const double k = std::cbrt(m_wmax * (1 - m_cubicOptions.cubicBeta) / CUBIC_C);
|
||||
const double k = std::cbrt(m_wmax * (1 - m_options.cubicBeta) / CUBIC_C);
|
||||
|
||||
// 3. Target: W_cubic(t) = C*(t-K)^3 + wmax (Eq. 1)
|
||||
const double wCubic = CUBIC_C * std::pow(t - k, 3) + m_wmax;
|
||||
@@ -93,9 +94,9 @@ PipelineInterestsCubic::decreaseWindow()
|
||||
// before it updates wmax for the current congestion event.
|
||||
|
||||
// Current wmax < last_wmax
|
||||
if (m_cubicOptions.enableFastConv && m_cwnd < m_lastWmax) {
|
||||
if (m_options.enableFastConv && m_cwnd < m_lastWmax) {
|
||||
m_lastWmax = m_cwnd;
|
||||
m_wmax = m_cwnd * (1.0 + m_cubicOptions.cubicBeta) / 2.0;
|
||||
m_wmax = m_cwnd * (1.0 + m_options.cubicBeta) / 2.0;
|
||||
}
|
||||
else {
|
||||
// Save old cwnd as wmax
|
||||
@@ -103,22 +104,12 @@ PipelineInterestsCubic::decreaseWindow()
|
||||
m_wmax = m_cwnd;
|
||||
}
|
||||
|
||||
m_ssthresh = std::max(m_options.initCwnd, m_cwnd * m_cubicOptions.cubicBeta);
|
||||
m_ssthresh = std::max(m_options.initCwnd, m_cwnd * m_options.cubicBeta);
|
||||
m_cwnd = m_ssthresh;
|
||||
m_lastDecrease = time::steady_clock::now();
|
||||
|
||||
emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const PipelineInterestsCubicOptions& options)
|
||||
{
|
||||
os << static_cast<const PipelineInterestsAdaptiveOptions&>(options)
|
||||
<< "Cubic pipeline parameters:\n"
|
||||
<< "\tFast convergence = " << (options.enableFastConv ? "yes" : "no") << "\n"
|
||||
<< "\tCubic beta = " << options.cubicBeta << "\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace chunks
|
||||
} // namespace ndn
|
||||
@@ -31,24 +31,6 @@
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
class PipelineInterestsCubicOptions : public PipelineInterestsAdaptiveOptions
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
PipelineInterestsCubicOptions(const PipelineInterestsAdaptiveOptions& options =
|
||||
PipelineInterestsAdaptiveOptions())
|
||||
: PipelineInterestsAdaptiveOptions(options)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
bool enableFastConv = false; ///< use cubic fast convergence
|
||||
double cubicBeta = 0.7; ///< multiplicative decrease factor (from Linux kernel: 717/1024)
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const PipelineInterestsCubicOptions& options);
|
||||
|
||||
/**
|
||||
* @brief Implements Cubic window increase and decrease.
|
||||
*
|
||||
@@ -58,11 +40,7 @@ operator<<(std::ostream& os, const PipelineInterestsCubicOptions& options);
|
||||
class PipelineInterestsCubic final : public PipelineInterestsAdaptive
|
||||
{
|
||||
public:
|
||||
using Options = PipelineInterestsCubicOptions;
|
||||
|
||||
public:
|
||||
PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator,
|
||||
const Options& options = Options());
|
||||
PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -72,8 +50,6 @@ private:
|
||||
decreaseWindow() final;
|
||||
|
||||
private:
|
||||
const Options m_cubicOptions;
|
||||
|
||||
double m_wmax = 0.0; ///< window size before last window decrease
|
||||
double m_lastWmax = 0.0; ///< last wmax
|
||||
time::steady_clock::TimePoint m_lastDecrease; ///< time of last window decrease
|
||||
|
||||
@@ -33,12 +33,15 @@
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
PipelineInterestsFixed::PipelineInterestsFixed(Face& face, const Options& options)
|
||||
: PipelineInterests(face)
|
||||
, m_options(options)
|
||||
, m_hasFailure(false)
|
||||
PipelineInterestsFixed::PipelineInterestsFixed(Face& face, const Options& opts)
|
||||
: PipelineInterests(face, opts)
|
||||
{
|
||||
m_segmentFetchers.resize(m_options.maxPipelineSize);
|
||||
|
||||
if (m_options.isVerbose) {
|
||||
printOptions();
|
||||
std::cerr << "\tPipeline size = " << m_options.maxPipelineSize << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
PipelineInterestsFixed::~PipelineInterestsFixed()
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_FIXED_HPP
|
||||
#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_FIXED_HPP
|
||||
|
||||
#include "options.hpp"
|
||||
#include "pipeline-interests.hpp"
|
||||
|
||||
namespace ndn {
|
||||
@@ -38,20 +37,6 @@ namespace chunks {
|
||||
|
||||
class DataFetcher;
|
||||
|
||||
class PipelineInterestsFixedOptions : public Options
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
PipelineInterestsFixedOptions(const Options& options = Options())
|
||||
: Options(options)
|
||||
, maxPipelineSize(1)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
size_t maxPipelineSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Service for retrieving Data via an Interest pipeline
|
||||
*
|
||||
@@ -65,17 +50,7 @@ public:
|
||||
class PipelineInterestsFixed final : public PipelineInterests
|
||||
{
|
||||
public:
|
||||
typedef PipelineInterestsFixedOptions Options;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create a PipelineInterestsFixed service
|
||||
*
|
||||
* Configures the pipelining service without specifying the retrieval namespace. After this
|
||||
* configuration the method run must be called to start the Pipeline.
|
||||
*/
|
||||
explicit
|
||||
PipelineInterestsFixed(Face& face, const Options& options = Options());
|
||||
PipelineInterestsFixed(Face& face, const Options& opts);
|
||||
|
||||
~PipelineInterestsFixed() final;
|
||||
|
||||
@@ -107,14 +82,13 @@ private:
|
||||
handleFail(const std::string& reason, size_t pipeNo);
|
||||
|
||||
private:
|
||||
const Options m_options;
|
||||
std::vector<std::pair<shared_ptr<DataFetcher>, uint64_t>> m_segmentFetchers;
|
||||
|
||||
/**
|
||||
* true if one or more segment fetchers encountered an error; if m_hasFinalBlockId
|
||||
* is false, this is usually not a fatal error for the pipeline
|
||||
*/
|
||||
bool m_hasFailure;
|
||||
bool m_hasFailure = false;
|
||||
};
|
||||
|
||||
} // namespace chunks
|
||||
|
||||
@@ -29,12 +29,14 @@
|
||||
*/
|
||||
|
||||
#include "pipeline-interests.hpp"
|
||||
#include "data-fetcher.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
|
||||
PipelineInterests::PipelineInterests(Face& face)
|
||||
: m_face(face)
|
||||
PipelineInterests::PipelineInterests(Face& face, const Options& opts)
|
||||
: m_options(opts)
|
||||
, m_face(face)
|
||||
, m_hasFinalBlockId(false)
|
||||
, m_lastSegmentNo(0)
|
||||
, m_nReceived(0)
|
||||
@@ -106,6 +108,31 @@ PipelineInterests::onFailure(const std::string& reason)
|
||||
m_face.getIoService().post([this, reason] { m_onFailure(reason); });
|
||||
}
|
||||
|
||||
void
|
||||
PipelineInterests::printOptions() const
|
||||
{
|
||||
std::cerr << "Pipeline parameters:\n"
|
||||
<< "\tRequest fresh content = " << (m_options.mustBeFresh ? "yes" : "no") << "\n"
|
||||
<< "\tInterest lifetime = " << m_options.interestLifetime << "\n"
|
||||
<< "\tMax retries on timeout or Nack = " <<
|
||||
(m_options.maxRetriesOnTimeoutOrNack == DataFetcher::MAX_RETRIES_INFINITE ?
|
||||
"infinite" : to_string(m_options.maxRetriesOnTimeoutOrNack)) << "\n";
|
||||
}
|
||||
|
||||
void
|
||||
PipelineInterests::printSummary() const
|
||||
{
|
||||
using namespace ndn::time;
|
||||
duration<double, seconds::period> timeElapsed = steady_clock::now() - getStartTime();
|
||||
double throughput = 8 * m_receivedSize / timeElapsed.count();
|
||||
|
||||
std::cerr << "\n\nAll segments have been received.\n"
|
||||
<< "Time elapsed: " << timeElapsed << "\n"
|
||||
<< "Segments received: " << m_nReceived << "\n"
|
||||
<< "Transferred size: " << m_receivedSize / 1e3 << " kB" << "\n"
|
||||
<< "Goodput: " << formatThroughput(throughput) << "\n";
|
||||
}
|
||||
|
||||
std::string
|
||||
PipelineInterests::formatThroughput(double throughput)
|
||||
{
|
||||
@@ -129,19 +156,5 @@ PipelineInterests::formatThroughput(double throughput)
|
||||
return "";
|
||||
}
|
||||
|
||||
void
|
||||
PipelineInterests::printSummary() const
|
||||
{
|
||||
using namespace ndn::time;
|
||||
duration<double, seconds::period> timeElapsed = steady_clock::now() - getStartTime();
|
||||
double throughput = 8 * m_receivedSize / timeElapsed.count();
|
||||
|
||||
std::cerr << "\n\nAll segments have been received.\n"
|
||||
<< "Time elapsed: " << timeElapsed << "\n"
|
||||
<< "Segments received: " << m_nReceived << "\n"
|
||||
<< "Transferred size: " << m_receivedSize / 1e3 << " kB" << "\n"
|
||||
<< "Goodput: " << formatThroughput(throughput) << "\n";
|
||||
}
|
||||
|
||||
} // namespace chunks
|
||||
} // namespace ndn
|
||||
@@ -31,7 +31,7 @@
|
||||
#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
|
||||
#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
|
||||
|
||||
#include "core/common.hpp"
|
||||
#include "options.hpp"
|
||||
|
||||
namespace ndn {
|
||||
namespace chunks {
|
||||
@@ -49,21 +49,20 @@ namespace chunks {
|
||||
class PipelineInterests
|
||||
{
|
||||
public:
|
||||
using DataCallback = std::function<void(const Data&)>;
|
||||
using FailureCallback = std::function<void(const std::string& reason)>;
|
||||
|
||||
/**
|
||||
* @brief create a PipelineInterests service
|
||||
* @brief Constructor.
|
||||
*
|
||||
* Configures the pipelining service without specifying the retrieval namespace.
|
||||
* After construction, the method run() must be called in order to start the pipeline.
|
||||
*/
|
||||
explicit
|
||||
PipelineInterests(Face& face);
|
||||
PipelineInterests(Face& face, const Options& opts);
|
||||
|
||||
virtual
|
||||
~PipelineInterests();
|
||||
|
||||
using DataCallback = std::function<void(const Data&)>;
|
||||
using FailureCallback = std::function<void(const std::string& reason)>;
|
||||
|
||||
/**
|
||||
* @brief start fetching all the segments of the specified prefix
|
||||
*
|
||||
@@ -119,6 +118,9 @@ protected:
|
||||
void
|
||||
onFailure(const std::string& reason);
|
||||
|
||||
void
|
||||
printOptions() const;
|
||||
|
||||
/**
|
||||
* @brief print statistics about this fetching session
|
||||
*
|
||||
@@ -150,6 +152,7 @@ private:
|
||||
doCancel() = 0;
|
||||
|
||||
protected:
|
||||
const Options& m_options;
|
||||
Face& m_face;
|
||||
Name m_prefix;
|
||||
|
||||
|
||||
Reference in new issue
Block a user