chunks: move getNextSegmentNo() to PipelineInterests base class
This hides the "excluded segment" logic from subclasses and
reduces code duplication.
Change-Id: I9f7b5b88e6010e4e16a0876e79fc2ecb9ff8dc00
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.cpp b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
index 2e3da09..3b35001 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
@@ -40,7 +40,6 @@
, m_rttEstimator(rttEstimator)
, m_scheduler(m_face.getIoService())
, m_checkRtoEvent(m_scheduler)
- , m_nextSegmentNo(0)
, m_highData(0)
, m_highInterest(0)
, m_recPoint(0)
@@ -394,15 +393,6 @@
afterCwndChange(time::steady_clock::now() - getStartTime(), m_cwnd);
}
-uint64_t
-PipelineInterestsAimd::getNextSegmentNo()
-{
- // get around the excluded segment
- if (m_nextSegmentNo == m_excludedSegmentNo)
- m_nextSegmentNo++;
- return m_nextSegmentNo++;
-}
-
void
PipelineInterestsAimd::cancelInFlightSegmentsGreaterThan(uint64_t segNo)
{
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.hpp b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
index 3248100..5aedbfb 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
@@ -122,9 +122,8 @@
/**
* @brief fetch all the segments between 0 and lastSegment of the specified prefix
*
- * Starts the pipeline with an AIMD algorithm to control the window size. The pipeline will fetch
- * every segment until the last segment is successfully received or an error occurs.
- * The segment with segment number equal to m_excludedSegmentNo will not be fetched.
+ * Starts the pipeline with an AIMD algorithm to control the window size. The pipeline will
+ * fetch every segment until the last segment is successfully received or an error occurs.
*/
void
doRun() final;
@@ -181,12 +180,6 @@
void
decreaseWindow();
- /** \return next segment number to retrieve
- * \post m_nextSegmentNo == return-value + 1
- */
- uint64_t
- getNextSegmentNo();
-
void
cancelInFlightSegmentsGreaterThan(uint64_t segNo);
@@ -199,8 +192,6 @@
Scheduler m_scheduler;
scheduler::ScopedEventId m_checkRtoEvent;
- uint64_t m_nextSegmentNo;
-
uint64_t m_highData; ///< the highest segment number of the Data packet the consumer has received so far
uint64_t m_highInterest; ///< the highest segment number of the Interests the consumer has sent so far
uint64_t m_recPoint; ///< the value of m_highInterest when a packet loss event occurred,
diff --git a/tools/chunks/catchunks/pipeline-interests-fixed-window.cpp b/tools/chunks/catchunks/pipeline-interests-fixed-window.cpp
index 04cbf03..b81ec97 100644
--- a/tools/chunks/catchunks/pipeline-interests-fixed-window.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-fixed-window.cpp
@@ -36,7 +36,6 @@
PipelineInterestsFixedWindow::PipelineInterestsFixedWindow(Face& face, const Options& options)
: PipelineInterests(face)
, m_options(options)
- , m_nextSegmentNo(0)
, m_hasFailure(false)
{
m_segmentFetchers.resize(m_options.maxPipelineSize);
@@ -71,17 +70,15 @@
return false;
}
- if (m_nextSegmentNo == m_excludedSegmentNo)
- m_nextSegmentNo++;
-
- if (m_hasFinalBlockId && m_nextSegmentNo > m_lastSegmentNo)
- return false;
+ uint64_t nextSegmentNo = getNextSegmentNo();
+ if (m_hasFinalBlockId && nextSegmentNo > m_lastSegmentNo)
+ return false;
// send interest for next segment
if (m_options.isVerbose)
- std::cerr << "Requesting segment #" << m_nextSegmentNo << std::endl;
+ std::cerr << "Requesting segment #" << nextSegmentNo << std::endl;
- Interest interest(Name(m_prefix).appendSegment(m_nextSegmentNo));
+ Interest interest(Name(m_prefix).appendSegment(nextSegmentNo));
interest.setInterestLifetime(m_options.interestLifetime);
interest.setMustBeFresh(m_options.mustBeFresh);
interest.setMaxSuffixComponents(1);
@@ -95,8 +92,7 @@
m_options.isVerbose);
BOOST_ASSERT(!m_segmentFetchers[pipeNo].first || !m_segmentFetchers[pipeNo].first->isRunning());
- m_segmentFetchers[pipeNo] = make_pair(fetcher, m_nextSegmentNo);
- m_nextSegmentNo++;
+ m_segmentFetchers[pipeNo] = make_pair(fetcher, nextSegmentNo);
return true;
}
diff --git a/tools/chunks/catchunks/pipeline-interests-fixed-window.hpp b/tools/chunks/catchunks/pipeline-interests-fixed-window.hpp
index 81b7d72..22f1a4b 100644
--- a/tools/chunks/catchunks/pipeline-interests-fixed-window.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-fixed-window.hpp
@@ -85,7 +85,6 @@
*
* Starts a fixed-window pipeline with size equal to m_options.maxPipelineSize. The pipeline
* will fetch every segment until the last segment is successfully received or an error occurs.
- * The segment with segment number equal to m_excludedSegmentNo will not be fetched.
*/
void
doRun() final;
@@ -110,7 +109,7 @@
private:
const Options m_options;
std::vector<std::pair<shared_ptr<DataFetcher>, uint64_t>> m_segmentFetchers;
- uint64_t m_nextSegmentNo;
+
/**
* 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
diff --git a/tools/chunks/catchunks/pipeline-interests.cpp b/tools/chunks/catchunks/pipeline-interests.cpp
index 965492f..c0512cc 100644
--- a/tools/chunks/catchunks/pipeline-interests.cpp
+++ b/tools/chunks/catchunks/pipeline-interests.cpp
@@ -36,10 +36,11 @@
PipelineInterests::PipelineInterests(Face& face)
: m_face(face)
, m_lastSegmentNo(0)
- , m_excludedSegmentNo(0)
- , m_receivedSize(0)
, m_nReceived(0)
+ , m_receivedSize(0)
, m_hasFinalBlockId(false)
+ , m_nextSegmentNo(0)
+ , m_excludedSegmentNo(0)
, m_isStopping(false)
{
}
@@ -78,6 +79,16 @@
doCancel();
}
+uint64_t
+PipelineInterests::getNextSegmentNo()
+{
+ // skip the excluded segment
+ if (m_nextSegmentNo == m_excludedSegmentNo)
+ m_nextSegmentNo++;
+
+ return m_nextSegmentNo++;
+}
+
void
PipelineInterests::onFailure(const std::string& reason)
{
@@ -116,8 +127,8 @@
void
PipelineInterests::printSummary() const
{
- typedef time::duration<double, time::milliseconds::period> Milliseconds;
- Milliseconds timeElapsed = time::steady_clock::now() - getStartTime();
+ using namespace ndn::time;
+ duration<double, milliseconds::period> timeElapsed = steady_clock::now() - getStartTime();
double throughput = (8 * m_receivedSize * 1000) / timeElapsed.count();
std::cerr << "\nAll segments have been received.\n"
diff --git a/tools/chunks/catchunks/pipeline-interests.hpp b/tools/chunks/catchunks/pipeline-interests.hpp
index d806d1b..c8e14fe 100644
--- a/tools/chunks/catchunks/pipeline-interests.hpp
+++ b/tools/chunks/catchunks/pipeline-interests.hpp
@@ -93,6 +93,13 @@
return m_isStopping;
}
+ /**
+ * @return next segment number to retrieve
+ * @post m_nextSegmentNo == return-value + 1
+ */
+ uint64_t
+ getNextSegmentNo();
+
void
onData(const Interest& interest, const Data& data) const
{
@@ -106,26 +113,26 @@
onFailure(const std::string& reason);
/**
+ * @brief print statistics about this fetching session
+ *
+ * Subclasses can override this method to print additional stats or change the summary format
+ */
+ virtual void
+ printSummary() const;
+
+ /**
* @param throughput The throughput in bits/s
*/
static std::string
formatThroughput(double throughput);
- /**
- * @brief print statistics about quality of packet delivery
- *
- * This method should be overriden by each pipeline (e.g. AIMD)
- */
- virtual void
- printSummary() const;
-
private:
/**
* @brief perform subclass-specific operations to fetch all the segments
*
* When overriding this function, at a minimum, the subclass should implement the retrieving
- * of all the segments. Segment m_excludedSegmentNo can be skipped. Subclass must guarantee
- * that onData is called at least once for every segment that is fetched successfully.
+ * of all the segments. Subclass must guarantee that onData is called at least once for every
+ * segment that is fetched successfully.
*
* @note m_lastSegmentNo contains a valid value only if m_hasFinalBlockId is true.
*/
@@ -138,11 +145,9 @@
protected:
Face& m_face;
Name m_prefix;
- uint64_t m_lastSegmentNo;
- uint64_t m_excludedSegmentNo;
-
- size_t m_receivedSize; ///< size of received data in bytes
+ uint64_t m_lastSegmentNo; ///< valid only if m_hasFinalBlockId == true
int64_t m_nReceived; ///< number of segments received
+ size_t m_receivedSize; ///< size of received data in bytes
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
bool m_hasFinalBlockId; ///< true if the last segment number is known
@@ -150,6 +155,8 @@
private:
DataCallback m_onData;
FailureCallback m_onFailure;
+ uint64_t m_nextSegmentNo;
+ uint64_t m_excludedSegmentNo;
time::steady_clock::TimePoint m_startTime;
bool m_isStopping;
};