Преглед на файлове

Rewritten ServerStatMan using BufferedFile.

Tatsuhiro Tsujikawa преди 14 години
родител
ревизия
190d170076
променени са 7 файла, в които са добавени 98 реда и са изтрити 85 реда
  1. 2 35
      src/RequestGroupMan.cc
  2. 16 11
      src/ServerStat.cc
  3. 2 2
      src/ServerStat.h
  4. 61 12
      src/ServerStatMan.cc
  5. 2 3
      src/ServerStatMan.h
  6. 10 8
      test/ServerStatManTest.cc
  7. 5 14
      test/ServerStatTest.cc

+ 2 - 35
src/RequestGroupMan.cc

@@ -39,7 +39,6 @@
 #include <iomanip>
 #include <sstream>
 #include <ostream>
-#include <fstream>
 #include <numeric>
 #include <algorithm>
 #include <utility>
@@ -835,44 +834,12 @@ bool RequestGroupMan::addServerStat(const SharedHandle<ServerStat>& serverStat)
 
 bool RequestGroupMan::loadServerStat(const std::string& filename)
 {
-  std::ifstream in(filename.c_str(), std::ios::binary);
-  if(!in) {
-    A2_LOG_ERROR(fmt(MSG_OPENING_READABLE_SERVER_STAT_FILE_FAILED,
-                     filename.c_str()));
-    return false;
-  }
-  if(serverStatMan_->load(in)) {
-    A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_LOADED, filename.c_str()));
-    return true;
-  } else {
-    A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED, filename.c_str()));
-    return false;
-  }
+  return serverStatMan_->load(filename);
 }
 
 bool RequestGroupMan::saveServerStat(const std::string& filename) const
 {
-  std::string tempfile = filename;
-  tempfile += "__temp";
-  {
-    std::ofstream out(tempfile.c_str(), std::ios::binary);
-    if(!out) {
-      A2_LOG_ERROR(fmt(MSG_OPENING_WRITABLE_SERVER_STAT_FILE_FAILED,
-                       filename.c_str()));
-      return false;
-    }
-    if(!serverStatMan_->save(out)) {
-      A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED, filename.c_str()));
-      return false;
-    }
-  }
-  if(File(tempfile).renameTo(filename)) {
-    A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_SAVED, filename.c_str()));
-    return true;
-  } else {
-    A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED, filename.c_str()));
-    return false;
-  }
+  return serverStatMan_->save(filename);
 }
 
 void RequestGroupMan::removeStaleServerStat(time_t timeout)

+ 16 - 11
src/ServerStat.cc

@@ -41,6 +41,8 @@
 #include "Logger.h"
 #include "LogFactory.h"
 #include "fmt.h"
+#include "a2functional.h"
+#include "util.h"
 
 namespace aria2 {
 
@@ -204,17 +206,20 @@ bool ServerStat::operator==(const ServerStat& serverStat) const
   return hostname_ == serverStat.hostname_ && protocol_ == serverStat.protocol_;
 }
 
-std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat)
-{
-  o << "host=" << serverStat.getHostname() << ", "
-    << "protocol=" << serverStat.getProtocol() << ", "
-    << "dl_speed=" << serverStat.getDownloadSpeed() << ", "
-    << "sc_avg_speed=" << serverStat.getSingleConnectionAvgSpeed() << ", "
-    << "mc_avg_speed=" << serverStat.getMultiConnectionAvgSpeed() << ", "
-    << "last_updated=" << serverStat.getLastUpdated().getTime() << ", "
-    << "counter=" << serverStat.getCounter() << ", "
-    << "status=" << ServerStat::STATUS_STRING[serverStat.getStatus()];
-  return o;
+std::string ServerStat::toString() const
+{
+  std::string res;
+  strappend(res, "host=", getHostname(), ", ");
+  strappend(res, "protocol=", getProtocol(), ", ");
+  strappend(res, "dl_speed=", util::uitos(getDownloadSpeed()), ", ");
+  strappend(res, "sc_avg_speed=", util::uitos(getSingleConnectionAvgSpeed()),
+            ", ");
+  strappend(res, "mc_avg_speed=", util::uitos(getMultiConnectionAvgSpeed()),
+            ", ");
+  strappend(res, "last_updated=", util::itos(getLastUpdated().getTime()), ", ");
+  strappend(res, "counter=", util::uitos(getCounter()), ", ");
+  strappend(res, "status=", ServerStat::STATUS_STRING[getStatus()]);
+  return res;
 }
 
 } // namespace aria2

+ 2 - 2
src/ServerStat.h

@@ -146,6 +146,8 @@ public:
   bool operator<(const ServerStat& serverStat) const;
 
   bool operator==(const ServerStat& serverStat) const;
+
+  std::string toString() const;
 private:
   std::string hostname_;
   
@@ -166,8 +168,6 @@ private:
   void setStatusInternal(STATUS status);
 };
 
-std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat);
-
 class ServerStatFaster {
 public:
   bool operator()

+ 61 - 12
src/ServerStatMan.cc

@@ -34,8 +34,9 @@
 /* copyright --> */
 #include "ServerStatMan.h"
 
+#include <cstring>
+#include <cstdio>
 #include <algorithm>
-#include <ostream>
 #include <iterator>
 #include <map>
 #include <vector>
@@ -44,6 +45,11 @@
 #include "util.h"
 #include "RecoverableException.h"
 #include "a2functional.h"
+#include "BufferedFile.h"
+#include "message.h"
+#include "fmt.h"
+#include "LogFactory.h"
+#include "File.h"
 
 namespace aria2 {
 
@@ -80,17 +86,44 @@ bool ServerStatMan::add(const SharedHandle<ServerStat>& serverStat)
   } 
 }
 
-bool ServerStatMan::save(std::ostream& out) const
+bool ServerStatMan::save(const std::string& filename) const
 {
-  for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
-        serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
-    out << *(*i) << "\n";
+  std::string tempfile = filename;
+  tempfile += "__temp";
+  {
+    BufferedFile fp(tempfile, BufferedFile::WRITE);
+    if(!fp) {
+      A2_LOG_ERROR(fmt(MSG_OPENING_WRITABLE_SERVER_STAT_FILE_FAILED,
+                       utf8ToNative(filename).c_str()));
+      return false;
+    }
+    for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
+          serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
+      std::string l = (*i)->toString();
+      l += "\n";
+      if(fp.write(l.data(), l.size()) != l.size()) {
+        A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
+                         utf8ToNative(filename).c_str()));
+      }
+    }
+    if(fp.close() == EOF) {
+      A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
+                       utf8ToNative(filename).c_str()));
+      return false;
+    }
+  }
+  if(File(tempfile).renameTo(filename)) {
+    A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_SAVED,
+                      utf8ToNative(filename).c_str()));
+    return true;
+  } else {
+    A2_LOG_ERROR(fmt(MSG_WRITING_SERVER_STAT_FILE_FAILED,
+                     utf8ToNative(filename).c_str()));
+    return false;
   }
-  out.flush();
-  return !out.bad();
 }
 
-bool ServerStatMan::load(std::istream& in)
+bool ServerStatMan::load(const std::string& filename)
 {
   static const std::string S_HOST = "host";
   static const std::string S_PROTOCOL = "protocol";
@@ -101,9 +134,24 @@ bool ServerStatMan::load(std::istream& in)
   static const std::string S_COUNTER = "counter";
   static const std::string S_STATUS = "status";
 
-  std::string line;
-  while(getline(in, line)) {
-    line = util::strip(line);
+  BufferedFile fp(filename, BufferedFile::READ);
+  if(!fp) {
+    A2_LOG_ERROR(fmt(MSG_OPENING_READABLE_SERVER_STAT_FILE_FAILED,
+                     utf8ToNative(filename).c_str()));
+    return false;
+  }
+  char buf[4096];
+  while(1) {
+    if(!fp.getsn(buf, sizeof(buf))) {
+      if(fp.eof()) {
+        break;
+      } else {
+        A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED,
+                         utf8ToNative(filename).c_str()));
+        return false;
+      }
+    }
+    std::string line = util::stripIter(&buf[0], &buf[strlen(buf)]);
     if(line.empty()) {
       continue;
     }
@@ -143,7 +191,8 @@ bool ServerStatMan::load(std::istream& in)
       continue;
     }
   }
-  return !in.bad();
+  A2_LOG_NOTICE(fmt(MSG_SERVER_STAT_LOADED, utf8ToNative(filename).c_str()));
+  return true;
 }
 
 namespace {

+ 2 - 3
src/ServerStatMan.h

@@ -38,7 +38,6 @@
 
 #include <string>
 #include <deque>
-#include <iosfwd>
 
 #include "SharedHandle.h"
 #include "a2time.h"
@@ -58,9 +57,9 @@ public:
 
   bool add(const SharedHandle<ServerStat>& serverStat);
 
-  bool load(std::istream& in);
+  bool load(const std::string& filename);
 
-  bool save(std::ostream& out) const;
+  bool save(const std::string& filename) const;
 
   void removeStaleServerStat(time_t timeout);
 private:

+ 10 - 8
test/ServerStatManTest.cc

@@ -1,13 +1,14 @@
 #include "ServerStatMan.h"
 
 #include <iostream>
-#include <sstream>
 
 #include <cppunit/extensions/HelperMacros.h>
 
 #include "ServerStat.h"
 #include "Exception.h"
 #include "util.h"
+#include "BufferedFile.h"
+#include "TestUtil.h"
 
 namespace aria2 {
 
@@ -78,9 +79,8 @@ void ServerStatManTest::testSave()
   CPPUNIT_ASSERT(ssm.add(localhost_ftp));
   CPPUNIT_ASSERT(ssm.add(mirror));
 
-  std::stringstream ss;
-  CPPUNIT_ASSERT(ssm.save(ss));
-  std::string out = ss.str();
+  std::string filename = A2_TEST_OUT_DIR"/aria2_ServerStatManTest_testSave";
+  CPPUNIT_ASSERT(ssm.save(filename));
   CPPUNIT_ASSERT_EQUAL
     (std::string
      ("host=localhost, protocol=ftp,"
@@ -106,20 +106,22 @@ void ServerStatManTest::testSave()
       " last_updated=1210000002,"
       " counter=0,"
       " status=ERROR\n"),
-     out);                         
+     readFile(filename));
 }
 
 void ServerStatManTest::testLoad()
 {
+  std::string filename = A2_TEST_OUT_DIR"/aria2_ServerStatManTest_testLoad";
   std::string in =
     "host=localhost, protocol=ftp, dl_speed=30000, last_updated=1210000001, status=OK\n"
     "host=localhost, protocol=http, dl_speed=25000, sc_avg_speed=101, mc_avg_speed=102, last_updated=1210000000, counter=6, status=OK\n"
     "host=mirror, protocol=http, dl_speed=0, last_updated=1210000002, status=ERROR\n";
-
-  std::stringstream ss(in);
+  BufferedFile fp(filename, BufferedFile::WRITE);
+  CPPUNIT_ASSERT_EQUAL((size_t)in.size(), fp.write(in.data(), in.size()));
+  CPPUNIT_ASSERT(fp.close() != EOF);
 
   ServerStatMan ssm;
-  CPPUNIT_ASSERT(ssm.load(ss));
+  CPPUNIT_ASSERT(ssm.load(filename));
 
   SharedHandle<ServerStat> localhost_http = ssm.find("localhost", "http");
   CPPUNIT_ASSERT(localhost_http);

+ 5 - 14
test/ServerStatTest.cc

@@ -14,7 +14,7 @@ class ServerStatTest:public CppUnit::TestFixture {
 
   CPPUNIT_TEST_SUITE(ServerStatTest);
   CPPUNIT_TEST(testSetStatus);
-  CPPUNIT_TEST(testOperatorOstream);
+  CPPUNIT_TEST(testToString);
   CPPUNIT_TEST_SUITE_END();
 public:
   void setUp() {}
@@ -22,7 +22,7 @@ public:
   void tearDown() {}
 
   void testSetStatus();
-  void testOperatorOstream();
+  void testToString();
 };
 
 
@@ -44,7 +44,7 @@ void ServerStatTest::testSetStatus()
   CPPUNIT_ASSERT_EQUAL(ServerStat::OK, ss.getStatus());  
 }
 
-void ServerStatTest::testOperatorOstream()
+void ServerStatTest::testToString()
 {
   ServerStat localhost_http("localhost", "http");
   localhost_http.setDownloadSpeed(90000);
@@ -53,33 +53,24 @@ void ServerStatTest::testOperatorOstream()
   localhost_http.setMultiConnectionAvgSpeed(102);
   localhost_http.setCounter(5);
 
-  std::stringstream ss;
-  
-  ss << localhost_http;
-
   CPPUNIT_ASSERT_EQUAL
     (std::string
      ("host=localhost, protocol=http, dl_speed=90000,"
       " sc_avg_speed=101, mc_avg_speed=102,"
       " last_updated=1000, counter=5, status=OK"),
-     ss.str());
-
-  ss.str("");
+     localhost_http.toString());
 
   ServerStat localhost_ftp("localhost", "ftp");
   localhost_ftp.setDownloadSpeed(10000);
   localhost_ftp.setLastUpdated(Time(1210000000));
   localhost_ftp.setStatus("ERROR");
 
-  ss << localhost_ftp;
-
   CPPUNIT_ASSERT_EQUAL
     (std::string
      ("host=localhost, protocol=ftp, dl_speed=10000,"
       " sc_avg_speed=0, mc_avg_speed=0,"
       " last_updated=1210000000, counter=0, status=ERROR"),
-     ss.str());
-
+     localhost_ftp.toString());
 }
 
 } // namespace aria2