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

Unified Diff: chrome/browser/password_manager/password_store_mac.cc

Issue 885033002: PasswordStoreMac: Use ScopedVector::weak_erase to improve performance (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Compily compily comp. Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/password_manager/password_store_mac.cc
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc
index 96518ffb46c3524bb441264a80799338b5a8df07..45875a1d33c84659561ab9a28aa71d1ea74fc689 100644
--- a/chrome/browser/password_manager/password_store_mac.cc
+++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -195,6 +195,46 @@ void AppendSecondToFirst(ScopedVector<autofill::PasswordForm>* first,
second->weak_clear();
}
+// Returns the best match for |base_form| from |keychain_forms|, or nullptr if
+// there is no suitable match.
+const PasswordForm* BestKeychainFormForForm(
+ const PasswordForm& base_form,
+ const std::vector<PasswordForm*>& keychain_forms) {
+ const PasswordForm* partial_match = nullptr;
+ for (const auto* keychain_form : keychain_forms) {
+ // TODO(stuartmorgan): We should really be scoring path matches and picking
+ // the best, rather than just checking exact-or-not (although in practice
+ // keychain items with paths probably came from us).
+ if (internal_keychain_helpers::FormsMatchForMerge(
+ base_form, *keychain_form,
+ internal_keychain_helpers::FUZZY_FORM_MATCH)) {
+ if (base_form.origin == keychain_form->origin) {
+ return keychain_form;
+ } else if (!partial_match) {
+ partial_match = keychain_form;
+ }
+ }
+ }
+ return partial_match;
+}
+
+// Iterates over all elements in |forms|, passes the pointed to objects to
+// |move_form|, and clears |forms| efficiently. FormMover needs to be a callable
+// entity, accepting scoped_ptr<autofill::PasswordForm> as its sole argument.
+template <typename FormMover>
+inline void MoveAllFormsOut(ScopedVector<autofill::PasswordForm>* forms,
+ FormMover mover) {
+ for (autofill::PasswordForm* form_ptr : *forms) {
+ mover(scoped_ptr<autofill::PasswordForm>(form_ptr));
+ }
+ // We moved the ownership of every form out of |forms|. For performance
+ // reasons, we can just weak_clear it, instead of nullptr-ing the respective
+ // elements and letting the vector's destructor to go through the list once
+ // more. This was tested on a benchmark, and seemed to make a difference on
+ // Mac.
+ forms->weak_clear();
+}
+
} // namespace
#pragma mark -
@@ -402,40 +442,20 @@ bool FormsMatchForMerge(const PasswordForm& form_a,
form_a.username_value == form_b.username_value;
}
-// Returns an the best match for |base_form| from |keychain_forms|, or NULL if
-// there is no suitable match.
-PasswordForm* BestKeychainFormForForm(
- const PasswordForm& base_form,
- const std::vector<PasswordForm*>* keychain_forms) {
- PasswordForm* partial_match = NULL;
- for (std::vector<PasswordForm*>::const_iterator i = keychain_forms->begin();
- i != keychain_forms->end(); ++i) {
- // TODO(stuartmorgan): We should really be scoring path matches and picking
- // the best, rather than just checking exact-or-not (although in practice
- // keychain items with paths probably came from us).
- if (FormsMatchForMerge(base_form, *(*i), FUZZY_FORM_MATCH)) {
- if (base_form.origin == (*i)->origin) {
- return *i;
- } else if (!partial_match) {
- partial_match = *i;
- }
- }
- }
- return partial_match;
-}
-
// Moves entries from |forms| that are blacklist entries into |blacklist|.
void ExtractBlacklistForms(ScopedVector<autofill::PasswordForm>* forms,
ScopedVector<autofill::PasswordForm>* blacklist) {
blacklist->reserve(blacklist->size() + forms->size());
ScopedVector<autofill::PasswordForm> non_blacklist;
- for (auto& form : *forms) {
+ // Move forms in either |non_blacklist| or |blacklist|, depending on whether
+ // they are blacklisted by the user.
+ MoveAllFormsOut(forms, [&non_blacklist, blacklist](
+ scoped_ptr<autofill::PasswordForm> form) {
if (form->blacklisted_by_user)
- blacklist->push_back(form);
+ blacklist->push_back(form.release());
else
- non_blacklist.push_back(form);
- form = nullptr;
- }
+ non_blacklist.push_back(form.release());
+ });
forms->swap(non_blacklist);
}
@@ -455,19 +475,24 @@ void MergePasswordForms(ScopedVector<autofill::PasswordForm>* keychain_forms,
// Merge the normal entries.
ScopedVector<autofill::PasswordForm> unused_database_forms;
unused_database_forms.reserve(database_forms->size());
- std::set<autofill::PasswordForm*> used_keychain_forms;
- for (auto& db_form : *database_forms) {
- PasswordForm* best_match =
- BestKeychainFormForForm(*db_form, &keychain_forms->get());
+ std::set<const autofill::PasswordForm*> used_keychain_forms;
+ // Move all database forms to either |merged_forms| or
+ // |unused_database_forms|, based on whether they have a match in the keychain
+ // forms or not. If there is a match, add its password to the DB form and
+ // mark the keychain form as used.
+ MoveAllFormsOut(database_forms, [keychain_forms, &used_keychain_forms,
+ merged_forms, &unused_database_forms](
+ scoped_ptr<autofill::PasswordForm> form) {
+ const PasswordForm* best_match =
+ BestKeychainFormForForm(*form, keychain_forms->get());
if (best_match) {
used_keychain_forms.insert(best_match);
- db_form->password_value = best_match->password_value;
- merged_forms->push_back(db_form);
+ form->password_value = best_match->password_value;
+ merged_forms->push_back(form.release());
} else {
- unused_database_forms.push_back(db_form);
+ unused_database_forms.push_back(form.release());
}
- db_form = nullptr;
- }
+ });
database_forms->swap(unused_database_forms);
// Clear out all the Keychain entries we used.
@@ -522,18 +547,19 @@ void GetPasswordsForForms(const AppleKeychain& keychain,
// matching PasswordForm using its corresponding SecKeychainItemRef.
ScopedVector<autofill::PasswordForm> unused_db_forms;
unused_db_forms.reserve(database_forms->size());
- for (auto& db_form : *database_forms) {
+ // Move database forms with a password stored in |keychain| to |passwords|,
+ // including the password. The rest is moved to |unused_db_forms|.
+ MoveAllFormsOut(database_forms,
+ [&keychain, &item_form_pairs, passwords, &unused_db_forms](
+ scoped_ptr<autofill::PasswordForm> form) {
ScopedVector<autofill::PasswordForm> keychain_matches =
- ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *db_form);
+ ExtractPasswordsMergeableWithForm(keychain, item_form_pairs, *form);
ScopedVector<autofill::PasswordForm> db_form_container;
- db_form_container.push_back(db_form);
- db_form = nullptr;
+ db_form_container.push_back(form.release());
MergePasswordForms(&keychain_matches, &db_form_container, passwords);
- unused_db_forms.insert(unused_db_forms.end(), db_form_container.begin(),
- db_form_container.end());
- db_form_container.weak_clear();
- }
+ AppendSecondToFirst(&unused_db_forms, &db_form_container);
+ });
database_forms->swap(unused_db_forms);
STLDeleteContainerPairSecondPointers(item_form_pairs.begin(),
@@ -582,8 +608,7 @@ bool FormIsValidAndMatchesOtherForm(const PasswordForm& query_form,
&is_secure, &security_domain)) {
return false;
}
- return internal_keychain_helpers::FormsMatchForMerge(
- query_form, other_form, STRICT_FORM_MATCH);
+ return FormsMatchForMerge(query_form, other_form, STRICT_FORM_MATCH);
}
ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm(
@@ -597,7 +622,7 @@ ScopedVector<autofill::PasswordForm> ExtractPasswordsMergeableWithForm(
// Create a new object, since the caller is responsible for deleting the
// returned forms.
scoped_ptr<PasswordForm> form_with_password(new PasswordForm());
- internal_keychain_helpers::FillPasswordFormFromKeychainItem(
+ FillPasswordFormFromKeychainItem(
keychain, *(i->first), form_with_password.get(),
true); // Load password attributes and data.
// Do not include blacklisted items found in the keychain.
@@ -1052,10 +1077,7 @@ void PasswordStoreMac::GetLoginsImpl(
ScopedVector<PasswordForm> keychain_blacklist_forms;
internal_keychain_helpers::ExtractBlacklistForms(&keychain_forms,
&keychain_blacklist_forms);
- matched_forms.insert(matched_forms.end(),
- keychain_forms.begin(),
- keychain_forms.end());
- keychain_forms.weak_clear();
+ AppendSecondToFirst(&matched_forms, &keychain_forms);
if (!database_forms.empty()) {
RemoveDatabaseForms(database_forms.get());
@@ -1169,7 +1191,5 @@ void PasswordStoreMac::CleanOrphanedForms(
RemoveDatabaseForms(database_forms.get());
// Move the orphaned DB forms to the output parameter.
- orphaned_forms->insert(orphaned_forms->end(), database_forms.begin(),
- database_forms.end());
- database_forms.weak_clear();
+ AppendSecondToFirst(orphaned_forms, &database_forms);
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698