diff options
author | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 23:47:26 +0000 |
---|---|---|
committer | jyasskin@chromium.org <jyasskin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-18 23:47:26 +0000 |
commit | adf5f3543feadf581e3ba84d930efd18110ffa31 (patch) | |
tree | 0ffe74804f72f0d2c53992a5abfb86a5669cf44a /extensions/common/extension_api.cc | |
parent | c75c62e4a3f1223fd252a835d314f5da0a839d42 (diff) | |
download | chromium_src-adf5f3543feadf581e3ba84d930efd18110ffa31.zip chromium_src-adf5f3543feadf581e3ba84d930efd18110ffa31.tar.gz chromium_src-adf5f3543feadf581e3ba84d930efd18110ffa31.tar.bz2 |
Optimize ExtensionAPI::IsAnyFeatureAvailableToContext from O(#features) to O(#children + log #features).
This also replaces O(N) string allocations with 1 and moves the top-level
feature check to the top of the function to provide a quick exit when the
context has full access.
And it adds an IsAvailable() overload taking a Feature to avoid the string
copies in GetFeatureDependency().
BUG=305000
Review URL: https://codereview.chromium.org/107473004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241706 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions/common/extension_api.cc')
-rw-r--r-- | extensions/common/extension_api.cc | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc index 13c1ce3..710dc51 100644 --- a/extensions/common/extension_api.cc +++ b/extensions/common/extension_api.cc @@ -282,21 +282,19 @@ bool ExtensionAPI::IsAnyFeatureAvailableToContext(const Feature& api, const GURL& url) { FeatureProviderMap::iterator provider = dependency_providers_.find("api"); CHECK(provider != dependency_providers_.end()); - const std::vector<std::string>& features = - provider->second->GetAllFeatureNames(); + if (IsAvailable(api, extension, context, url).is_available()) + return true; // Check to see if there are any parts of this API that are allowed in this // context. - for (std::vector<std::string>::const_iterator i = features.begin(); - i != features.end(); ++i) { - const std::string& feature_name = *i; - if (feature_name != api.name() && - feature_name.find(api.name() + ".") == 0) { - if (IsAvailable(feature_name, extension, context, url).is_available()) - return true; - } + const std::vector<Feature*> features = provider->second->GetChildren(api); + for (std::vector<Feature*>::const_iterator feature = features.begin(); + feature != features.end(); + ++feature) { + if (IsAvailable(**feature, extension, context, url).is_available()) + return true; } - return IsAvailable(api.name(), extension, context, url).is_available(); + return false; } Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, @@ -305,14 +303,20 @@ Feature::Availability ExtensionAPI::IsAvailable(const std::string& full_name, const GURL& url) { Feature* feature = GetFeatureDependency(full_name); CHECK(feature) << full_name; + return IsAvailable(*feature, extension, context, url); +} +Feature::Availability ExtensionAPI::IsAvailable(const Feature& feature, + const Extension* extension, + Feature::Context context, + const GURL& url) { Feature::Availability availability = - feature->IsAvailableToContext(extension, context, url); + feature.IsAvailableToContext(extension, context, url); if (!availability.is_available()) return availability; - for (std::set<std::string>::iterator iter = feature->dependencies().begin(); - iter != feature->dependencies().end(); ++iter) { + for (std::set<std::string>::iterator iter = feature.dependencies().begin(); + iter != feature.dependencies().end(); ++iter) { Feature::Availability dependency_availability = IsAvailable(*iter, extension, context, url); if (!dependency_availability.is_available()) |