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

Side by Side Diff: chrome/browser/extensions/api/declarative/rules_registry_with_cache.cc

Issue 14851011: RulesRegistryWithCache::ProcessChangedRules speed-up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 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/extensions/api/declarative/rules_registry_with_cache.h" 5 #include "chrome/browser/extensions/api/declarative/rules_registry_with_cache.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 24 matching lines...) Expand all
35 } 35 }
36 36
37 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > RulesFromValue( 37 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > RulesFromValue(
38 const base::Value* value) { 38 const base::Value* value) {
39 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > rules; 39 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > rules;
40 40
41 const base::ListValue* list = NULL; 41 const base::ListValue* list = NULL;
42 if (!value || !value->GetAsList(&list)) 42 if (!value || !value->GetAsList(&list))
43 return rules; 43 return rules;
44 44
45 rules.reserve(list->GetSize());
45 for (size_t i = 0; i < list->GetSize(); ++i) { 46 for (size_t i = 0; i < list->GetSize(); ++i) {
46 const base::DictionaryValue* dict = NULL; 47 const base::DictionaryValue* dict = NULL;
47 if (!list->GetDictionary(i, &dict)) 48 if (!list->GetDictionary(i, &dict))
48 continue; 49 continue;
49 linked_ptr<extensions::RulesRegistry::Rule> rule( 50 linked_ptr<extensions::RulesRegistry::Rule> rule(
50 new extensions::RulesRegistry::Rule()); 51 new extensions::RulesRegistry::Rule());
51 if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get())) 52 if (extensions::RulesRegistry::Rule::Populate(*dict, rule.get()))
52 rules.push_back(rule); 53 rules.push_back(rule);
53 } 54 }
54 55
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } 105 }
105 106
106 void RulesRegistryWithCache::AddReadyCallback(const base::Closure& callback) { 107 void RulesRegistryWithCache::AddReadyCallback(const base::Closure& callback) {
107 ready_callbacks_.push_back(callback); 108 ready_callbacks_.push_back(callback);
108 } 109 }
109 110
110 std::string RulesRegistryWithCache::AddRules( 111 std::string RulesRegistryWithCache::AddRules(
111 const std::string& extension_id, 112 const std::string& extension_id,
112 const std::vector<linked_ptr<Rule> >& rules) { 113 const std::vector<linked_ptr<Rule> >& rules) {
113 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 114 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
115 RulesDictionary& current_rules = rules_[extension_id];
114 116
115 // Verify that all rule IDs are new. 117 // Verify that all rule IDs are new.
116 for (std::vector<linked_ptr<Rule> >::const_iterator i = 118 for (std::vector<linked_ptr<Rule> >::const_iterator i =
117 rules.begin(); i != rules.end(); ++i) { 119 rules.begin(); i != rules.end(); ++i) {
118 const RuleId& rule_id = *((*i)->id); 120 const RuleId& rule_id = *((*i)->id);
119 RulesDictionaryKey key(extension_id, rule_id); 121 if (current_rules.find(rule_id) != current_rules.end())
120 if (rules_.find(key) != rules_.end())
121 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str()); 122 return base::StringPrintf(kDuplicateRuleId, rule_id.c_str());
122 } 123 }
123 124
124 std::string error = AddRulesImpl(extension_id, rules); 125 std::string error = AddRulesImpl(extension_id, rules);
125 126
126 if (!error.empty()) 127 if (!error.empty())
127 return error; 128 return error;
128 129
129 // Commit all rules into |rules_| on success. 130 // Commit all rules into |rules_| on success.
130 for (std::vector<linked_ptr<Rule> >::const_iterator i = 131 for (std::vector<linked_ptr<Rule> >::const_iterator i =
131 rules.begin(); i != rules.end(); ++i) { 132 rules.begin(); i != rules.end(); ++i) {
132 const RuleId& rule_id = *((*i)->id); 133 const RuleId& rule_id = *((*i)->id);
133 RulesDictionaryKey key(extension_id, rule_id); 134 current_rules[rule_id] = *i;
134 rules_[key] = *i;
135 } 135 }
136 136
137 ProcessChangedRules(extension_id); 137 ProcessChangedRules(extension_id);
138 return kSuccess; 138 return kSuccess;
139 } 139 }
140 140
141 std::string RulesRegistryWithCache::RemoveRules( 141 std::string RulesRegistryWithCache::RemoveRules(
142 const std::string& extension_id, 142 const std::string& extension_id,
143 const std::vector<std::string>& rule_identifiers) { 143 const std::vector<std::string>& rule_identifiers) {
144 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 144 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
145 145
146 std::string error = RemoveRulesImpl(extension_id, rule_identifiers); 146 std::string error = RemoveRulesImpl(extension_id, rule_identifiers);
147 147
148 if (!error.empty()) 148 if (!error.empty())
149 return error; 149 return error;
150 150
151 // Commit removal of rules from |rules_| on success. 151 // Commit removal of rules from |rules_| on success.
152 RulesDictionary& current_rules = rules_[extension_id];
152 for (std::vector<std::string>::const_iterator i = 153 for (std::vector<std::string>::const_iterator i =
153 rule_identifiers.begin(); i != rule_identifiers.end(); ++i) { 154 rule_identifiers.begin(); i != rule_identifiers.end(); ++i) {
154 RulesDictionaryKey lookup_key(extension_id, *i); 155 current_rules.erase(*i);
155 rules_.erase(lookup_key);
156 } 156 }
157 if (current_rules.empty())
158 rules_.erase(extension_id);
157 159
158 ProcessChangedRules(extension_id); 160 ProcessChangedRules(extension_id);
159 return kSuccess; 161 return kSuccess;
160 } 162 }
161 163
162 std::string RulesRegistryWithCache::RemoveAllRules( 164 std::string RulesRegistryWithCache::RemoveAllRules(
163 const std::string& extension_id) { 165 const std::string& extension_id) {
164 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 166 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
165 167
166 std::string error = RemoveAllRulesImpl(extension_id); 168 std::string error = RemoveAllRulesImpl(extension_id);
167 169
168 if (!error.empty()) 170 if (!error.empty())
169 return error; 171 return error;
170 172
171 // Commit removal of rules from |rules_| on success. 173 // Commit removal of rules from |rules_| on success.
172 for (RulesDictionary::const_iterator i = rules_.begin(); 174 rules_.erase(extension_id);
173 i != rules_.end();) {
174 const RulesDictionaryKey& key = i->first;
175 ++i;
176 if (key.first == extension_id)
177 rules_.erase(key);
178 }
179 175
180 ProcessChangedRules(extension_id); 176 ProcessChangedRules(extension_id);
181 return kSuccess; 177 return kSuccess;
182 } 178 }
183 179
184 std::string RulesRegistryWithCache::GetRules( 180 std::string RulesRegistryWithCache::GetRules(
185 const std::string& extension_id, 181 const std::string& extension_id,
186 const std::vector<std::string>& rule_identifiers, 182 const std::vector<std::string>& rule_identifiers,
187 std::vector<linked_ptr<RulesRegistry::Rule> >* out) { 183 std::vector<linked_ptr<RulesRegistry::Rule> >* out) {
188 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 184 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
189 185
186 RulesDictionary& current_rules = rules_[extension_id];
190 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin(); 187 for (std::vector<std::string>::const_iterator i = rule_identifiers.begin();
191 i != rule_identifiers.end(); ++i) { 188 i != rule_identifiers.end(); ++i) {
192 RulesDictionaryKey lookup_key(extension_id, *i); 189 RulesDictionary::iterator entry = current_rules.find(*i);
193 RulesDictionary::iterator entry = rules_.find(lookup_key); 190 if (entry != current_rules.end())
194 if (entry != rules_.end())
195 out->push_back(entry->second); 191 out->push_back(entry->second);
196 } 192 }
197 return kSuccess; 193 return kSuccess;
198 } 194 }
199 195
200 std::string RulesRegistryWithCache::GetAllRules( 196 std::string RulesRegistryWithCache::GetAllRules(
201 const std::string& extension_id, 197 const std::string& extension_id,
202 std::vector<linked_ptr<RulesRegistry::Rule> >* out) { 198 std::vector<linked_ptr<RulesRegistry::Rule> >* out) {
203 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 199 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
204 200
205 for (RulesDictionary::const_iterator i = rules_.begin(); 201 RulesDictionary& current_rules = rules_[extension_id];
206 i != rules_.end(); ++i) { 202 out->reserve(out->size() + current_rules.size());
207 const RulesDictionaryKey& key = i->first; 203 for (RulesDictionary::const_iterator i = current_rules.begin();
208 if (key.first == extension_id) 204 i != current_rules.end(); ++i) {
209 out->push_back(i->second); 205 out->push_back(i->second);
210 } 206 }
211 return kSuccess; 207 return kSuccess;
212 } 208 }
213 209
214 void RulesRegistryWithCache::OnExtensionUnloaded( 210 void RulesRegistryWithCache::OnExtensionUnloaded(
215 const std::string& extension_id) { 211 const std::string& extension_id) {
216 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 212 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
217 std::string error = RemoveAllRules(extension_id); 213 std::string error = RemoveAllRules(extension_id);
218 if (!error.empty()) 214 if (!error.empty())
219 LOG(ERROR) << error; 215 LOG(ERROR) << error;
(...skipping 23 matching lines...) Expand all
243 scoped_ptr<base::Value> rules) { 239 scoped_ptr<base::Value> rules) {
244 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 240 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
245 241
246 AddRules(extension_id, RulesFromValue(rules.get())); 242 AddRules(extension_id, RulesFromValue(rules.get()));
247 } 243 }
248 244
249 void RulesRegistryWithCache::ProcessChangedRules( 245 void RulesRegistryWithCache::ProcessChangedRules(
250 const std::string& extension_id) { 246 const std::string& extension_id) {
251 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread())); 247 DCHECK(content::BrowserThread::CurrentlyOn(owner_thread()));
252 248
253 std::vector<linked_ptr<RulesRegistry::Rule> > new_rules; 249 scoped_ptr<RulesVector> new_rules(new RulesVector());
254 std::string error = GetAllRules(extension_id, &new_rules); 250 std::string error = GetAllRules(extension_id, new_rules.get());
255 DCHECK_EQ(std::string(), error); 251 DCHECK_EQ(std::string(), error);
256 content::BrowserThread::PostTask( 252 content::BrowserThread::PostTask(
257 content::BrowserThread::UI, 253 content::BrowserThread::UI,
258 FROM_HERE, 254 FROM_HERE,
259 base::Bind(&RuleStorageOnUI::WriteToStorage, 255 base::Bind(&RuleStorageOnUI::WriteToStorage,
260 storage_on_ui_, 256 storage_on_ui_,
261 extension_id, 257 extension_id,
262 base::Passed(RulesToValue(new_rules)))); 258 base::Passed(&new_rules)));
263 } 259 }
264 260
265 // RulesRegistryWithCache::RuleStorageOnUI 261 // RulesRegistryWithCache::RuleStorageOnUI
266 262
267 RulesRegistryWithCache::RuleStorageOnUI::RuleStorageOnUI( 263 RulesRegistryWithCache::RuleStorageOnUI::RuleStorageOnUI(
268 Profile* profile, 264 Profile* profile,
269 const std::string& storage_key, 265 const std::string& storage_key,
270 content::BrowserThread::ID rules_registry_thread, 266 content::BrowserThread::ID rules_registry_thread,
271 base::WeakPtr<RulesRegistryWithCache> registry, 267 base::WeakPtr<RulesRegistryWithCache> registry,
272 bool log_storage_init_delay) 268 bool log_storage_init_delay)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 // can post tasks for the not-yet-initialized registry to run, we need to 315 // can post tasks for the not-yet-initialized registry to run, we need to
320 // postpone checking for being ready (=all rules loaded), on the registry's 316 // postpone checking for being ready (=all rules loaded), on the registry's
321 // thread. 317 // thread.
322 base::MessageLoop::current()->PostTask( 318 base::MessageLoop::current()->PostTask(
323 FROM_HERE, base::Bind(&RuleStorageOnUI::CheckIfReady, GetWeakPtr())); 319 FROM_HERE, base::Bind(&RuleStorageOnUI::CheckIfReady, GetWeakPtr()));
324 } 320 }
325 } 321 }
326 322
327 void RulesRegistryWithCache::RuleStorageOnUI::WriteToStorage( 323 void RulesRegistryWithCache::RuleStorageOnUI::WriteToStorage(
328 const std::string& extension_id, 324 const std::string& extension_id,
329 scoped_ptr<base::Value> value) { 325 scoped_ptr<RulesVector> new_rules) {
330 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 326 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
331 if (!profile_) 327 if (!profile_)
332 return; 328 return;
333 329
334 StateStore* store = ExtensionSystem::Get(profile_)->rules_store(); 330 StateStore* store = ExtensionSystem::Get(profile_)->rules_store();
335 if (store) 331 if (store) {
336 store->SetExtensionValue(extension_id, storage_key_, value.Pass()); 332 store->SetExtensionValue(
333 extension_id, storage_key_, RulesToValue(*new_rules));
334 }
337 } 335 }
338 336
339 void RulesRegistryWithCache::RuleStorageOnUI::Observe( 337 void RulesRegistryWithCache::RuleStorageOnUI::Observe(
340 int type, 338 int type,
341 const content::NotificationSource& source, 339 const content::NotificationSource& source,
342 const content::NotificationDetails& details) { 340 const content::NotificationDetails& details) {
343 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 341 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
344 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) { 342 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
345 const extensions::Extension* extension = 343 const extensions::Extension* extension =
346 content::Details<const extensions::Extension>(details).ptr(); 344 content::Details<const extensions::Extension>(details).ptr();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 registry_, 405 registry_,
408 extension_id, 406 extension_id,
409 base::Passed(&value))); 407 base::Passed(&value)));
410 408
411 waiting_for_extensions_.erase(extension_id); 409 waiting_for_extensions_.erase(extension_id);
412 410
413 CheckIfReady(); 411 CheckIfReady();
414 } 412 }
415 413
416 } // namespace extensions 414 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698