summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/FileEntry.cc136
-rw-r--r--src/FileEntry.h6
2 files changed, 88 insertions, 54 deletions
diff --git a/src/FileEntry.cc b/src/FileEntry.cc
index f2770c28..95b3f50a 100644
--- a/src/FileEntry.cc
+++ b/src/FileEntry.cc
@@ -136,79 +136,107 @@ OutputIterator enumerateInFlightHosts(InputIterator first, InputIterator last,
}
} // namespace
-std::shared_ptr<Request> FileEntry::getRequest(
+std::shared_ptr<Request> FileEntry::getRequestWithInFlightHosts(
URISelector* selector, bool uriReuse,
const std::vector<std::pair<size_t, std::string>>& usedHosts,
- const std::string& referer, const std::string& method)
+ const std::string& referer, const std::string& method,
+ const std::vector<std::string>& inFlightHosts)
{
std::shared_ptr<Request> req;
- if (requestPool_.empty()) {
- std::vector<std::string> inFlightHosts;
- enumerateInFlightHosts(inFlightRequests_.begin(), inFlightRequests_.end(),
- std::back_inserter(inFlightHosts));
- for (int g = 0; g < 2; ++g) {
- std::vector<std::string> pending;
- std::vector<std::string> ignoreHost;
- while (1) {
- std::string uri = selector->select(this, usedHosts);
- if (uri.empty()) {
- break;
+
+ for (int g = 0; g < 2; ++g) {
+ std::vector<std::string> pending;
+ std::vector<std::string> ignoreHost;
+ while (1) {
+ std::string uri = selector->select(this, usedHosts);
+ if (uri.empty()) {
+ break;
+ }
+ req = std::make_shared<Request>();
+ if (req->setUri(uri)) {
+ if (std::count(std::begin(inFlightHosts), std::end(inFlightHosts),
+ req->getHost()) >= maxConnectionPerServer_) {
+ pending.push_back(uri);
+ ignoreHost.push_back(req->getHost());
+ req.reset();
+ continue;
}
- req = std::make_shared<Request>();
- if (req->setUri(uri)) {
- if (std::count(inFlightHosts.begin(), inFlightHosts.end(),
- req->getHost()) >= maxConnectionPerServer_) {
- pending.push_back(uri);
- ignoreHost.push_back(req->getHost());
- req.reset();
- continue;
- }
- if (referer == "*") {
- // Assuming uri has already been percent-encoded.
- req->setReferer(uri);
- }
- else {
- req->setReferer(util::percentEncodeMini(referer));
- }
- req->setMethod(method);
- spentUris_.push_back(uri);
- inFlightRequests_.insert(req);
- break;
+ if (referer == "*") {
+ // Assuming uri has already been percent-encoded.
+ req->setReferer(uri);
}
else {
- req.reset();
+ req->setReferer(util::percentEncodeMini(referer));
}
- }
- uris_.insert(uris_.begin(), pending.begin(), pending.end());
- if (g == 0 && uriReuse && !req && uris_.size() == pending.size()) {
- // Reuse URIs other than ones in pending
- reuseUri(ignoreHost);
+ req->setMethod(method);
+ spentUris_.push_back(uri);
+ inFlightRequests_.insert(req);
+ break;
}
else {
- break;
+ req.reset();
}
}
+ uris_.insert(std::begin(uris_), std::begin(pending), std::end(pending));
+ if (g == 0 && uriReuse && !req && uris_.size() == pending.size()) {
+ // Reuse URIs other than ones in pending
+ reuseUri(ignoreHost);
+ continue;
+ }
+
+ return req;
}
- else {
- // Skip Request object if it is still
- // sleeping(Request::getWakeTime() < global::wallclock()). If all
- // pooled objects are sleeping, return first one. Caller should
- // inspect returned object's getWakeTime().
- auto i = requestPool_.begin();
- auto eoi = requestPool_.end();
- for (; i != eoi; ++i) {
- if ((*i)->getWakeTime() <= global::wallclock()) {
- break;
- }
+}
+
+std::shared_ptr<Request> FileEntry::getRequest(
+ URISelector* selector, bool uriReuse,
+ const std::vector<std::pair<size_t, std::string>>& usedHosts,
+ const std::string& referer, const std::string& method)
+{
+ std::shared_ptr<Request> req;
+ if (requestPool_.empty()) {
+ std::vector<std::string> inFlightHosts;
+ enumerateInFlightHosts(std::begin(inFlightRequests_),
+ std::end(inFlightRequests_),
+ std::back_inserter(inFlightHosts));
+ return getRequestWithInFlightHosts(selector, uriReuse, usedHosts, referer,
+ method, inFlightHosts);
+ }
+
+ // Skip Request object if it is still
+ // sleeping(Request::getWakeTime() < global::wallclock()). If all
+ // pooled objects are sleeping, we may return first one. Caller
+ // should inspect returned object's getWakeTime().
+ auto i = std::begin(requestPool_);
+ for (; i != std::end(requestPool_); ++i) {
+ if ((*i)->getWakeTime() <= global::wallclock()) {
+ break;
}
- if (i == eoi) {
- i = requestPool_.begin();
+ }
+ if (i == std::end(requestPool_)) {
+ // all requests are sleeping; try to another URI
+ std::vector<std::string> inFlightHosts;
+ enumerateInFlightHosts(std::begin(inFlightRequests_),
+ std::end(inFlightRequests_),
+ std::back_inserter(inFlightHosts));
+ enumerateInFlightHosts(std::begin(requestPool_), std::end(requestPool_),
+ std::back_inserter(inFlightHosts));
+
+ req = getRequestWithInFlightHosts(selector, uriReuse, usedHosts, referer,
+ method, inFlightHosts);
+ if (!req || req->getUri() == (*std::begin(requestPool_))->getUri()) {
+ i = std::begin(requestPool_);
}
+ }
+
+ if (i != std::end(requestPool_)) {
req = *i;
requestPool_.erase(i);
- inFlightRequests_.insert(req);
A2_LOG_DEBUG(fmt("Picked up from pool: %s", req->getUri().c_str()));
}
+
+ inFlightRequests_.insert(req);
+
return req;
}
diff --git a/src/FileEntry.h b/src/FileEntry.h
index dc32e7f7..d304ce16 100644
--- a/src/FileEntry.h
+++ b/src/FileEntry.h
@@ -97,6 +97,12 @@ private:
void storePool(const std::shared_ptr<Request>& request);
+ std::shared_ptr<Request> getRequestWithInFlightHosts(
+ URISelector* selector, bool uriReuse,
+ const std::vector<std::pair<size_t, std::string>>& usedHosts,
+ const std::string& referer, const std::string& method,
+ const std::vector<std::string>& inFlightHosts);
+
public:
FileEntry();