Rewritten ServerStatMan using BufferedFile.

pull/1/head
Tatsuhiro Tsujikawa 2011-08-07 00:10:53 +09:00
parent 7f3d027b83
commit 190d170076
7 changed files with 97 additions and 84 deletions

View File

@ -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)

View File

@ -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)
std::string ServerStat::toString() const
{
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 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

View File

@ -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()

View File

@ -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 {

View File

@ -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:

View File

@ -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);

View File

@ -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