mirror of https://github.com/aria2/aria2
Use std::set instead of std::deque if the elements are sorted and
insertions and deletions are frequent.pull/14/head
parent
4acc0f8831
commit
eed804baaa
|
@ -64,20 +64,21 @@ AuthConfigFactory::createAuthConfig
|
||||||
|
|
||||||
if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) {
|
if(op->getAsBool(PREF_HTTP_AUTH_CHALLENGE)) {
|
||||||
if(!request->getUsername().empty()) {
|
if(!request->getUsername().empty()) {
|
||||||
updateBasicCred(BasicCred(request->getUsername(),
|
SharedHandle<BasicCred> bc(new BasicCred(request->getUsername(),
|
||||||
request->getPassword(),
|
request->getPassword(),
|
||||||
request->getHost(),
|
request->getHost(),
|
||||||
request->getPort(),
|
request->getPort(),
|
||||||
request->getDir(), true));
|
request->getDir(), true));
|
||||||
|
updateBasicCred(bc);
|
||||||
return createAuthConfig(request->getUsername(), request->getPassword());
|
return createAuthConfig(request->getUsername(), request->getPassword());
|
||||||
}
|
}
|
||||||
std::deque<BasicCred>::const_iterator i =
|
BasicCredSet::iterator i =
|
||||||
findBasicCred(request->getHost(), request->getPort(),
|
findBasicCred(request->getHost(), request->getPort(),
|
||||||
request->getDir());
|
request->getDir());
|
||||||
if(i == basicCreds_.end()) {
|
if(i == basicCreds_.end()) {
|
||||||
return SharedHandle<AuthConfig>();
|
return SharedHandle<AuthConfig>();
|
||||||
} else {
|
} else {
|
||||||
return createAuthConfig((*i).user_, (*i).password_);
|
return createAuthConfig((*i)->user_, (*i)->password_);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!request->getUsername().empty()) {
|
if(!request->getUsername().empty()) {
|
||||||
|
@ -170,13 +171,12 @@ void AuthConfigFactory::setNetrc(const SharedHandle<Netrc>& netrc)
|
||||||
netrc_ = netrc;
|
netrc_ = netrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthConfigFactory::updateBasicCred(const BasicCred& basicCred)
|
void AuthConfigFactory::updateBasicCred
|
||||||
|
(const SharedHandle<BasicCred>& basicCred)
|
||||||
{
|
{
|
||||||
std::deque<BasicCred>::iterator i =
|
BasicCredSet::iterator i = basicCreds_.lower_bound(basicCred);
|
||||||
std::lower_bound(basicCreds_.begin(), basicCreds_.end(), basicCred);
|
if(i != basicCreds_.end() && *(*i) == *basicCred) {
|
||||||
|
*(*i) = *basicCred;
|
||||||
if(i != basicCreds_.end() && (*i) == basicCred) {
|
|
||||||
(*i) = basicCred;
|
|
||||||
} else {
|
} else {
|
||||||
basicCreds_.insert(i, basicCred);
|
basicCreds_.insert(i, basicCred);
|
||||||
}
|
}
|
||||||
|
@ -188,22 +188,21 @@ bool AuthConfigFactory::activateBasicCred
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
const Option* op)
|
const Option* op)
|
||||||
{
|
{
|
||||||
|
BasicCredSet::iterator i = findBasicCred(host, port, path);
|
||||||
std::deque<BasicCred>::iterator i = findBasicCred(host, port, path);
|
|
||||||
if(i == basicCreds_.end()) {
|
if(i == basicCreds_.end()) {
|
||||||
SharedHandle<AuthConfig> authConfig =
|
SharedHandle<AuthConfig> authConfig =
|
||||||
createHttpAuthResolver(op)->resolveAuthConfig(host);
|
createHttpAuthResolver(op)->resolveAuthConfig(host);
|
||||||
if(!authConfig) {
|
if(!authConfig) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
BasicCred bc(authConfig->getUser(), authConfig->getPassword(),
|
SharedHandle<BasicCred> bc
|
||||||
host, port, path, true);
|
(new BasicCred(authConfig->getUser(), authConfig->getPassword(),
|
||||||
i = std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
|
host, port, path, true));
|
||||||
basicCreds_.insert(i, bc);
|
basicCreds_.insert(bc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(*i).activate();
|
(*i)->activate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,18 +241,17 @@ bool AuthConfigFactory::BasicCred::operator<(const BasicCred& cred) const
|
||||||
(!(cred.port_ < port_) && path_ > cred.path_)));
|
(!(cred.port_ < port_) && path_ > cred.path_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::deque<AuthConfigFactory::BasicCred>::iterator
|
AuthConfigFactory::BasicCredSet::iterator
|
||||||
AuthConfigFactory::findBasicCred
|
AuthConfigFactory::findBasicCred
|
||||||
(const std::string& host,
|
(const std::string& host,
|
||||||
uint16_t port,
|
uint16_t port,
|
||||||
const std::string& path)
|
const std::string& path)
|
||||||
{
|
{
|
||||||
BasicCred bc("", "", host, port, path);
|
SharedHandle<BasicCred> bc(new BasicCred("", "", host, port, path));
|
||||||
std::deque<BasicCred>::iterator i =
|
BasicCredSet::iterator i = basicCreds_.lower_bound(bc);
|
||||||
std::lower_bound(basicCreds_.begin(), basicCreds_.end(), bc);
|
for(; i != basicCreds_.end() && (*i)->host_ == host && (*i)->port_ == port;
|
||||||
for(; i != basicCreds_.end() && (*i).host_ == host && (*i).port_ == port;
|
|
||||||
++i) {
|
++i) {
|
||||||
if(util::startsWith(bc.path_, (*i).path_)) {
|
if(util::startsWith(bc->path_, (*i)->path_)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,11 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <set>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
#include "SingletonHolder.h"
|
#include "SingletonHolder.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -83,8 +84,11 @@ public:
|
||||||
|
|
||||||
bool operator<(const BasicCred& cred) const;
|
bool operator<(const BasicCred& cred) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::set<SharedHandle<BasicCred>,
|
||||||
|
DerefLess<SharedHandle<BasicCred> > > BasicCredSet;
|
||||||
private:
|
private:
|
||||||
std::deque<BasicCred> basicCreds_;
|
BasicCredSet basicCreds_;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AuthConfigFactory();
|
AuthConfigFactory();
|
||||||
|
@ -115,7 +119,7 @@ public:
|
||||||
// Find a BasicCred using host, port and path and return the
|
// Find a BasicCred using host, port and path and return the
|
||||||
// iterator pointing to it. If not found, then return
|
// iterator pointing to it. If not found, then return
|
||||||
// basicCreds_.end().
|
// basicCreds_.end().
|
||||||
std::deque<AuthConfigFactory::BasicCred>::iterator
|
BasicCredSet::iterator
|
||||||
findBasicCred
|
findBasicCred
|
||||||
(const std::string& host,
|
(const std::string& host,
|
||||||
uint16_t port,
|
uint16_t port,
|
||||||
|
@ -124,7 +128,7 @@ public:
|
||||||
// If the same BasicCred is already added, then it is replaced with
|
// If the same BasicCred is already added, then it is replaced with
|
||||||
// given basicCred. Otherwise, insert given basicCred to
|
// given basicCred. Otherwise, insert given basicCred to
|
||||||
// basicCreds_.
|
// basicCreds_.
|
||||||
void updateBasicCred(const BasicCred& basicCred);
|
void updateBasicCred(const SharedHandle<BasicCred>& basicCred);
|
||||||
|
|
||||||
static const std::string ANONYMOUS;
|
static const std::string ANONYMOUS;
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,21 @@ void swap(CookieStorage::DomainEntry& a, CookieStorage::DomainEntry& b)
|
||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CookieStorage::DomainEntry::findCookie
|
||||||
|
(std::vector<Cookie>& out,
|
||||||
|
const std::string& requestHost,
|
||||||
|
const std::string& requestPath,
|
||||||
|
time_t now, bool secure)
|
||||||
|
{
|
||||||
|
for(std::deque<Cookie>::iterator i = cookies_.begin(),
|
||||||
|
eoi = cookies_.end(); i != eoi; ++i) {
|
||||||
|
if((*i).match(requestHost, requestPath, now, secure)) {
|
||||||
|
(*i).setLastAccessTime(now);
|
||||||
|
out.push_back(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie, time_t now)
|
bool CookieStorage::DomainEntry::addCookie(const Cookie& cookie, time_t now)
|
||||||
{
|
{
|
||||||
setLastAccessTime(now);
|
setLastAccessTime(now);
|
||||||
|
@ -152,6 +167,10 @@ size_t CookieStorage::DomainEntry::countCookie() const
|
||||||
return cookies_.size();
|
return cookies_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CookieStorage::DomainEntry::operator==(const DomainEntry& de) const
|
||||||
|
{
|
||||||
|
return key_ == de.key_;
|
||||||
|
}
|
||||||
|
|
||||||
bool CookieStorage::DomainEntry::operator<(const DomainEntry& de) const
|
bool CookieStorage::DomainEntry::operator<(const DomainEntry& de) const
|
||||||
{
|
{
|
||||||
|
@ -172,20 +191,21 @@ const double DOMAIN_EVICTION_RATE = 0.1;
|
||||||
bool CookieStorage::store(const Cookie& cookie, time_t now)
|
bool CookieStorage::store(const Cookie& cookie, time_t now)
|
||||||
{
|
{
|
||||||
if(domains_.size() >= DOMAIN_EVICTION_TRIGGER) {
|
if(domains_.size() >= DOMAIN_EVICTION_TRIGGER) {
|
||||||
std::sort(domains_.begin(), domains_.end(),
|
std::vector<SharedHandle<DomainEntry> > evictions(domains_.begin(),
|
||||||
|
domains_.end());
|
||||||
|
std::sort(evictions.begin(), evictions.end(),
|
||||||
LeastRecentAccess<DomainEntry>());
|
LeastRecentAccess<DomainEntry>());
|
||||||
size_t delnum = (size_t)(domains_.size()*DOMAIN_EVICTION_RATE);
|
size_t delnum = (size_t)(evictions.size()*DOMAIN_EVICTION_RATE);
|
||||||
domains_.erase(domains_.begin(), domains_.begin()+delnum);
|
domains_.clear();
|
||||||
std::sort(domains_.begin(), domains_.end());
|
domains_.insert(evictions.begin()+delnum, evictions.end());
|
||||||
}
|
}
|
||||||
DomainEntry v(cookie.getDomain());
|
SharedHandle<DomainEntry> v(new DomainEntry(cookie.getDomain()));
|
||||||
std::deque<DomainEntry>::iterator i =
|
DomainEntrySet::iterator i = domains_.lower_bound(v);
|
||||||
std::lower_bound(domains_.begin(), domains_.end(), v);
|
|
||||||
bool added = false;
|
bool added = false;
|
||||||
if(i != domains_.end() && (*i).getKey() == v.getKey()) {
|
if(i != domains_.end() && *(*i) == *v) {
|
||||||
added = (*i).addCookie(cookie, now);
|
added = (*i)->addCookie(cookie, now);
|
||||||
} else {
|
} else {
|
||||||
added = v.addCookie(cookie, now);
|
added = v->addCookie(cookie, now);
|
||||||
if(added) {
|
if(added) {
|
||||||
domains_.insert(i, v);
|
domains_.insert(i, v);
|
||||||
}
|
}
|
||||||
|
@ -264,32 +284,27 @@ public:
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
void CookieStorage::searchCookieByDomainSuffix
|
||||||
template<typename DomainInputIterator, typename CookieOutputIterator>
|
(std::vector<Cookie>& out,
|
||||||
void searchCookieByDomainSuffix
|
const std::string& domain,
|
||||||
(const std::string& domain,
|
|
||||||
DomainInputIterator first, DomainInputIterator last, CookieOutputIterator out,
|
|
||||||
const std::string& requestHost,
|
const std::string& requestHost,
|
||||||
const std::string& requestPath,
|
const std::string& requestPath,
|
||||||
time_t now, bool secure)
|
time_t now, bool secure)
|
||||||
{
|
{
|
||||||
CookieStorage::DomainEntry v(domain);
|
SharedHandle<DomainEntry> v(new DomainEntry(domain));
|
||||||
std::deque<CookieStorage::DomainEntry>::iterator i =
|
DomainEntrySet::iterator i = domains_.lower_bound(v);
|
||||||
std::lower_bound(first, last, v);
|
if(i != domains_.end() && *(*i) == *v) {
|
||||||
if(i != last && (*i).getKey() == v.getKey()) {
|
(*i)->setLastAccessTime(now);
|
||||||
(*i).setLastAccessTime(now);
|
(*i)->findCookie(out, requestHost, requestPath, now, secure);
|
||||||
(*i).findCookie(out, requestHost, requestPath, now, secure);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool CookieStorage::contains(const Cookie& cookie) const
|
bool CookieStorage::contains(const Cookie& cookie) const
|
||||||
{
|
{
|
||||||
CookieStorage::DomainEntry v(cookie.getDomain());
|
SharedHandle<DomainEntry> v(new DomainEntry(cookie.getDomain()));
|
||||||
std::deque<CookieStorage::DomainEntry>::const_iterator i =
|
DomainEntrySet::iterator i = domains_.find(v);
|
||||||
std::lower_bound(domains_.begin(), domains_.end(), v);
|
if(i != domains_.end()) {
|
||||||
if(i != domains_.end() && (*i).getKey() == v.getKey()) {
|
return (*i)->contains(cookie);
|
||||||
return (*i).contains(cookie);
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -307,8 +322,7 @@ std::vector<Cookie> CookieStorage::criteriaFind
|
||||||
}
|
}
|
||||||
if(util::isNumericHost(requestHost)) {
|
if(util::isNumericHost(requestHost)) {
|
||||||
searchCookieByDomainSuffix
|
searchCookieByDomainSuffix
|
||||||
(requestHost, domains_.begin(), domains_.end(), std::back_inserter(res),
|
(res, requestHost, requestHost, requestPath, now, secure);
|
||||||
requestHost, requestPath, now, secure);
|
|
||||||
} else {
|
} else {
|
||||||
std::vector<Scip> levels;
|
std::vector<Scip> levels;
|
||||||
util::splitIter(requestHost.begin(), requestHost.end(),
|
util::splitIter(requestHost.begin(), requestHost.end(),
|
||||||
|
@ -319,8 +333,7 @@ std::vector<Cookie> CookieStorage::criteriaFind
|
||||||
i != eoi; ++i, domain.insert(domain.begin(), '.')) {
|
i != eoi; ++i, domain.insert(domain.begin(), '.')) {
|
||||||
domain.insert(domain.begin(), (*i).first, (*i).second);
|
domain.insert(domain.begin(), (*i).first, (*i).second);
|
||||||
searchCookieByDomainSuffix
|
searchCookieByDomainSuffix
|
||||||
(domain, domains_.begin(), domains_.end(),
|
(res, domain, requestHost, requestPath, now, secure);
|
||||||
std::back_inserter(res), requestHost, requestPath, now, secure);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<CookiePathDivider> divs;
|
std::vector<CookiePathDivider> divs;
|
||||||
|
@ -335,9 +348,9 @@ std::vector<Cookie> CookieStorage::criteriaFind
|
||||||
size_t CookieStorage::size() const
|
size_t CookieStorage::size() const
|
||||||
{
|
{
|
||||||
size_t numCookie = 0;
|
size_t numCookie = 0;
|
||||||
for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
|
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
||||||
eoi = domains_.end(); i != eoi; ++i) {
|
i != eoi; ++i) {
|
||||||
numCookie += (*i).countCookie();
|
numCookie += (*i)->countCookie();
|
||||||
}
|
}
|
||||||
return numCookie;
|
return numCookie;
|
||||||
}
|
}
|
||||||
|
@ -394,9 +407,9 @@ bool CookieStorage::saveNsFormat(const std::string& filename)
|
||||||
A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str()));
|
A2_LOG_ERROR(fmt("Cannot create cookie file %s", filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
|
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
||||||
eoi = domains_.end(); i != eoi; ++i) {
|
i != eoi; ++i) {
|
||||||
if(!(*i).writeCookie(fp)) {
|
if(!(*i)->writeCookie(fp)) {
|
||||||
A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str()));
|
A2_LOG_ERROR(fmt("Failed to save cookies to %s", filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,12 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
#include "Cookie.h"
|
#include "Cookie.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -78,22 +80,11 @@ public:
|
||||||
return key_;
|
return key_;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OutputIterator>
|
void findCookie
|
||||||
OutputIterator findCookie
|
(std::vector<Cookie>& out,
|
||||||
(OutputIterator out,
|
|
||||||
const std::string& requestHost,
|
const std::string& requestHost,
|
||||||
const std::string& requestPath,
|
const std::string& requestPath,
|
||||||
time_t now, bool secure)
|
time_t now, bool secure);
|
||||||
{
|
|
||||||
for(std::deque<Cookie>::iterator i = cookies_.begin(),
|
|
||||||
eoi = cookies_.end(); i != eoi; ++i) {
|
|
||||||
if((*i).match(requestHost, requestPath, now, secure)) {
|
|
||||||
(*i).setLastAccessTime(now);
|
|
||||||
out++ = *i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t countCookie() const;
|
size_t countCookie() const;
|
||||||
|
|
||||||
|
@ -119,10 +110,13 @@ public:
|
||||||
return std::copy(cookies_.begin(), cookies_.end(), out);
|
return std::copy(cookies_.begin(), cookies_.end(), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const DomainEntry& de) const;
|
||||||
bool operator<(const DomainEntry& de) const;
|
bool operator<(const DomainEntry& de) const;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
std::deque<DomainEntry> domains_;
|
typedef std::set<SharedHandle<DomainEntry>,
|
||||||
|
DerefLess<SharedHandle<DomainEntry> > > DomainEntrySet;
|
||||||
|
DomainEntrySet domains_;
|
||||||
|
|
||||||
template<typename InputIterator>
|
template<typename InputIterator>
|
||||||
void storeCookies(InputIterator first, InputIterator last, time_t now)
|
void storeCookies(InputIterator first, InputIterator last, time_t now)
|
||||||
|
@ -176,12 +170,22 @@ public:
|
||||||
// satisfies.
|
// satisfies.
|
||||||
bool contains(const Cookie& cookie) const;
|
bool contains(const Cookie& cookie) const;
|
||||||
|
|
||||||
|
// Searches Cookie using given domain, requestHost, requestPath,
|
||||||
|
// current time and secure flag. The found Cookies are stored in
|
||||||
|
// out.
|
||||||
|
void searchCookieByDomainSuffix
|
||||||
|
(std::vector<Cookie>& out,
|
||||||
|
const std::string& domain,
|
||||||
|
const std::string& requestHost,
|
||||||
|
const std::string& requestPath,
|
||||||
|
time_t now, bool secure);
|
||||||
|
|
||||||
template<typename OutputIterator>
|
template<typename OutputIterator>
|
||||||
OutputIterator dumpCookie(OutputIterator out) const
|
OutputIterator dumpCookie(OutputIterator out) const
|
||||||
{
|
{
|
||||||
for(std::deque<DomainEntry>::const_iterator i = domains_.begin(),
|
for(DomainEntrySet::iterator i = domains_.begin(), eoi = domains_.end();
|
||||||
eoi = domains_.end(); i != eoi; ++i) {
|
i != eoi; ++i) {
|
||||||
out = (*i).dumpCookie(out);
|
out = (*i)->dumpCookie(out);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,25 +56,19 @@ DHTPeerAnnounceStorage::DHTPeerAnnounceStorage() {}
|
||||||
|
|
||||||
DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {}
|
DHTPeerAnnounceStorage::~DHTPeerAnnounceStorage() {}
|
||||||
|
|
||||||
namespace {
|
bool DHTPeerAnnounceStorage::InfoHashLess::operator()
|
||||||
class InfoHashLess
|
(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
|
|
||||||
const SharedHandle<DHTPeerAnnounceEntry>& rhs)
|
const SharedHandle<DHTPeerAnnounceEntry>& rhs)
|
||||||
{
|
{
|
||||||
return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0;
|
return memcmp(lhs->getInfoHash(), rhs->getInfoHash(), DHT_ID_LENGTH) < 0;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
SharedHandle<DHTPeerAnnounceEntry>
|
SharedHandle<DHTPeerAnnounceEntry>
|
||||||
DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash)
|
DHTPeerAnnounceStorage::getPeerAnnounceEntry(const unsigned char* infoHash)
|
||||||
{
|
{
|
||||||
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
||||||
|
|
||||||
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
|
DHTPeerAnnounceEntrySet::iterator i = entries_.lower_bound(entry);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), entry, InfoHashLess());
|
|
||||||
|
|
||||||
if(i != entries_.end() &&
|
if(i != entries_.end() &&
|
||||||
memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) {
|
memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0) {
|
||||||
|
@ -107,11 +101,8 @@ void DHTPeerAnnounceStorage::getPeers(std::vector<SharedHandle<Peer> >& peers,
|
||||||
{
|
{
|
||||||
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
SharedHandle<DHTPeerAnnounceEntry> entry(new DHTPeerAnnounceEntry(infoHash));
|
||||||
|
|
||||||
std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
|
DHTPeerAnnounceEntrySet::iterator i = entries_.find(entry);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), entry, InfoHashLess());
|
if(i != entries_.end()) {
|
||||||
if(i != entries_.end() &&
|
|
||||||
memcmp(infoHash, (*i)->getInfoHash(), DHT_ID_LENGTH) == 0 &&
|
|
||||||
!(*i)->empty()) {
|
|
||||||
(*i)->getPeers(peers);
|
(*i)->getPeers(peers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,9 +123,14 @@ void DHTPeerAnnounceStorage::handleTimeout()
|
||||||
A2_LOG_DEBUG(fmt("Now purge peer announces(%lu entries) which are timed out.",
|
A2_LOG_DEBUG(fmt("Now purge peer announces(%lu entries) which are timed out.",
|
||||||
static_cast<unsigned long>(entries_.size())));
|
static_cast<unsigned long>(entries_.size())));
|
||||||
std::for_each(entries_.begin(), entries_.end(), RemoveStalePeerAddrEntry());
|
std::for_each(entries_.begin(), entries_.end(), RemoveStalePeerAddrEntry());
|
||||||
entries_.erase(std::remove_if(entries_.begin(), entries_.end(),
|
for(DHTPeerAnnounceEntrySet::iterator i = entries_.begin(),
|
||||||
mem_fun_sh(&DHTPeerAnnounceEntry::empty)),
|
eoi = entries_.end(); i != eoi;) {
|
||||||
entries_.end());
|
if((*i)->empty()) {
|
||||||
|
entries_.erase(i++);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
A2_LOG_DEBUG(fmt("Currently %lu peer announce entries",
|
A2_LOG_DEBUG(fmt("Currently %lu peer announce entries",
|
||||||
static_cast<unsigned long>(entries_.size())));
|
static_cast<unsigned long>(entries_.size())));
|
||||||
}
|
}
|
||||||
|
@ -142,7 +138,7 @@ void DHTPeerAnnounceStorage::handleTimeout()
|
||||||
void DHTPeerAnnounceStorage::announcePeer()
|
void DHTPeerAnnounceStorage::announcePeer()
|
||||||
{
|
{
|
||||||
A2_LOG_DEBUG("Now announcing peer.");
|
A2_LOG_DEBUG("Now announcing peer.");
|
||||||
for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
|
for(DHTPeerAnnounceEntrySet::iterator i =
|
||||||
entries_.begin(), eoi = entries_.end(); i != eoi; ++i) {
|
entries_.begin(), eoi = entries_.end(); i != eoi; ++i) {
|
||||||
if((*i)->getLastUpdated().
|
if((*i)->getLastUpdated().
|
||||||
difference(global::wallclock()) >= DHT_PEER_ANNOUNCE_INTERVAL) {
|
difference(global::wallclock()) >= DHT_PEER_ANNOUNCE_INTERVAL) {
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -52,7 +52,14 @@ class DHTTaskFactory;
|
||||||
|
|
||||||
class DHTPeerAnnounceStorage {
|
class DHTPeerAnnounceStorage {
|
||||||
private:
|
private:
|
||||||
std::deque<SharedHandle<DHTPeerAnnounceEntry> > entries_;
|
class InfoHashLess {
|
||||||
|
public:
|
||||||
|
bool operator()(const SharedHandle<DHTPeerAnnounceEntry>& lhs,
|
||||||
|
const SharedHandle<DHTPeerAnnounceEntry>& rhs);
|
||||||
|
};
|
||||||
|
typedef std::set<SharedHandle<DHTPeerAnnounceEntry>, InfoHashLess>
|
||||||
|
DHTPeerAnnounceEntrySet;
|
||||||
|
DHTPeerAnnounceEntrySet entries_;
|
||||||
|
|
||||||
SharedHandle<DHTPeerAnnounceEntry> getPeerAnnounceEntry(const unsigned char* infoHash);
|
SharedHandle<DHTPeerAnnounceEntry> getPeerAnnounceEntry(const unsigned char* infoHash);
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,16 @@ DNSCache::CacheEntry& DNSCache::CacheEntry::operator=(const CacheEntry& c)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSCache::CacheEntry::add(const std::string& addr)
|
bool DNSCache::CacheEntry::add(const std::string& addr)
|
||||||
{
|
{
|
||||||
|
for(std::vector<AddrEntry>::const_iterator i = addrEntries_.begin(),
|
||||||
|
eoi = addrEntries_.end(); i != eoi; ++i) {
|
||||||
|
if((*i).addr_ == addr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
addrEntries_.push_back(AddrEntry(addr));
|
addrEntries_.push_back(AddrEntry(addr));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DNSCache::AddrEntry>::iterator DNSCache::CacheEntry::find
|
std::vector<DNSCache::AddrEntry>::iterator DNSCache::CacheEntry::find
|
||||||
|
@ -160,50 +167,42 @@ DNSCache& DNSCache::operator=(const DNSCache& c)
|
||||||
const std::string& DNSCache::find
|
const std::string& DNSCache::find
|
||||||
(const std::string& hostname, uint16_t port) const
|
(const std::string& hostname, uint16_t port) const
|
||||||
{
|
{
|
||||||
CacheEntry target(hostname, port);
|
SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
|
||||||
std::deque<CacheEntry>::const_iterator i =
|
CacheEntrySet::iterator i = entries_.find(target);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), target);
|
if(i == entries_.end()) {
|
||||||
if(i != entries_.end() && (*i) == target) {
|
|
||||||
return (*i).getGoodAddr();
|
|
||||||
}
|
|
||||||
return A2STR::NIL;
|
return A2STR::NIL;
|
||||||
|
} else {
|
||||||
|
return (*i)->getGoodAddr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSCache::put
|
void DNSCache::put
|
||||||
(const std::string& hostname, const std::string& ipaddr, uint16_t port)
|
(const std::string& hostname, const std::string& ipaddr, uint16_t port)
|
||||||
{
|
{
|
||||||
CacheEntry target(hostname, port);
|
SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
|
||||||
std::deque<CacheEntry>::iterator i =
|
CacheEntrySet::iterator i = entries_.lower_bound(target);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), target);
|
if(i != entries_.end() && *(*i) == *target) {
|
||||||
if(i == entries_.end() || !((*i) == target)) {
|
(*i)->add(ipaddr);
|
||||||
target.add(ipaddr);
|
|
||||||
entries_.insert(i, target);
|
|
||||||
} else {
|
} else {
|
||||||
if(!(*i).contains(ipaddr)) {
|
target->add(ipaddr);
|
||||||
(*i).add(ipaddr);
|
entries_.insert(i, target);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSCache::markBad
|
void DNSCache::markBad
|
||||||
(const std::string& hostname, const std::string& ipaddr, uint16_t port)
|
(const std::string& hostname, const std::string& ipaddr, uint16_t port)
|
||||||
{
|
{
|
||||||
CacheEntry target(hostname, port);
|
SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
|
||||||
std::deque<CacheEntry>::iterator i =
|
CacheEntrySet::iterator i = entries_.find(target);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), target);
|
if(i != entries_.end()) {
|
||||||
if(i != entries_.end() && (*i) == target) {
|
(*i)->markBad(ipaddr);
|
||||||
(*i).markBad(ipaddr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSCache::remove(const std::string& hostname, uint16_t port)
|
void DNSCache::remove(const std::string& hostname, uint16_t port)
|
||||||
{
|
{
|
||||||
CacheEntry target(hostname, port);
|
SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
|
||||||
std::deque<CacheEntry>::iterator i =
|
entries_.erase(target);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), target);
|
|
||||||
if(i != entries_.end() && (*i) == target) {
|
|
||||||
entries_.erase(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -38,10 +38,12 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
class DNSCache {
|
class DNSCache {
|
||||||
|
@ -68,7 +70,7 @@ private:
|
||||||
|
|
||||||
CacheEntry& operator=(const CacheEntry& c);
|
CacheEntry& operator=(const CacheEntry& c);
|
||||||
|
|
||||||
void add(const std::string& addr);
|
bool add(const std::string& addr);
|
||||||
|
|
||||||
std::vector<AddrEntry>::iterator find(const std::string& addr);
|
std::vector<AddrEntry>::iterator find(const std::string& addr);
|
||||||
|
|
||||||
|
@ -96,8 +98,9 @@ private:
|
||||||
bool operator==(const CacheEntry& e) const;
|
bool operator==(const CacheEntry& e) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::deque<CacheEntry> entries_;
|
typedef std::set<SharedHandle<CacheEntry>,
|
||||||
|
DerefLess<SharedHandle<CacheEntry> > > CacheEntrySet;
|
||||||
|
CacheEntrySet entries_;
|
||||||
public:
|
public:
|
||||||
DNSCache();
|
DNSCache();
|
||||||
DNSCache(const DNSCache& c);
|
DNSCache(const DNSCache& c);
|
||||||
|
@ -111,11 +114,10 @@ public:
|
||||||
void findAll
|
void findAll
|
||||||
(OutputIterator out, const std::string& hostname, uint16_t port) const
|
(OutputIterator out, const std::string& hostname, uint16_t port) const
|
||||||
{
|
{
|
||||||
CacheEntry target(hostname, port);
|
SharedHandle<CacheEntry> target(new CacheEntry(hostname, port));
|
||||||
std::deque<CacheEntry>::const_iterator i =
|
CacheEntrySet::iterator i = entries_.find(target);
|
||||||
std::lower_bound(entries_.begin(), entries_.end(), target);
|
if(i != entries_.end()) {
|
||||||
if(i != entries_.end() && (*i) == target) {
|
(*i)->getAllGoodAddrs(out);
|
||||||
(*i).getAllGoodAddrs(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,10 +140,7 @@ SharedHandle<Piece> DefaultPieceStorage::getPiece(size_t index)
|
||||||
|
|
||||||
void DefaultPieceStorage::addUsedPiece(const SharedHandle<Piece>& piece)
|
void DefaultPieceStorage::addUsedPiece(const SharedHandle<Piece>& piece)
|
||||||
{
|
{
|
||||||
std::deque<SharedHandle<Piece> >::iterator i =
|
usedPieces_.insert(piece);
|
||||||
std::lower_bound(usedPieces_.begin(), usedPieces_.end(), piece,
|
|
||||||
DerefLess<SharedHandle<Piece> >());
|
|
||||||
usedPieces_.insert(i, piece);
|
|
||||||
A2_LOG_DEBUG(fmt("usedPieces_.size()=%lu",
|
A2_LOG_DEBUG(fmt("usedPieces_.size()=%lu",
|
||||||
static_cast<unsigned long>(usedPieces_.size())));
|
static_cast<unsigned long>(usedPieces_.size())));
|
||||||
}
|
}
|
||||||
|
@ -153,14 +150,12 @@ SharedHandle<Piece> DefaultPieceStorage::findUsedPiece(size_t index) const
|
||||||
SharedHandle<Piece> p(new Piece());
|
SharedHandle<Piece> p(new Piece());
|
||||||
p->setIndex(index);
|
p->setIndex(index);
|
||||||
|
|
||||||
std::deque<SharedHandle<Piece> >::const_iterator i =
|
UsedPieceSet::iterator i = usedPieces_.find(p);
|
||||||
std::lower_bound(usedPieces_.begin(), usedPieces_.end(), p,
|
if(i == usedPieces_.end()) {
|
||||||
DerefLess<SharedHandle<Piece> >());
|
|
||||||
if(i != usedPieces_.end() && *(*i) == *p) {
|
|
||||||
return *i;
|
|
||||||
} else {
|
|
||||||
p.reset();
|
p.reset();
|
||||||
return p;
|
return p;
|
||||||
|
} else {
|
||||||
|
return *i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +233,7 @@ void unsetExcludedIndexes(BitfieldMan& bitfield,
|
||||||
void DefaultPieceStorage::createFastIndexBitfield
|
void DefaultPieceStorage::createFastIndexBitfield
|
||||||
(BitfieldMan& bitfield, const SharedHandle<Peer>& peer)
|
(BitfieldMan& bitfield, const SharedHandle<Peer>& peer)
|
||||||
{
|
{
|
||||||
for(std::vector<size_t>::const_iterator itr =
|
for(std::set<size_t>::const_iterator itr =
|
||||||
peer->getPeerAllowedIndexSet().begin(),
|
peer->getPeerAllowedIndexSet().begin(),
|
||||||
eoi = peer->getPeerAllowedIndexSet().end(); itr != eoi; ++itr) {
|
eoi = peer->getPeerAllowedIndexSet().end(); itr != eoi; ++itr) {
|
||||||
if(!bitfieldMan_->isBitSet(*itr) && peer->hasPiece(*itr)) {
|
if(!bitfieldMan_->isBitSet(*itr) && peer->hasPiece(*itr)) {
|
||||||
|
@ -405,12 +400,7 @@ void DefaultPieceStorage::deleteUsedPiece(const SharedHandle<Piece>& piece)
|
||||||
if(!piece) {
|
if(!piece) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::deque<SharedHandle<Piece> >::iterator i =
|
usedPieces_.erase(piece);
|
||||||
std::lower_bound(usedPieces_.begin(), usedPieces_.end(), piece,
|
|
||||||
DerefLess<SharedHandle<Piece> >());
|
|
||||||
if(i != usedPieces_.end() && *(*i) == *piece) {
|
|
||||||
usedPieces_.erase(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// void DefaultPieceStorage::reduceUsedPieces(size_t upperBound)
|
// void DefaultPieceStorage::reduceUsedPieces(size_t upperBound)
|
||||||
|
@ -758,9 +748,7 @@ void DefaultPieceStorage::markPieceMissing(size_t index)
|
||||||
void DefaultPieceStorage::addInFlightPiece
|
void DefaultPieceStorage::addInFlightPiece
|
||||||
(const std::vector<SharedHandle<Piece> >& pieces)
|
(const std::vector<SharedHandle<Piece> >& pieces)
|
||||||
{
|
{
|
||||||
usedPieces_.insert(usedPieces_.end(), pieces.begin(), pieces.end());
|
usedPieces_.insert(pieces.begin(), pieces.end());
|
||||||
std::sort(usedPieces_.begin(), usedPieces_.end(),
|
|
||||||
DerefLess<SharedHandle<Piece> >());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DefaultPieceStorage::countInFlightPiece()
|
size_t DefaultPieceStorage::countInFlightPiece()
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
#include "PieceStorage.h"
|
#include "PieceStorage.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -76,7 +79,9 @@ private:
|
||||||
BitfieldMan* bitfieldMan_;
|
BitfieldMan* bitfieldMan_;
|
||||||
SharedHandle<DiskAdaptor> diskAdaptor_;
|
SharedHandle<DiskAdaptor> diskAdaptor_;
|
||||||
SharedHandle<DiskWriterFactory> diskWriterFactory_;
|
SharedHandle<DiskWriterFactory> diskWriterFactory_;
|
||||||
std::deque<SharedHandle<Piece> > usedPieces_;
|
typedef std::set<SharedHandle<Piece>,
|
||||||
|
DerefLess<SharedHandle<Piece> > > UsedPieceSet;
|
||||||
|
UsedPieceSet usedPieces_;
|
||||||
|
|
||||||
bool endGame_;
|
bool endGame_;
|
||||||
size_t endGamePieceNum_;
|
size_t endGamePieceNum_;
|
||||||
|
|
|
@ -132,7 +132,7 @@ void EpollEventPoll::poll(const struct timeval& tv)
|
||||||
// own timeout and ares may create new sockets or closes socket in
|
// own timeout and ares may create new sockets or closes socket in
|
||||||
// their API. So we call ares_process_fd for all ares_channel and
|
// their API. So we call ares_process_fd for all ares_channel and
|
||||||
// re-register their sockets.
|
// re-register their sockets.
|
||||||
for(std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator i =
|
for(KAsyncNameResolverEntrySet::iterator i =
|
||||||
nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
|
nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
|
||||||
i != eoi; ++i) {
|
i != eoi; ++i) {
|
||||||
(*i)->processTimeout();
|
(*i)->processTimeout();
|
||||||
|
@ -169,9 +169,7 @@ bool EpollEventPoll::addEvents(sock_t socket,
|
||||||
const EpollEventPoll::KEvent& event)
|
const EpollEventPoll::KEvent& event)
|
||||||
{
|
{
|
||||||
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
KSocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
|
||||||
DerefLess<SharedHandle<KSocketEntry> >());
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int errNum = 0;
|
int errNum = 0;
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
||||||
|
@ -232,13 +230,12 @@ bool EpollEventPoll::deleteEvents(sock_t socket,
|
||||||
const EpollEventPoll::KEvent& event)
|
const EpollEventPoll::KEvent& event)
|
||||||
{
|
{
|
||||||
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
KSocketEntrySet::iterator i = socketEntries_.find(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
if(i == socketEntries_.end()) {
|
||||||
DerefLess<SharedHandle<KSocketEntry> >());
|
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
return false;
|
||||||
|
} else {
|
||||||
event.removeSelf(*i);
|
event.removeSelf(*i);
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int errNum = 0;
|
int errNum = 0;
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
|
@ -266,9 +263,6 @@ bool EpollEventPoll::deleteEvents(sock_t socket,
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,15 +287,14 @@ bool EpollEventPoll::addNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<KAsyncNameResolverEntry> entry
|
SharedHandle<KAsyncNameResolverEntry> entry
|
||||||
(new KAsyncNameResolverEntry(resolver, command));
|
(new KAsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
|
KAsyncNameResolverEntrySet::iterator itr =
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
nameResolverEntries_.lower_bound(entry);
|
||||||
derefEqual(entry));
|
if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
|
||||||
if(itr == nameResolverEntries_.end()) {
|
return false;
|
||||||
nameResolverEntries_.push_back(entry);
|
} else {
|
||||||
|
nameResolverEntries_.insert(itr, entry);
|
||||||
entry->addSocketEvents(this);
|
entry->addSocketEvents(this);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,9 +303,8 @@ bool EpollEventPoll::deleteNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<KAsyncNameResolverEntry> entry
|
SharedHandle<KAsyncNameResolverEntry> entry
|
||||||
(new KAsyncNameResolverEntry(resolver, command));
|
(new KAsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
|
KAsyncNameResolverEntrySet::iterator itr =
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
nameResolverEntries_.find(entry);
|
||||||
derefEqual(entry));
|
|
||||||
if(itr == nameResolverEntries_.end()) {
|
if(itr == nameResolverEntries_.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,9 +39,10 @@
|
||||||
|
|
||||||
# include <sys/epoll.h>
|
# include <sys/epoll.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <set>
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "a2functional.h"
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
# include "AsyncNameResolver.h"
|
# include "AsyncNameResolver.h"
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
@ -69,9 +70,14 @@ private:
|
||||||
friend int accumulateEvent(int events, const KEvent& event);
|
friend int accumulateEvent(int events, const KEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<SharedHandle<KSocketEntry> > socketEntries_;
|
typedef std::set<SharedHandle<KSocketEntry>,
|
||||||
|
DerefLess<SharedHandle<KSocketEntry> > > KSocketEntrySet;
|
||||||
|
KSocketEntrySet socketEntries_;
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> > nameResolverEntries_;
|
typedef std::set<SharedHandle<KAsyncNameResolverEntry>,
|
||||||
|
DerefLess<SharedHandle<KAsyncNameResolverEntry> > >
|
||||||
|
KAsyncNameResolverEntrySet;
|
||||||
|
KAsyncNameResolverEntrySet nameResolverEntries_;
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
int epfd_;
|
int epfd_;
|
||||||
|
|
|
@ -327,6 +327,13 @@ public:
|
||||||
command_ == entry.command_;
|
command_ == entry.command_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const AsyncNameResolverEntry& entry)
|
||||||
|
{
|
||||||
|
return nameResolver_.get() < entry.nameResolver_.get() ||
|
||||||
|
(nameResolver_.get() == entry.nameResolver_.get() &&
|
||||||
|
command_ < entry.command_);
|
||||||
|
}
|
||||||
|
|
||||||
void addSocketEvents(EventPoll* e)
|
void addSocketEvents(EventPoll* e)
|
||||||
{
|
{
|
||||||
socketsSize_ = 0;
|
socketsSize_ = 0;
|
||||||
|
|
|
@ -51,6 +51,21 @@
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
bool FileEntry::RequestFaster::operator()
|
||||||
|
(const SharedHandle<Request>& lhs,
|
||||||
|
const SharedHandle<Request>& rhs) const
|
||||||
|
{
|
||||||
|
if(!lhs->getPeerStat()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!rhs->getPeerStat()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int lspd = lhs->getPeerStat()->getAvgDownloadSpeed();
|
||||||
|
int rspd = rhs->getPeerStat()->getAvgDownloadSpeed();
|
||||||
|
return lspd > rspd || (lspd == rspd && lhs.get() < rhs.get());
|
||||||
|
}
|
||||||
|
|
||||||
FileEntry::FileEntry
|
FileEntry::FileEntry
|
||||||
(const std::string& path,
|
(const std::string& path,
|
||||||
off_t length,
|
off_t length,
|
||||||
|
@ -158,7 +173,7 @@ FileEntry::getRequest
|
||||||
req->setReferer(util::percentEncodeMini(referer));
|
req->setReferer(util::percentEncodeMini(referer));
|
||||||
req->setMethod(method);
|
req->setMethod(method);
|
||||||
spentUris_.push_back(uri);
|
spentUris_.push_back(uri);
|
||||||
inFlightRequests_.push_back(req);
|
inFlightRequests_.insert(req);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
req.reset();
|
req.reset();
|
||||||
|
@ -177,8 +192,8 @@ FileEntry::getRequest
|
||||||
// sleeping(Request::getWakeTime() < global::wallclock()). If all
|
// sleeping(Request::getWakeTime() < global::wallclock()). If all
|
||||||
// pooled objects are sleeping, return first one. Caller should
|
// pooled objects are sleeping, return first one. Caller should
|
||||||
// inspect returned object's getWakeTime().
|
// inspect returned object's getWakeTime().
|
||||||
std::deque<SharedHandle<Request> >::iterator i = requestPool_.begin();
|
RequestPool::iterator i = requestPool_.begin();
|
||||||
std::deque<SharedHandle<Request> >::iterator eoi = requestPool_.end();
|
RequestPool::iterator eoi = requestPool_.end();
|
||||||
for(; i != eoi; ++i) {
|
for(; i != eoi; ++i) {
|
||||||
if((*i)->getWakeTime() <= global::wallclock()) {
|
if((*i)->getWakeTime() <= global::wallclock()) {
|
||||||
break;
|
break;
|
||||||
|
@ -189,7 +204,7 @@ FileEntry::getRequest
|
||||||
}
|
}
|
||||||
req = *i;
|
req = *i;
|
||||||
requestPool_.erase(i);
|
requestPool_.erase(i);
|
||||||
inFlightRequests_.push_back(req);
|
inFlightRequests_.insert(req);
|
||||||
A2_LOG_DEBUG(fmt("Picked up from pool: %s", req->getUri().c_str()));
|
A2_LOG_DEBUG(fmt("Picked up from pool: %s", req->getUri().c_str()));
|
||||||
}
|
}
|
||||||
return req;
|
return req;
|
||||||
|
@ -203,7 +218,8 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
|
||||||
lastFasterReplace_.difference(global::wallclock()) < startupIdleTime) {
|
lastFasterReplace_.difference(global::wallclock()) < startupIdleTime) {
|
||||||
return SharedHandle<Request>();
|
return SharedHandle<Request>();
|
||||||
}
|
}
|
||||||
const SharedHandle<PeerStat>& fastest = requestPool_.front()->getPeerStat();
|
const SharedHandle<PeerStat>& fastest =
|
||||||
|
(*requestPool_.begin())->getPeerStat();
|
||||||
if(!fastest) {
|
if(!fastest) {
|
||||||
return SharedHandle<Request>();
|
return SharedHandle<Request>();
|
||||||
}
|
}
|
||||||
|
@ -214,9 +230,9 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
|
||||||
difference(global::wallclock()) >= startupIdleTime &&
|
difference(global::wallclock()) >= startupIdleTime &&
|
||||||
fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){
|
fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){
|
||||||
// TODO we should consider that "fastest" is very slow.
|
// TODO we should consider that "fastest" is very slow.
|
||||||
SharedHandle<Request> fastestRequest = requestPool_.front();
|
SharedHandle<Request> fastestRequest = *requestPool_.begin();
|
||||||
requestPool_.pop_front();
|
requestPool_.erase(requestPool_.begin());
|
||||||
inFlightRequests_.push_back(fastestRequest);
|
inFlightRequests_.insert(fastestRequest);
|
||||||
lastFasterReplace_ = global::wallclock();
|
lastFasterReplace_ = global::wallclock();
|
||||||
return fastestRequest;
|
return fastestRequest;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +295,7 @@ FileEntry::findFasterRequest
|
||||||
fastestRequest->setReferer(base->getReferer());
|
fastestRequest->setReferer(base->getReferer());
|
||||||
uris_.erase(std::find(uris_.begin(), uris_.end(), uri));
|
uris_.erase(std::find(uris_.begin(), uris_.end(), uri));
|
||||||
spentUris_.push_back(uri);
|
spentUris_.push_back(uri);
|
||||||
inFlightRequests_.push_back(fastestRequest);
|
inFlightRequests_.insert(fastestRequest);
|
||||||
lastFasterReplace_ = global::wallclock();
|
lastFasterReplace_ = global::wallclock();
|
||||||
return fastestRequest;
|
return fastestRequest;
|
||||||
}
|
}
|
||||||
|
@ -287,24 +303,6 @@ FileEntry::findFasterRequest
|
||||||
return SharedHandle<Request>();
|
return SharedHandle<Request>();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
class RequestFaster {
|
|
||||||
public:
|
|
||||||
bool operator()(const SharedHandle<Request>& lhs,
|
|
||||||
const SharedHandle<Request>& rhs) const
|
|
||||||
{
|
|
||||||
if(!lhs->getPeerStat()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!rhs->getPeerStat()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return
|
|
||||||
lhs->getPeerStat()->getAvgDownloadSpeed() > rhs->getPeerStat()->getAvgDownloadSpeed();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void FileEntry::storePool(const SharedHandle<Request>& request)
|
void FileEntry::storePool(const SharedHandle<Request>& request)
|
||||||
{
|
{
|
||||||
const SharedHandle<PeerStat>& peerStat = request->getPeerStat();
|
const SharedHandle<PeerStat>& peerStat = request->getPeerStat();
|
||||||
|
@ -313,10 +311,7 @@ void FileEntry::storePool(const SharedHandle<Request>& request)
|
||||||
// store Request in the right position in the pool.
|
// store Request in the right position in the pool.
|
||||||
peerStat->calculateAvgDownloadSpeed();
|
peerStat->calculateAvgDownloadSpeed();
|
||||||
}
|
}
|
||||||
std::deque<SharedHandle<Request> >::iterator i =
|
requestPool_.insert(request);
|
||||||
std::lower_bound(requestPool_.begin(), requestPool_.end(), request,
|
|
||||||
RequestFaster());
|
|
||||||
requestPool_.insert(i, request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileEntry::poolRequest(const SharedHandle<Request>& request)
|
void FileEntry::poolRequest(const SharedHandle<Request>& request)
|
||||||
|
@ -329,15 +324,7 @@ void FileEntry::poolRequest(const SharedHandle<Request>& request)
|
||||||
|
|
||||||
bool FileEntry::removeRequest(const SharedHandle<Request>& request)
|
bool FileEntry::removeRequest(const SharedHandle<Request>& request)
|
||||||
{
|
{
|
||||||
for(std::deque<SharedHandle<Request> >::iterator i =
|
return inFlightRequests_.erase(request) == 1;
|
||||||
inFlightRequests_.begin(), eoi = inFlightRequests_.end();
|
|
||||||
i != eoi; ++i) {
|
|
||||||
if((*i).get() == request.get()) {
|
|
||||||
inFlightRequests_.erase(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileEntry::removeURIWhoseHostnameIs(const std::string& hostname)
|
void FileEntry::removeURIWhoseHostnameIs(const std::string& hostname)
|
||||||
|
@ -500,10 +487,11 @@ bool FileEntry::removeUri(const std::string& uri)
|
||||||
} else {
|
} else {
|
||||||
spentUris_.erase(itr);
|
spentUris_.erase(itr);
|
||||||
SharedHandle<Request> req;
|
SharedHandle<Request> req;
|
||||||
std::deque<SharedHandle<Request> >::iterator riter =
|
InFlightRequestSet::iterator riter =
|
||||||
findRequestByUri(inFlightRequests_.begin(), inFlightRequests_.end(), uri);
|
findRequestByUri(inFlightRequests_.begin(), inFlightRequests_.end(), uri);
|
||||||
if(riter == inFlightRequests_.end()) {
|
if(riter == inFlightRequests_.end()) {
|
||||||
riter = findRequestByUri(requestPool_.begin(), requestPool_.end(), uri);
|
RequestPool::iterator riter = findRequestByUri(requestPool_.begin(),
|
||||||
|
requestPool_.end(), uri);
|
||||||
if(riter == requestPool_.end()) {
|
if(riter == requestPool_.end()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
#include "A2STR.h"
|
#include "A2STR.h"
|
||||||
#include "TimerA2.h"
|
#include "TimerA2.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -57,6 +59,9 @@ class URISelector;
|
||||||
class ServerStatMan;
|
class ServerStatMan;
|
||||||
|
|
||||||
class FileEntry {
|
class FileEntry {
|
||||||
|
public:
|
||||||
|
typedef std::set<SharedHandle<Request>, RefLess<Request> >
|
||||||
|
InFlightRequestSet;
|
||||||
private:
|
private:
|
||||||
std::string path_;
|
std::string path_;
|
||||||
std::deque<std::string> uris_;
|
std::deque<std::string> uris_;
|
||||||
|
@ -64,8 +69,16 @@ private:
|
||||||
off_t length_;
|
off_t length_;
|
||||||
off_t offset_;
|
off_t offset_;
|
||||||
bool requested_;
|
bool requested_;
|
||||||
std::deque<SharedHandle<Request> > requestPool_;
|
|
||||||
std::deque<SharedHandle<Request> > inFlightRequests_;
|
class RequestFaster {
|
||||||
|
public:
|
||||||
|
bool operator()(const SharedHandle<Request>& lhs,
|
||||||
|
const SharedHandle<Request>& rhs) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::set<SharedHandle<Request>, RequestFaster> RequestPool;
|
||||||
|
RequestPool requestPool_;
|
||||||
|
InFlightRequestSet inFlightRequests_;
|
||||||
std::string contentType_;
|
std::string contentType_;
|
||||||
// URIResult is stored in the ascending order of the time when its result is
|
// URIResult is stored in the ascending order of the time when its result is
|
||||||
// available.
|
// available.
|
||||||
|
@ -186,7 +199,7 @@ public:
|
||||||
|
|
||||||
size_t countPooledRequest() const;
|
size_t countPooledRequest() const;
|
||||||
|
|
||||||
const std::deque<SharedHandle<Request> >& getInFlightRequests() const
|
const InFlightRequestSet& getInFlightRequests() const
|
||||||
{
|
{
|
||||||
return inFlightRequests_;
|
return inFlightRequests_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,7 +287,7 @@ size_t Peer::countPeerAllowedIndexSet() const
|
||||||
return res_->peerAllowedIndexSet().size();
|
return res_->peerAllowedIndexSet().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<size_t>& Peer::getPeerAllowedIndexSet() const
|
const std::set<size_t>& Peer::getPeerAllowedIndexSet() const
|
||||||
{
|
{
|
||||||
assert(res_);
|
assert(res_);
|
||||||
return res_->peerAllowedIndexSet();
|
return res_->peerAllowedIndexSet();
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
|
@ -265,7 +265,7 @@ public:
|
||||||
|
|
||||||
size_t countPeerAllowedIndexSet() const;
|
size_t countPeerAllowedIndexSet() const;
|
||||||
|
|
||||||
const std::vector<size_t>& getPeerAllowedIndexSet() const;
|
const std::set<size_t>& getPeerAllowedIndexSet() const;
|
||||||
|
|
||||||
void addAmAllowedIndex(size_t index);
|
void addAmAllowedIndex(size_t index);
|
||||||
|
|
||||||
|
|
|
@ -162,43 +162,29 @@ void PeerSessionResource::fastExtensionEnabled(bool b)
|
||||||
fastExtensionEnabled_ = b;
|
fastExtensionEnabled_ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<size_t>& PeerSessionResource::peerAllowedIndexSet() const
|
const std::set<size_t>& PeerSessionResource::peerAllowedIndexSet() const
|
||||||
{
|
{
|
||||||
return peerAllowedIndexSet_;
|
return peerAllowedIndexSet_;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
void updateIndexSet(std::vector<size_t>& c, size_t index)
|
|
||||||
{
|
|
||||||
std::vector<size_t>::iterator i = std::lower_bound(c.begin(), c.end(), index);
|
|
||||||
if(i == c.end() || (*i) != index) {
|
|
||||||
c.insert(i, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void PeerSessionResource::addPeerAllowedIndex(size_t index)
|
void PeerSessionResource::addPeerAllowedIndex(size_t index)
|
||||||
{
|
{
|
||||||
updateIndexSet(peerAllowedIndexSet_, index);
|
peerAllowedIndexSet_.insert(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerSessionResource::peerAllowedIndexSetContains(size_t index) const
|
bool PeerSessionResource::peerAllowedIndexSetContains(size_t index) const
|
||||||
{
|
{
|
||||||
return std::binary_search(peerAllowedIndexSet_.begin(),
|
return peerAllowedIndexSet_.count(index) == 1;
|
||||||
peerAllowedIndexSet_.end(),
|
|
||||||
index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerSessionResource::addAmAllowedIndex(size_t index)
|
void PeerSessionResource::addAmAllowedIndex(size_t index)
|
||||||
{
|
{
|
||||||
updateIndexSet(amAllowedIndexSet_, index);
|
amAllowedIndexSet_.insert(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PeerSessionResource::amAllowedIndexSetContains(size_t index) const
|
bool PeerSessionResource::amAllowedIndexSetContains(size_t index) const
|
||||||
{
|
{
|
||||||
return std::binary_search(amAllowedIndexSet_.begin(),
|
return amAllowedIndexSet_.count(index) == 1;
|
||||||
amAllowedIndexSet_.end(),
|
|
||||||
index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerSessionResource::extendedMessagingEnabled(bool b)
|
void PeerSessionResource::extendedMessagingEnabled(bool b)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <set>
|
||||||
|
|
||||||
#include "BtConstants.h"
|
#include "BtConstants.h"
|
||||||
#include "PeerStat.h"
|
#include "PeerStat.h"
|
||||||
|
@ -69,9 +69,9 @@ private:
|
||||||
BitfieldMan* bitfieldMan_;
|
BitfieldMan* bitfieldMan_;
|
||||||
bool fastExtensionEnabled_;
|
bool fastExtensionEnabled_;
|
||||||
// fast index set which a peer has sent to localhost.
|
// fast index set which a peer has sent to localhost.
|
||||||
std::vector<size_t> peerAllowedIndexSet_;
|
std::set<size_t> peerAllowedIndexSet_;
|
||||||
// fast index set which localhost has sent to a peer.
|
// fast index set which localhost has sent to a peer.
|
||||||
std::vector<size_t> amAllowedIndexSet_;
|
std::set<size_t> amAllowedIndexSet_;
|
||||||
bool extendedMessagingEnabled_;
|
bool extendedMessagingEnabled_;
|
||||||
Extensions extensions_;
|
Extensions extensions_;
|
||||||
bool dhtEnabled_;
|
bool dhtEnabled_;
|
||||||
|
@ -169,14 +169,14 @@ public:
|
||||||
void fastExtensionEnabled(bool b);
|
void fastExtensionEnabled(bool b);
|
||||||
|
|
||||||
// fast index set which a peer has sent to localhost.
|
// fast index set which a peer has sent to localhost.
|
||||||
const std::vector<size_t>& peerAllowedIndexSet() const;
|
const std::set<size_t>& peerAllowedIndexSet() const;
|
||||||
|
|
||||||
void addPeerAllowedIndex(size_t index);
|
void addPeerAllowedIndex(size_t index);
|
||||||
|
|
||||||
bool peerAllowedIndexSetContains(size_t index) const;
|
bool peerAllowedIndexSetContains(size_t index) const;
|
||||||
|
|
||||||
// fast index set which localhost has sent to a peer.
|
// fast index set which localhost has sent to a peer.
|
||||||
const std::vector<size_t>& amAllowedIndexSet() const
|
const std::set<size_t>& amAllowedIndexSet() const
|
||||||
{
|
{
|
||||||
return amAllowedIndexSet_;
|
return amAllowedIndexSet_;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,14 +101,12 @@ void PollEventPoll::poll(const struct timeval& tv)
|
||||||
first != last; ++first) {
|
first != last; ++first) {
|
||||||
if(first->revents) {
|
if(first->revents) {
|
||||||
se->setSocket(first->fd);
|
se->setSocket(first->fd);
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator itr =
|
KSocketEntrySet::iterator itr = socketEntries_.find(se);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), se,
|
if(itr == socketEntries_.end()) {
|
||||||
DerefLess<SharedHandle<KSocketEntry> >());
|
|
||||||
if(itr != socketEntries_.end() && *(*itr) == *se) {
|
|
||||||
(*itr)->processEvents(first->revents);
|
|
||||||
} else {
|
|
||||||
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.",
|
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.",
|
||||||
first->fd));
|
first->fd));
|
||||||
|
} else {
|
||||||
|
(*itr)->processEvents(first->revents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,9 +119,8 @@ void PollEventPoll::poll(const struct timeval& tv)
|
||||||
// own timeout and ares may create new sockets or closes socket in
|
// own timeout and ares may create new sockets or closes socket in
|
||||||
// their API. So we call ares_process_fd for all ares_channel and
|
// their API. So we call ares_process_fd for all ares_channel and
|
||||||
// re-register their sockets.
|
// re-register their sockets.
|
||||||
for(std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator i =
|
for(KAsyncNameResolverEntrySet::iterator i = nameResolverEntries_.begin(),
|
||||||
nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
|
eoi = nameResolverEntries_.end(); i != eoi; ++i) {
|
||||||
i != eoi; ++i) {
|
|
||||||
(*i)->processTimeout();
|
(*i)->processTimeout();
|
||||||
(*i)->removeSocketEvents(this);
|
(*i)->removeSocketEvents(this);
|
||||||
(*i)->addSocketEvents(this);
|
(*i)->addSocketEvents(this);
|
||||||
|
@ -156,9 +153,7 @@ bool PollEventPoll::addEvents
|
||||||
(sock_t socket, const PollEventPoll::KEvent& event)
|
(sock_t socket, const PollEventPoll::KEvent& event)
|
||||||
{
|
{
|
||||||
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
KSocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
|
||||||
DerefLess<SharedHandle<KSocketEntry> >());
|
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
||||||
event.addSelf(*i);
|
event.addSelf(*i);
|
||||||
for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
|
for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
|
||||||
|
@ -204,10 +199,11 @@ bool PollEventPoll::deleteEvents
|
||||||
(sock_t socket, const PollEventPoll::KEvent& event)
|
(sock_t socket, const PollEventPoll::KEvent& event)
|
||||||
{
|
{
|
||||||
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
SharedHandle<KSocketEntry> socketEntry(new KSocketEntry(socket));
|
||||||
std::deque<SharedHandle<KSocketEntry> >::iterator i =
|
KSocketEntrySet::iterator i = socketEntries_.find(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
if(i == socketEntries_.end()) {
|
||||||
DerefLess<SharedHandle<KSocketEntry> >());
|
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
return false;
|
||||||
|
} else {
|
||||||
event.removeSelf(*i);
|
event.removeSelf(*i);
|
||||||
for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
|
for(struct pollfd* first = pollfds_, *last = pollfds_+pollfdNum_;
|
||||||
first != last; ++first) {
|
first != last; ++first) {
|
||||||
|
@ -225,9 +221,6 @@ bool PollEventPoll::deleteEvents
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,15 +245,14 @@ bool PollEventPoll::addNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<KAsyncNameResolverEntry> entry
|
SharedHandle<KAsyncNameResolverEntry> entry
|
||||||
(new KAsyncNameResolverEntry(resolver, command));
|
(new KAsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
|
KAsyncNameResolverEntrySet::iterator itr =
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
nameResolverEntries_.lower_bound(entry);
|
||||||
derefEqual(entry));
|
if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
|
||||||
if(itr == nameResolverEntries_.end()) {
|
return false;
|
||||||
nameResolverEntries_.push_back(entry);
|
} else {
|
||||||
|
nameResolverEntries_.insert(itr, entry);
|
||||||
entry->addSocketEvents(this);
|
entry->addSocketEvents(this);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,9 +261,7 @@ bool PollEventPoll::deleteNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<KAsyncNameResolverEntry> entry
|
SharedHandle<KAsyncNameResolverEntry> entry
|
||||||
(new KAsyncNameResolverEntry(resolver, command));
|
(new KAsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> >::iterator itr =
|
KAsyncNameResolverEntrySet::iterator itr = nameResolverEntries_.find(entry);
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
|
||||||
derefEqual(entry));
|
|
||||||
if(itr == nameResolverEntries_.end()) {
|
if(itr == nameResolverEntries_.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,9 +39,10 @@
|
||||||
|
|
||||||
# include <poll.h>
|
# include <poll.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <set>
|
||||||
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
|
#include "a2functional.h"
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
# include "AsyncNameResolver.h"
|
# include "AsyncNameResolver.h"
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
@ -69,9 +70,14 @@ private:
|
||||||
friend int accumulateEvent(int events, const KEvent& event);
|
friend int accumulateEvent(int events, const KEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::deque<SharedHandle<KSocketEntry> > socketEntries_;
|
typedef std::set<SharedHandle<KSocketEntry>,
|
||||||
|
DerefLess<SharedHandle<KSocketEntry> > > KSocketEntrySet;
|
||||||
|
KSocketEntrySet socketEntries_;
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
std::deque<SharedHandle<KAsyncNameResolverEntry> > nameResolverEntries_;
|
typedef std::set<SharedHandle<KAsyncNameResolverEntry>,
|
||||||
|
DerefLess<SharedHandle<KAsyncNameResolverEntry> > >
|
||||||
|
KAsyncNameResolverEntrySet;
|
||||||
|
KAsyncNameResolverEntrySet nameResolverEntries_;
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
// Allocated the number of struct pollfd in pollfds_.
|
// Allocated the number of struct pollfd in pollfds_.
|
||||||
|
|
|
@ -971,9 +971,9 @@ void RequestGroupMan::getUsedHosts
|
||||||
std::vector<Triplet<size_t, int, std::string> > tempHosts;
|
std::vector<Triplet<size_t, int, std::string> > tempHosts;
|
||||||
for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
|
for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
|
||||||
requestGroups_.begin(), eoi = requestGroups_.end(); i != eoi; ++i) {
|
requestGroups_.begin(), eoi = requestGroups_.end(); i != eoi; ++i) {
|
||||||
const std::deque<SharedHandle<Request> >& inFlightReqs =
|
const FileEntry::InFlightRequestSet& inFlightReqs =
|
||||||
(*i)->getDownloadContext()->getFirstFileEntry()->getInFlightRequests();
|
(*i)->getDownloadContext()->getFirstFileEntry()->getInFlightRequests();
|
||||||
for(std::deque<SharedHandle<Request> >::const_iterator j =
|
for(FileEntry::InFlightRequestSet::iterator j =
|
||||||
inFlightReqs.begin(), eoj = inFlightReqs.end(); j != eoj; ++j) {
|
inFlightReqs.begin(), eoj = inFlightReqs.end(); j != eoj; ++j) {
|
||||||
uri::UriStruct us;
|
uri::UriStruct us;
|
||||||
if(uri::parse(us, (*j)->getUri())) {
|
if(uri::parse(us, (*j)->getUri())) {
|
||||||
|
|
|
@ -1368,9 +1368,9 @@ SharedHandle<ValueBase> GetServersRpcMethod::process
|
||||||
SharedHandle<Dict> fileEntry = Dict::g();
|
SharedHandle<Dict> fileEntry = Dict::g();
|
||||||
fileEntry->put(KEY_INDEX, util::uitos(index));
|
fileEntry->put(KEY_INDEX, util::uitos(index));
|
||||||
SharedHandle<List> servers = List::g();
|
SharedHandle<List> servers = List::g();
|
||||||
const std::deque<SharedHandle<Request> >& requests =
|
const FileEntry::InFlightRequestSet& requests =
|
||||||
(*fi)->getInFlightRequests();
|
(*fi)->getInFlightRequests();
|
||||||
for(std::deque<SharedHandle<Request> >::const_iterator ri =requests.begin(),
|
for(FileEntry::InFlightRequestSet::iterator ri =requests.begin(),
|
||||||
eoi = requests.end(); ri != eoi; ++ri) {
|
eoi = requests.end(); ri != eoi; ++ri) {
|
||||||
SharedHandle<PeerStat> ps = (*ri)->getPeerStat();
|
SharedHandle<PeerStat> ps = (*ri)->getPeerStat();
|
||||||
if(ps) {
|
if(ps) {
|
||||||
|
|
|
@ -181,9 +181,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
for(std::deque<SharedHandle<AsyncNameResolverEntry> >::const_iterator itr =
|
for(AsyncNameResolverEntrySet::iterator itr = nameResolverEntries_.begin(),
|
||||||
nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
|
eoi = nameResolverEntries_.end(); itr != eoi; ++itr) {
|
||||||
itr != eoi; ++itr) {
|
|
||||||
const SharedHandle<AsyncNameResolverEntry>& entry = *itr;
|
const SharedHandle<AsyncNameResolverEntry>& entry = *itr;
|
||||||
int fd = entry->getFds(&rfds, &wfds);
|
int fd = entry->getFds(&rfds, &wfds);
|
||||||
// TODO force error if fd == 0
|
// TODO force error if fd == 0
|
||||||
|
@ -203,8 +202,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
|
||||||
#endif // !__MINGW32__
|
#endif // !__MINGW32__
|
||||||
} while(retval == -1 && errno == EINTR);
|
} while(retval == -1 && errno == EINTR);
|
||||||
if(retval > 0) {
|
if(retval > 0) {
|
||||||
for(std::deque<SharedHandle<SocketEntry> >::const_iterator i =
|
for(SocketEntrySet::iterator i = socketEntries_.begin(),
|
||||||
socketEntries_.begin(), eoi = socketEntries_.end(); i != eoi; ++i) {
|
eoi = socketEntries_.end(); i != eoi; ++i) {
|
||||||
int events = 0;
|
int events = 0;
|
||||||
if(FD_ISSET((*i)->getSocket(), &rfds)) {
|
if(FD_ISSET((*i)->getSocket(), &rfds)) {
|
||||||
events |= EventPoll::EVENT_READ;
|
events |= EventPoll::EVENT_READ;
|
||||||
|
@ -220,9 +219,8 @@ void SelectEventPoll::poll(const struct timeval& tv)
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
for(std::deque<SharedHandle<AsyncNameResolverEntry> >::const_iterator i =
|
for(AsyncNameResolverEntrySet::iterator i = nameResolverEntries_.begin(),
|
||||||
nameResolverEntries_.begin(), eoi = nameResolverEntries_.end();
|
eoi = nameResolverEntries_.end(); i != eoi; ++i) {
|
||||||
i != eoi; ++i) {
|
|
||||||
(*i)->process(&rfds, &wfds);
|
(*i)->process(&rfds, &wfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +248,8 @@ void SelectEventPoll::updateFdSet()
|
||||||
#endif // !__MINGW32__
|
#endif // !__MINGW32__
|
||||||
FD_ZERO(&rfdset_);
|
FD_ZERO(&rfdset_);
|
||||||
FD_ZERO(&wfdset_);
|
FD_ZERO(&wfdset_);
|
||||||
for(std::deque<SharedHandle<SocketEntry> >::const_iterator i =
|
for(SocketEntrySet::iterator i = socketEntries_.begin(),
|
||||||
socketEntries_.begin(), eoi = socketEntries_.end(); i != eoi; ++i) {
|
eoi = socketEntries_.end(); i != eoi; ++i) {
|
||||||
sock_t fd = (*i)->getSocket();
|
sock_t fd = (*i)->getSocket();
|
||||||
#ifndef __MINGW32__
|
#ifndef __MINGW32__
|
||||||
if(fd < 0 || FD_SETSIZE <= fd) {
|
if(fd < 0 || FD_SETSIZE <= fd) {
|
||||||
|
@ -283,9 +281,7 @@ bool SelectEventPoll::addEvents(sock_t socket, Command* command,
|
||||||
EventPoll::EventType events)
|
EventPoll::EventType events)
|
||||||
{
|
{
|
||||||
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
||||||
std::deque<SharedHandle<SocketEntry> >::iterator i =
|
SocketEntrySet::iterator i = socketEntries_.lower_bound(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
|
||||||
DerefLess<SharedHandle<SocketEntry> >());
|
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
||||||
(*i)->addCommandEvent(command, events);
|
(*i)->addCommandEvent(command, events);
|
||||||
} else {
|
} else {
|
||||||
|
@ -300,19 +296,17 @@ bool SelectEventPoll::deleteEvents(sock_t socket, Command* command,
|
||||||
EventPoll::EventType events)
|
EventPoll::EventType events)
|
||||||
{
|
{
|
||||||
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
SharedHandle<SocketEntry> socketEntry(new SocketEntry(socket));
|
||||||
std::deque<SharedHandle<SocketEntry> >::iterator i =
|
SocketEntrySet::iterator i = socketEntries_.find(socketEntry);
|
||||||
std::lower_bound(socketEntries_.begin(), socketEntries_.end(), socketEntry,
|
if(i == socketEntries_.end()) {
|
||||||
DerefLess<SharedHandle<SocketEntry> >());
|
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
||||||
if(i != socketEntries_.end() && *(*i) == *socketEntry) {
|
return false;
|
||||||
|
} else {
|
||||||
(*i)->removeCommandEvent(command, events);
|
(*i)->removeCommandEvent(command, events);
|
||||||
if((*i)->eventEmpty()) {
|
if((*i)->eventEmpty()) {
|
||||||
socketEntries_.erase(i);
|
socketEntries_.erase(i);
|
||||||
}
|
}
|
||||||
updateFdSet();
|
updateFdSet();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
A2_LOG_DEBUG(fmt("Socket %d is not found in SocketEntries.", socket));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,14 +316,13 @@ bool SelectEventPoll::addNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<AsyncNameResolverEntry> entry
|
SharedHandle<AsyncNameResolverEntry> entry
|
||||||
(new AsyncNameResolverEntry(resolver, command));
|
(new AsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<AsyncNameResolverEntry> >::iterator itr =
|
AsyncNameResolverEntrySet::iterator itr =
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
nameResolverEntries_.lower_bound(entry);
|
||||||
derefEqual(entry));
|
if(itr != nameResolverEntries_.end() && *(*itr) == *entry) {
|
||||||
if(itr == nameResolverEntries_.end()) {
|
|
||||||
nameResolverEntries_.push_back(entry);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
return false;
|
||||||
|
} else {
|
||||||
|
nameResolverEntries_.insert(itr, entry);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,15 +331,7 @@ bool SelectEventPoll::deleteNameResolver
|
||||||
{
|
{
|
||||||
SharedHandle<AsyncNameResolverEntry> entry
|
SharedHandle<AsyncNameResolverEntry> entry
|
||||||
(new AsyncNameResolverEntry(resolver, command));
|
(new AsyncNameResolverEntry(resolver, command));
|
||||||
std::deque<SharedHandle<AsyncNameResolverEntry> >::iterator itr =
|
return nameResolverEntries_.erase(entry) == 1;
|
||||||
std::find_if(nameResolverEntries_.begin(), nameResolverEntries_.end(),
|
|
||||||
derefEqual(entry));
|
|
||||||
if(itr == nameResolverEntries_.end()) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
nameResolverEntries_.erase(itr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,9 @@
|
||||||
#include "EventPoll.h"
|
#include "EventPoll.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "a2functional.h"
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
# include "AsyncNameResolver.h"
|
# include "AsyncNameResolver.h"
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
@ -145,6 +147,13 @@ private:
|
||||||
command_ == entry.command_;
|
command_ == entry.command_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(const AsyncNameResolverEntry& entry)
|
||||||
|
{
|
||||||
|
return nameResolver_.get() < entry.nameResolver_.get() ||
|
||||||
|
(nameResolver_.get() == entry.nameResolver_.get() &&
|
||||||
|
command_ < entry.command_);
|
||||||
|
}
|
||||||
|
|
||||||
int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
int getFds(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||||
|
|
||||||
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
void process(fd_set* rfdsPtr, fd_set* wfdsPtr);
|
||||||
|
@ -155,9 +164,14 @@ private:
|
||||||
fd_set wfdset_;
|
fd_set wfdset_;
|
||||||
sock_t fdmax_;
|
sock_t fdmax_;
|
||||||
|
|
||||||
std::deque<SharedHandle<SocketEntry> > socketEntries_;
|
typedef std::set<SharedHandle<SocketEntry>,
|
||||||
|
DerefLess<SharedHandle<SocketEntry> > > SocketEntrySet;
|
||||||
|
SocketEntrySet socketEntries_;
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
std::deque<SharedHandle<AsyncNameResolverEntry> > nameResolverEntries_;
|
typedef std::set<SharedHandle<AsyncNameResolverEntry>,
|
||||||
|
DerefLess<SharedHandle<AsyncNameResolverEntry> > >
|
||||||
|
AsyncNameResolverEntrySet;
|
||||||
|
AsyncNameResolverEntrySet nameResolverEntries_;
|
||||||
#endif // ENABLE_ASYNC_DNS
|
#endif // ENABLE_ASYNC_DNS
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
|
|
@ -191,12 +191,8 @@ void ServerStat::setError()
|
||||||
|
|
||||||
bool ServerStat::operator<(const ServerStat& serverStat) const
|
bool ServerStat::operator<(const ServerStat& serverStat) const
|
||||||
{
|
{
|
||||||
int c = hostname_.compare(serverStat.hostname_);
|
return hostname_ < serverStat.hostname_ ||
|
||||||
if(c == 0) {
|
(hostname_ == serverStat.hostname_ && protocol_ < serverStat.protocol_);
|
||||||
return protocol_ < serverStat.protocol_;
|
|
||||||
} else {
|
|
||||||
return c < 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerStat::operator==(const ServerStat& serverStat) const
|
bool ServerStat::operator==(const ServerStat& serverStat) const
|
||||||
|
|
|
@ -61,23 +61,17 @@ SharedHandle<ServerStat> ServerStatMan::find(const std::string& hostname,
|
||||||
const std::string& protocol) const
|
const std::string& protocol) const
|
||||||
{
|
{
|
||||||
SharedHandle<ServerStat> ss(new ServerStat(hostname, protocol));
|
SharedHandle<ServerStat> ss(new ServerStat(hostname, protocol));
|
||||||
std::deque<SharedHandle<ServerStat> >::const_iterator i =
|
ServerStatSet::iterator i = serverStats_.find(ss);
|
||||||
std::lower_bound(serverStats_.begin(), serverStats_.end(), ss,
|
if(i == serverStats_.end()) {
|
||||||
DerefLess<SharedHandle<ServerStat> >());
|
|
||||||
if(i != serverStats_.end() &&
|
|
||||||
(*i)->getHostname() == hostname && (*i)->getProtocol() == protocol) {
|
|
||||||
return *i;
|
|
||||||
} else {
|
|
||||||
return SharedHandle<ServerStat>();
|
return SharedHandle<ServerStat>();
|
||||||
|
} else {
|
||||||
|
return *i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerStatMan::add(const SharedHandle<ServerStat>& serverStat)
|
bool ServerStatMan::add(const SharedHandle<ServerStat>& serverStat)
|
||||||
{
|
{
|
||||||
std::deque<SharedHandle<ServerStat> >::iterator i =
|
ServerStatSet::iterator i = serverStats_.lower_bound(serverStat);
|
||||||
std::lower_bound(serverStats_.begin(), serverStats_.end(), serverStat,
|
|
||||||
DerefLess<SharedHandle<ServerStat> >());
|
|
||||||
|
|
||||||
if(i != serverStats_.end() && *(*i) == *serverStat) {
|
if(i != serverStats_.end() && *(*i) == *serverStat) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,8 +91,8 @@ bool ServerStatMan::save(const std::string& filename) const
|
||||||
filename.c_str()));
|
filename.c_str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for(std::deque<SharedHandle<ServerStat> >::const_iterator i =
|
for(ServerStatSet::iterator i = serverStats_.begin(),
|
||||||
serverStats_.begin(), eoi = serverStats_.end(); i != eoi; ++i) {
|
eoi = serverStats_.end(); i != eoi; ++i) {
|
||||||
std::string l = (*i)->toString();
|
std::string l = (*i)->toString();
|
||||||
l += "\n";
|
l += "\n";
|
||||||
if(fp.write(l.data(), l.size()) != l.size()) {
|
if(fp.write(l.data(), l.size()) != l.size()) {
|
||||||
|
@ -217,9 +211,15 @@ public:
|
||||||
|
|
||||||
void ServerStatMan::removeStaleServerStat(time_t timeout)
|
void ServerStatMan::removeStaleServerStat(time_t timeout)
|
||||||
{
|
{
|
||||||
serverStats_.erase(std::remove_if(serverStats_.begin(), serverStats_.end(),
|
FindStaleServerStat finder(timeout);
|
||||||
FindStaleServerStat(timeout)),
|
for(ServerStatSet::iterator i = serverStats_.begin(),
|
||||||
serverStats_.end());
|
eoi = serverStats_.end(); i != eoi;) {
|
||||||
|
if(finder(*i)) {
|
||||||
|
serverStats_.erase(i++);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -37,10 +37,11 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <deque>
|
#include <set>
|
||||||
|
|
||||||
#include "SharedHandle.h"
|
#include "SharedHandle.h"
|
||||||
#include "a2time.h"
|
#include "a2time.h"
|
||||||
|
#include "a2functional.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -63,7 +64,9 @@ public:
|
||||||
|
|
||||||
void removeStaleServerStat(time_t timeout);
|
void removeStaleServerStat(time_t timeout);
|
||||||
private:
|
private:
|
||||||
std::deque<SharedHandle<ServerStat> > serverStats_;
|
typedef std::set<SharedHandle<ServerStat>,
|
||||||
|
DerefLess<SharedHandle<ServerStat> > > ServerStatSet;
|
||||||
|
ServerStatSet serverStats_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -70,9 +70,9 @@ void StreamFileAllocationEntry::prepareForNextAction
|
||||||
dctx->getFileEntries();
|
dctx->getFileEntries();
|
||||||
for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
|
for(std::vector<SharedHandle<FileEntry> >::const_iterator i =
|
||||||
fileEntries.begin(), eoi = fileEntries.end(); i != eoi; ++i) {
|
fileEntries.begin(), eoi = fileEntries.end(); i != eoi; ++i) {
|
||||||
const std::deque<SharedHandle<Request> >& reqs =
|
const FileEntry::InFlightRequestSet& reqs =
|
||||||
(*i)->getInFlightRequests();
|
(*i)->getInFlightRequests();
|
||||||
for(std::deque<SharedHandle<Request> >::const_iterator j =
|
for(FileEntry::InFlightRequestSet::iterator j =
|
||||||
reqs.begin(), eoj = reqs.end(); j != eoj; ++j) {
|
reqs.begin(), eoj = reqs.end(); j != eoj; ++j) {
|
||||||
const SharedHandle<PeerStat>& peerStat = (*j)->getPeerStat();
|
const SharedHandle<PeerStat>& peerStat = (*j)->getPeerStat();
|
||||||
if(peerStat) {
|
if(peerStat) {
|
||||||
|
|
|
@ -286,6 +286,12 @@ std::string strjoin(InputIterator first, InputIterator last,
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class LeastRecentAccess:public std::binary_function<T, T, bool> {
|
class LeastRecentAccess:public std::binary_function<T, T, bool> {
|
||||||
public:
|
public:
|
||||||
|
bool operator()(const SharedHandle<T>& lhs,
|
||||||
|
const SharedHandle<T>& rhs) const
|
||||||
|
{
|
||||||
|
return lhs->getLastAccessTime() < rhs->getLastAccessTime();
|
||||||
|
}
|
||||||
|
|
||||||
bool operator()(const T& lhs, const T& rhs) const
|
bool operator()(const T& lhs, const T& rhs) const
|
||||||
{
|
{
|
||||||
return lhs.getLastAccessTime() < rhs.getLastAccessTime();
|
return lhs.getLastAccessTime() < rhs.getLastAccessTime();
|
||||||
|
|
|
@ -195,6 +195,21 @@ void AuthConfigFactoryTest::testCreateAuthConfig_ftp()
|
||||||
factory.createAuthConfig(req, &option)->getAuthText());
|
factory.createAuthConfig(req, &option)->getAuthText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
SharedHandle<AuthConfigFactory::BasicCred>
|
||||||
|
createBasicCred(const std::string& user,
|
||||||
|
const std::string& password,
|
||||||
|
const std::string& host, uint16_t port,
|
||||||
|
const std::string& path,
|
||||||
|
bool activated = false)
|
||||||
|
{
|
||||||
|
SharedHandle<AuthConfigFactory::BasicCred> bc
|
||||||
|
(new AuthConfigFactory::BasicCred(user, password, host, port, path,
|
||||||
|
activated));
|
||||||
|
return bc;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void AuthConfigFactoryTest::testUpdateBasicCred()
|
void AuthConfigFactoryTest::testUpdateBasicCred()
|
||||||
{
|
{
|
||||||
Option option;
|
Option option;
|
||||||
|
@ -204,15 +219,15 @@ void AuthConfigFactoryTest::testUpdateBasicCred()
|
||||||
AuthConfigFactory factory;
|
AuthConfigFactory factory;
|
||||||
|
|
||||||
factory.updateBasicCred
|
factory.updateBasicCred
|
||||||
(AuthConfigFactory::BasicCred("myname", "mypass", "localhost", 80, "/", true));
|
(createBasicCred("myname", "mypass", "localhost", 80, "/", true));
|
||||||
factory.updateBasicCred
|
factory.updateBasicCred
|
||||||
(AuthConfigFactory::BasicCred("price", "j38jdc", "localhost", 80, "/download", true));
|
(createBasicCred("price", "j38jdc", "localhost", 80, "/download", true));
|
||||||
factory.updateBasicCred
|
factory.updateBasicCred
|
||||||
(AuthConfigFactory::BasicCred("soap", "planB", "localhost", 80, "/download/beta", true));
|
(createBasicCred("soap", "planB", "localhost", 80, "/download/beta", true));
|
||||||
factory.updateBasicCred
|
factory.updateBasicCred
|
||||||
(AuthConfigFactory::BasicCred("alice", "ium8", "localhost", 80, "/documents", true));
|
(createBasicCred("alice", "ium8", "localhost", 80, "/documents", true));
|
||||||
factory.updateBasicCred
|
factory.updateBasicCred
|
||||||
(AuthConfigFactory::BasicCred("jack", "jackx", "mirror", 80, "/doc", true));
|
(createBasicCred("jack", "jackx", "mirror", 80, "/doc", true));
|
||||||
|
|
||||||
SharedHandle<Request> req(new Request());
|
SharedHandle<Request> req(new Request());
|
||||||
req->setUri("http://localhost/download/v2.6/Changelog");
|
req->setUri("http://localhost/download/v2.6/Changelog");
|
||||||
|
|
Loading…
Reference in New Issue