Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: chrome/browser/autocomplete/shortcuts_provider.cc

Issue 10701043: Make ShortcutsBackend a ProfileKeyedService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/autocomplete/shortcuts_provider.h" 5 #include "chrome/browser/autocomplete/shortcuts_provider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <map> 9 #include <map>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/i18n/break_iterator.h" 12 #include "base/i18n/break_iterator.h"
13 #include "base/i18n/case_conversion.h" 13 #include "base/i18n/case_conversion.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/string_number_conversions.h" 16 #include "base/string_number_conversions.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/time.h" 18 #include "base/time.h"
19 #include "base/utf_string_conversions.h" 19 #include "base/utf_string_conversions.h"
20 #include "chrome/browser/autocomplete/autocomplete.h" 20 #include "chrome/browser/autocomplete/autocomplete.h"
21 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h" 21 #include "chrome/browser/autocomplete/autocomplete_provider_listener.h"
22 #include "chrome/browser/history/history.h" 22 #include "chrome/browser/history/history.h"
23 #include "chrome/browser/history/history_notifications.h" 23 #include "chrome/browser/history/history_notifications.h"
24 #include "chrome/browser/history/history_service_factory.h" 24 #include "chrome/browser/history/history_service_factory.h"
25 #include "chrome/browser/history/shortcuts_backend_factory.h"
25 #include "chrome/browser/prefs/pref_service.h" 26 #include "chrome/browser/prefs/pref_service.h"
26 #include "chrome/browser/profiles/profile.h" 27 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
28 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
29 #include "googleurl/src/url_parse.h" 30 #include "googleurl/src/url_parse.h"
30 31
31 namespace { 32 namespace {
32 33
33 class RemoveMatchPredicate { 34 class RemoveMatchPredicate {
34 public: 35 public:
35 explicit RemoveMatchPredicate(const std::set<GURL>& urls) 36 explicit RemoveMatchPredicate(const std::set<GURL>& urls)
36 : urls_(urls) { 37 : urls_(urls) {
37 } 38 }
38 bool operator()(const AutocompleteMatch& match) { 39 bool operator()(const AutocompleteMatch& match) {
39 return urls_.find(match.destination_url) != urls_.end(); 40 return urls_.find(match.destination_url) != urls_.end();
40 } 41 }
41 private: 42 private:
42 // Lifetime of the object is less than the lifetime of passed |urls|, so 43 // Lifetime of the object is less than the lifetime of passed |urls|, so
43 // it is safe to store reference. 44 // it is safe to store reference.
44 const std::set<GURL>& urls_; 45 const std::set<GURL>& urls_;
45 }; 46 };
46 47
47 } // namespace 48 } // namespace
48 49
49 ShortcutsProvider::ShortcutsProvider(AutocompleteProviderListener* listener, 50 ShortcutsProvider::ShortcutsProvider(AutocompleteProviderListener* listener,
50 Profile* profile) 51 Profile* profile)
51 : AutocompleteProvider(listener, profile, "ShortcutsProvider"), 52 : AutocompleteProvider(listener, profile, "ShortcutsProvider"),
52 languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)), 53 languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)),
53 initialized_(false), 54 initialized_(false) {
54 shortcuts_backend_(profile->GetShortcutsBackend()) { 55 scoped_refptr<history::ShortcutsBackend> backend =
55 if (shortcuts_backend_.get()) { 56 ShortcutsBackendFactory::GetForProfile(profile_);
56 shortcuts_backend_->AddObserver(this); 57 if (backend) {
57 if (shortcuts_backend_->initialized()) 58 backend->AddObserver(this);
59 if (backend->initialized())
58 initialized_ = true; 60 initialized_ = true;
59 } 61 }
60 } 62 }
61 63
62 void ShortcutsProvider::Start(const AutocompleteInput& input, 64 void ShortcutsProvider::Start(const AutocompleteInput& input,
63 bool minimal_changes) { 65 bool minimal_changes) {
64 matches_.clear(); 66 matches_.clear();
65 67
66 if ((input.type() == AutocompleteInput::INVALID) || 68 if ((input.type() == AutocompleteInput::INVALID) ||
67 (input.type() == AutocompleteInput::FORCED_QUERY)) 69 (input.type() == AutocompleteInput::FORCED_QUERY))
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 // Delete the match from the history DB. This will eventually result in a 104 // Delete the match from the history DB. This will eventually result in a
103 // second call to DeleteShortcutsWithURLs(), which is harmless. 105 // second call to DeleteShortcutsWithURLs(), which is harmless.
104 HistoryService* const history_service = 106 HistoryService* const history_service =
105 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); 107 HistoryServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
106 108
107 DCHECK(history_service && url.is_valid()); 109 DCHECK(history_service && url.is_valid());
108 history_service->DeleteURL(url); 110 history_service->DeleteURL(url);
109 } 111 }
110 112
111 ShortcutsProvider::~ShortcutsProvider() { 113 ShortcutsProvider::~ShortcutsProvider() {
112 if (shortcuts_backend_.get()) 114 scoped_refptr<history::ShortcutsBackend> backend =
113 shortcuts_backend_->RemoveObserver(this); 115 ShortcutsBackendFactory::GetForProfileIfExists(profile_);
116 if (backend)
117 backend->RemoveObserver(this);
114 } 118 }
115 119
116 void ShortcutsProvider::OnShortcutsLoaded() { 120 void ShortcutsProvider::OnShortcutsLoaded() {
117 initialized_ = true; 121 initialized_ = true;
118 } 122 }
119 123
120 void ShortcutsProvider::DeleteMatchesWithURLs(const std::set<GURL>& urls) { 124 void ShortcutsProvider::DeleteMatchesWithURLs(const std::set<GURL>& urls) {
121 std::remove_if(matches_.begin(), matches_.end(), RemoveMatchPredicate(urls)); 125 std::remove_if(matches_.begin(), matches_.end(), RemoveMatchPredicate(urls));
122 listener_->OnProviderUpdate(true); 126 listener_->OnProviderUpdate(true);
123 } 127 }
124 128
125 void ShortcutsProvider::DeleteShortcutsWithURLs(const std::set<GURL>& urls) { 129 void ShortcutsProvider::DeleteShortcutsWithURLs(const std::set<GURL>& urls) {
126 if (!shortcuts_backend_.get()) 130 scoped_refptr<history::ShortcutsBackend> backend =
131 ShortcutsBackendFactory::GetForProfileIfExists(profile_);
132 if (!backend)
127 return; // We are off the record. 133 return; // We are off the record.
128 for (std::set<GURL>::const_iterator url = urls.begin(); url != urls.end(); 134 for (std::set<GURL>::const_iterator url = urls.begin(); url != urls.end();
129 ++url) 135 ++url)
130 shortcuts_backend_->DeleteShortcutsWithUrl(*url); 136 backend->DeleteShortcutsWithUrl(*url);
131 } 137 }
132 138
133 void ShortcutsProvider::GetMatches(const AutocompleteInput& input) { 139 void ShortcutsProvider::GetMatches(const AutocompleteInput& input) {
140 scoped_refptr<history::ShortcutsBackend> backend =
141 ShortcutsBackendFactory::GetForProfileIfExists(profile_);
142 if (!backend)
143 return;
134 // Get the URLs from the shortcuts database with keys that partially or 144 // Get the URLs from the shortcuts database with keys that partially or
135 // completely match the search term. 145 // completely match the search term.
136 string16 term_string(base::i18n::ToLower(input.text())); 146 string16 term_string(base::i18n::ToLower(input.text()));
137 DCHECK(!term_string.empty()); 147 DCHECK(!term_string.empty());
138 148
139 for (history::ShortcutsBackend::ShortcutMap::const_iterator it = 149 for (history::ShortcutsBackend::ShortcutMap::const_iterator it =
140 FindFirstMatch(term_string); 150 FindFirstMatch(term_string, backend.get());
141 it != shortcuts_backend_->shortcuts_map().end() && 151 it != backend->shortcuts_map().end() &&
142 StartsWith(it->first, term_string, true); ++it) 152 StartsWith(it->first, term_string, true); ++it)
143 matches_.push_back(ShortcutToACMatch(input, term_string, it->second)); 153 matches_.push_back(ShortcutToACMatch(input, term_string, it->second));
144 std::partial_sort(matches_.begin(), 154 std::partial_sort(matches_.begin(),
145 matches_.begin() + 155 matches_.begin() +
146 std::min(AutocompleteProvider::kMaxMatches, matches_.size()), 156 std::min(AutocompleteProvider::kMaxMatches, matches_.size()),
147 matches_.end(), &AutocompleteMatch::MoreRelevant); 157 matches_.end(), &AutocompleteMatch::MoreRelevant);
148 if (matches_.size() > AutocompleteProvider::kMaxMatches) { 158 if (matches_.size() > AutocompleteProvider::kMaxMatches) {
149 matches_.erase(matches_.begin() + AutocompleteProvider::kMaxMatches, 159 matches_.erase(matches_.begin() + AutocompleteProvider::kMaxMatches,
150 matches_.end()); 160 matches_.end());
151 } 161 }
152 } 162 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (next_i_offset >= next_j_offset) 259 if (next_i_offset >= next_j_offset)
250 ++j; 260 ++j;
251 if (next_j_offset >= next_i_offset) 261 if (next_j_offset >= next_i_offset)
252 ++i; 262 ++i;
253 } 263 }
254 264
255 return output; 265 return output;
256 } 266 }
257 267
258 history::ShortcutsBackend::ShortcutMap::const_iterator 268 history::ShortcutsBackend::ShortcutMap::const_iterator
259 ShortcutsProvider::FindFirstMatch(const string16& keyword) { 269 ShortcutsProvider::FindFirstMatch(const string16& keyword,
270 history::ShortcutsBackend* backend) {
271 DCHECK(backend);
260 history::ShortcutsBackend::ShortcutMap::const_iterator it = 272 history::ShortcutsBackend::ShortcutMap::const_iterator it =
261 shortcuts_backend_->shortcuts_map().lower_bound(keyword); 273 backend->shortcuts_map().lower_bound(keyword);
262 // Lower bound not necessarily matches the keyword, check for item pointed by 274 // Lower bound not necessarily matches the keyword, check for item pointed by
263 // the lower bound iterator to at least start with keyword. 275 // the lower bound iterator to at least start with keyword.
264 return ((it == shortcuts_backend_->shortcuts_map().end()) || 276 return ((it == backend->shortcuts_map().end()) ||
265 StartsWith(it->first, keyword, true)) ? it : 277 StartsWith(it->first, keyword, true)) ? it :
266 shortcuts_backend_->shortcuts_map().end(); 278 backend->shortcuts_map().end();
267 } 279 }
268 280
269 // static 281 // static
270 int ShortcutsProvider::CalculateScore( 282 int ShortcutsProvider::CalculateScore(
271 const string16& terms, 283 const string16& terms,
272 const history::ShortcutsBackend::Shortcut& shortcut) { 284 const history::ShortcutsBackend::Shortcut& shortcut) {
273 DCHECK(!terms.empty()); 285 DCHECK(!terms.empty());
274 DCHECK_LE(terms.length(), shortcut.text.length()); 286 DCHECK_LE(terms.length(), shortcut.text.length());
275 287
276 // The initial score is based on how much of the shortcut the user has typed. 288 // The initial score is based on how much of the shortcut the user has typed.
(...skipping 18 matching lines...) Expand all
295 // (1.0 / each 5 additional hits), up to a maximum of 5x as long. 307 // (1.0 / each 5 additional hits), up to a maximum of 5x as long.
296 const double kMaxDecaySpeedDivisor = 5.0; 308 const double kMaxDecaySpeedDivisor = 5.0;
297 const double kNumUsesPerDecaySpeedDivisorIncrement = 5.0; 309 const double kNumUsesPerDecaySpeedDivisorIncrement = 5.0;
298 double decay_divisor = std::min(kMaxDecaySpeedDivisor, 310 double decay_divisor = std::min(kMaxDecaySpeedDivisor,
299 (shortcut.number_of_hits + kNumUsesPerDecaySpeedDivisorIncrement - 1) / 311 (shortcut.number_of_hits + kNumUsesPerDecaySpeedDivisorIncrement - 1) /
300 kNumUsesPerDecaySpeedDivisorIncrement); 312 kNumUsesPerDecaySpeedDivisorIncrement);
301 313
302 return static_cast<int>((base_score / exp(decay_exponent / decay_divisor)) + 314 return static_cast<int>((base_score / exp(decay_exponent / decay_divisor)) +
303 0.5); 315 0.5);
304 } 316 }
305
306 void ShortcutsProvider::set_shortcuts_backend(
307 history::ShortcutsBackend* shortcuts_backend) {
308 DCHECK(shortcuts_backend);
309 shortcuts_backend_ = shortcuts_backend;
310 shortcuts_backend_->AddObserver(this);
311 if (shortcuts_backend_->initialized())
312 initialized_ = true;
313 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/shortcuts_provider.h ('k') | chrome/browser/autocomplete/shortcuts_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698