Browse Source

Made HTTP/FTP download speed limiter more accurate

We have to do the same thing for BitTorrent.
Tatsuhiro Tsujikawa 13 years ago
parent
commit
46bdaf0e8d
7 changed files with 17 additions and 51 deletions
  1. 0 1
      src/DownloadCommand.cc
  2. 5 0
      src/PeerStat.cc
  3. 4 0
      src/PeerStat.h
  4. 6 36
      src/SegmentMan.cc
  5. 0 9
      src/SegmentMan.h
  6. 2 2
      src/SpeedCalc.h
  7. 0 3
      test/SegmentManTest.cc

+ 0 - 1
src/DownloadCommand.cc

@@ -177,7 +177,6 @@ bool DownloadCommand::executeInternal() {
     getSocketRecvBuffer()->shiftBuffer(bufSize);
     peerStat_->updateDownloadLength(bufSize);
   }
-  getSegmentMan()->updateDownloadSpeedFor(peerStat_);
   bool segmentPartComplete = false;
   // Note that GrowSegment::complete() always returns false.
   if(sinkFilterOnly_) {

+ 5 - 0
src/PeerStat.cc

@@ -130,4 +130,9 @@ void PeerStat::downloadStop()
   status_ = PeerStat::IDLE;
 }
 
+bool PeerStat::affectsOverallSpeed() const
+{
+  return !downloadSpeed_.isIntervalOver();
+}
+
 } // namespace aria2

+ 4 - 0
src/PeerStat.h

@@ -149,6 +149,10 @@ public:
   {
     sessionDownloadLength_ += length;
   }
+
+  // Returns true if the download speed of this object still affects
+  // overall download speed statistics.
+  bool affectsOverallSpeed() const;
 };
 
 } // namespace aria2

+ 6 - 36
src/SegmentMan.cc

@@ -69,8 +69,6 @@ SegmentMan::SegmentMan
   : option_(option),
     downloadContext_(downloadContext),
     pieceStorage_(pieceStorage),
-    lastPeerStatDlspdMapUpdated_(0),
-    cachedDlspd_(0),
     ignoreBitfield_(downloadContext->getPieceLength(),
                     downloadContext->getTotalLength())
 {
@@ -350,13 +348,6 @@ int64_t SegmentMan::getDownloadLength() const {
 
 void SegmentMan::registerPeerStat(const SharedHandle<PeerStat>& peerStat)
 {
-  for(std::vector<SharedHandle<PeerStat> >::iterator i = peerStats_.begin(),
-        eoi = peerStats_.end(); i != eoi; ++i) {
-    if((*i)->getStatus() == PeerStat::IDLE) {
-      *i = peerStat;
-      return;
-    }
-  }
   peerStats_.push_back(peerStat);
 }
 
@@ -407,38 +398,17 @@ void SegmentMan::updateFastestPeerStat(const SharedHandle<PeerStat>& peerStat)
 int SegmentMan::calculateDownloadSpeed()
 {
   int speed = 0;
-  if(lastPeerStatDlspdMapUpdated_.differenceInMillis(global::wallclock())+
-     A2_DELTA_MILLIS >= 250){
-    lastPeerStatDlspdMapUpdated_ = global::wallclock();
-    peerStatDlspdMap_.clear();
-    for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
-          peerStats_.begin(), eoi = peerStats_.end(); i != eoi; ++i) {
-      if((*i)->getStatus() == PeerStat::ACTIVE) {
-        int s = (*i)->calculateDownloadSpeed();
-        peerStatDlspdMap_[(*i)->getCuid()] = s;
-        speed += s;
-      }
+  for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
+        peerStats_.begin(), eoi = peerStats_.end(); i != eoi; ++i) {
+    // PeerStat which is IDLE but its last download speed calculation
+    // interval is not over must be added to the result.
+    if((*i)->getStatus() == PeerStat::ACTIVE || (*i)->affectsOverallSpeed()) {
+      speed += (*i)->calculateDownloadSpeed();
     }
-    cachedDlspd_ = speed;
-  } else {
-    speed = cachedDlspd_;
   }
   return speed;
 }
 
-void SegmentMan::updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat)
-{
-  int newspd = pstat->calculateDownloadSpeed();
-  int oldSpd = peerStatDlspdMap_[pstat->getCuid()];
-  if(cachedDlspd_ > oldSpd) {
-    cachedDlspd_ -= oldSpd;
-    cachedDlspd_ += newspd;
-  } else {
-    cachedDlspd_ = newspd;
-  }
-  peerStatDlspdMap_[pstat->getCuid()] = newspd;
-}
-
 namespace {
 class PeerStatDownloadLengthOperator {
 public:

+ 0 - 9
src/SegmentMan.h

@@ -93,13 +93,6 @@ private:
   // Keep track of fastest PeerStat for each server
   std::vector<SharedHandle<PeerStat> > fastestPeerStats_;
 
-  // key: PeerStat's cuid, value: its download speed
-  std::map<cuid_t, int> peerStatDlspdMap_;
-
-  Timer lastPeerStatDlspdMapUpdated_;
-
-  int cachedDlspd_;
-
   BitfieldMan ignoreBitfield_;
 
   SharedHandle<Segment> checkoutSegment(cuid_t cuid,
@@ -232,8 +225,6 @@ public:
    */
   int calculateDownloadSpeed();
 
-  void updateDownloadSpeedFor(const SharedHandle<PeerStat>& pstat);
-
   /**
    * Returns the downloaded bytes in this session.
    */

+ 2 - 2
src/SpeedCalc.h

@@ -51,14 +51,14 @@ private:
   int64_t accumulatedLength_;
   time_t nextInterval_;
 
-  bool isIntervalOver() const;
-
   bool isIntervalOver(int64_t milliElapsed) const;
 
   void changeSw();
 public:
   SpeedCalc();
 
+  bool isIntervalOver() const;
+
   /**
    * Returns download/upload speed in byte per sec
    */

+ 0 - 3
test/SegmentManTest.cc

@@ -157,9 +157,6 @@ void SegmentManTest::testRegisterPeerStat()
   CPPUNIT_ASSERT_EQUAL((size_t)1, segman.getPeerStats().size());
   SharedHandle<PeerStat> p2(new PeerStat(0, "host2", "http"));
   segman.registerPeerStat(p2);
-  CPPUNIT_ASSERT_EQUAL((size_t)1, segman.getPeerStats().size());
-  p2->downloadStart();
-  segman.registerPeerStat(p1);
   CPPUNIT_ASSERT_EQUAL((size_t)2, segman.getPeerStats().size());
 }