Index: chrome/browser/autofill/autofill_download.cc |
=================================================================== |
--- chrome/browser/autofill/autofill_download.cc (revision 72523) |
+++ chrome/browser/autofill/autofill_download.cc (working copy) |
@@ -27,6 +27,10 @@ |
#define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "SOMESERVER/" |
#endif |
+namespace { |
+const size_t kMaxFormCacheSize = 16; |
+}; |
+ |
struct AutoFillDownloadManager::FormRequestData { |
std::vector<std::string> form_signatures; |
AutoFillRequestType request_type; |
@@ -35,6 +39,7 @@ |
AutoFillDownloadManager::AutoFillDownloadManager(Profile* profile) |
: profile_(profile), |
observer_(NULL), |
+ max_form_cache_size_(kMaxFormCacheSize), |
next_query_request_(base::Time::Now()), |
next_upload_request_(base::Time::Now()), |
positive_upload_rate_(0), |
@@ -76,12 +81,22 @@ |
std::string form_xml; |
FormRequestData request_data; |
if (!FormStructure::EncodeQueryRequest(forms, &request_data.form_signatures, |
- &form_xml)) |
+ &form_xml)) { |
return false; |
+ } |
request_data.request_type = AutoFillDownloadManager::REQUEST_QUERY; |
metric_logger.Log(AutoFillMetrics::QUERY_SENT); |
+ std::string query_data; |
+ if (CheckCacheForQueryRequest(request_data.form_signatures, &query_data)) { |
+ VLOG(1) << "AutoFillDownloadManager: query request has been retrieved from" |
+ << "the cache"; |
+ if (observer_) |
+ observer_->OnLoadedAutoFillHeuristics(query_data); |
+ return true; |
+ } |
+ |
return StartRequest(form_xml, request_data); |
} |
@@ -188,6 +203,60 @@ |
return true; |
} |
+void AutoFillDownloadManager::CacheQueryRequest( |
+ const std::vector<std::string>& forms_in_query, |
+ const std::string& query_data) { |
+ std::string signature = GetCombinedSignature(forms_in_query); |
+ for (QueryRequestCache::iterator it = cached_forms_.begin(); |
+ it != cached_forms_.end(); ++it) { |
+ if (it->first == signature) { |
+ // We hit the cache, move to the first position and return. |
+ std::pair<std::string, std::string> data = *it; |
+ cached_forms_.erase(it); |
+ cached_forms_.push_front(data); |
+ return; |
+ } |
+ } |
+ std::pair<std::string, std::string> data; |
+ data.first = signature; |
+ data.second = query_data; |
+ cached_forms_.push_front(data); |
+ while (cached_forms_.size() > max_form_cache_size_) |
+ cached_forms_.pop_back(); |
+} |
+ |
+bool AutoFillDownloadManager::CheckCacheForQueryRequest( |
+ const std::vector<std::string>& forms_in_query, |
+ std::string* query_data) const { |
+ std::string signature = GetCombinedSignature(forms_in_query); |
+ for (QueryRequestCache::const_iterator it = cached_forms_.begin(); |
+ it != cached_forms_.end(); ++it) { |
+ if (it->first == signature) { |
+ // We hit the cache, fill the data and return. |
+ *query_data = it->second; |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+std::string AutoFillDownloadManager::GetCombinedSignature( |
+ const std::vector<std::string>& forms_in_query) const { |
+ size_t total_size = forms_in_query.size(); |
+ for (size_t i = 0; i < forms_in_query.size(); ++i) |
+ total_size += forms_in_query[i].length(); |
+ std::string signature; |
+ |
+ signature.reserve(total_size); |
+ |
+ for (size_t i = 0; i < forms_in_query.size(); ++i) { |
+ if (i) |
+ signature.append(","); |
+ signature.append(forms_in_query[i]); |
+ } |
+ return signature; |
+} |
+ |
void AutoFillDownloadManager::OnURLFetchComplete( |
const URLFetcher* source, |
const GURL& url, |
@@ -250,6 +319,7 @@ |
VLOG(1) << "AutoFillDownloadManager: " << type_of_request |
<< " request has succeeded"; |
if (it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY) { |
+ CacheQueryRequest(it->second.form_signatures, data); |
if (observer_) |
observer_->OnLoadedAutoFillHeuristics(data); |
} else { |