Index: chrome/browser/history/history_backend.cc |
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc |
index 2915f141be09a7d764099c19a4abf84708a15b6d..47c889c4a4e465527f8d3a3db67b0dbbee946aa4 100644 |
--- a/chrome/browser/history/history_backend.cc |
+++ b/chrome/browser/history/history_backend.cc |
@@ -25,6 +25,7 @@ |
#include "chrome/browser/history/history_publisher.h" |
#include "chrome/browser/history/in_memory_history_backend.h" |
#include "chrome/browser/history/page_usage_data.h" |
+#include "chrome/browser/history/time_filter.h" |
#include "chrome/browser/history/top_sites.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_notification_types.h" |
@@ -1410,6 +1411,76 @@ void HistoryBackend::QueryMostVisitedURLs( |
request->ForwardResult(request->handle(), *result); |
} |
+void HistoryBackend::QueryMostVisitedURLsDuringTime( |
+ scoped_refptr<QueryMostVisitedURLsRequest> request, |
+ int result_count, |
+ const history::TimeFilter& filter) { |
+ if (request->canceled()) |
+ return; |
+ |
+ if (!db_.get()) { |
+ // No History Database - return an empty list. |
+ request->ForwardResult(request->handle(), MostVisitedURLList()); |
+ return; |
+ } |
+ |
+ VisitVector visits; |
+ db_->GetVisibleVisitsDuringTimes(filter, 0, &visits); |
+ |
+ std::map<URLID, double> score_map; |
+ const double kLn2 = 0.6931471805599453; |
+ base::Time now = base::Time::Now(); |
+ for (size_t i = 0; i < visits.size(); ++i) { |
+ // Decay score by half each week. |
+ base::TimeDelta time_passed = now - visits[i].visit_time; |
+ // Clamp to 0 in case time jumps backwards (e.g. due to DST). |
+ double decay_exponent = std::max(0.0, kLn2 * static_cast<double>( |
+ time_passed.InMicroseconds()) / base::Time::kMicrosecondsPerWeek); |
+ double score = 1.0 / exp(decay_exponent); |
+ std::map<URLID, double>::iterator it = score_map.find(visits[i].url_id); |
+ if (it == score_map.end()) |
+ score_map[visits[i].url_id] = score; |
+ else |
+ it->second += score; |
+ } |
+ |
+ ScopedVector<PageUsageData> data; |
+ data->reserve(score_map.size()); |
+ for (std::map<URLID, double>::iterator it = score_map.begin(); |
+ it != score_map.end(); ++it) { |
+ PageUsageData *one_url = new PageUsageData(it->first); |
+ one_url->SetScore(it->second); |
+ data->push_back(one_url); |
+ } |
+ |
+ // Limit to the top |result_count| results. |
+ std::sort(data.begin(), data.end(), PageUsageData::Predicate); |
+ if (result_count && static_cast<int>(data.size()) > result_count) { |
+ STLDeleteContainerPointers(data.begin() + result_count, data.end()); |
+ data.resize(result_count); |
+ } |
+ |
+ for (size_t i = 0; i < data->size(); ++i) { |
+ PageUsageData* pud = data[i]; |
+ URLRow info; |
+ if (db_->GetURLRow(pud->GetID(), &info)) { |
+ pud->SetURL(info.url()); |
+ pud->SetTitle(info.title()); |
+ } |
+ } |
+ |
+ MostVisitedURLList& result = request->value; |
+ for (size_t i = 0; i < data.size(); ++i) { |
+ PageUsageData* current_data = data[i]; |
+ RedirectList redirects; |
+ GetMostRecentRedirectsFrom(current_data->GetURL(), &redirects); |
+ MostVisitedURL url = MakeMostVisitedURL(*current_data, redirects); |
+ result.push_back(url); |
+ } |
+ |
+ request->ForwardResult(request->handle(), result); |
+} |
+ |
void HistoryBackend::QueryMostVisitedURLsImpl(int result_count, |
int days_back, |
MostVisitedURLList* result) { |