Commit 023e7d5d authored by Michael Crouse's avatar Michael Crouse Committed by Commit Bot

Enable processing URL-keyed hints and MRU cache.

This change enables processing of URL-keyed hints that are returned
from the remote optimization guide. It also add an in-memory cache
for these hints within the hint cache for their use by the
optimization guide and its consumers.

Future changes will allow the fetch of hints based on the current
navigation and enable their use for future consumers.

Bug: 1036490
Change-Id: I843043ff26541cad687a65899e9542c32823dde4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1987226Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Reviewed-by: default avatarSophie Chang <sophiechang@chromium.org>
Commit-Queue: Michael Crouse <mcrouse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#729825}
parent a3782800
......@@ -270,7 +270,7 @@ OptimizationGuideHintsManager::ProcessHintsComponent(
registered_optimization_types);
if (update_data) {
bool did_process_hints = optimization_guide::ProcessHints(
bool did_process_hints = hint_cache_->ProcessAndCacheHints(
config->mutable_hints(), update_data.get());
optimization_guide::RecordProcessHintsComponentResult(
did_process_hints
......@@ -350,8 +350,8 @@ void OptimizationGuideHintsManager::OnHintCacheInitialized() {
std::unique_ptr<optimization_guide::StoreUpdateData> update_data =
hint_cache_->MaybeCreateUpdateDataForComponentHints(
base::Version(kManualConfigComponentVersion));
optimization_guide::ProcessHints(manual_config->mutable_hints(),
update_data.get());
hint_cache_->ProcessAndCacheHints(manual_config->mutable_hints(),
update_data.get());
// Allow |UpdateComponentHints| to block startup so that the first
// navigation gets the hints when a command line hint proto is provided.
UpdateComponentHints(base::DoNothing(), std::move(update_data));
......@@ -748,7 +748,7 @@ OptimizationGuideHintsManager::ShouldTargetNavigation(
const auto& host = url.host();
// Check if we have a hint already loaded for this navigation.
const optimization_guide::proto::Hint* loaded_hint =
hint_cache_->GetHintIfLoaded(host);
hint_cache_->GetHostKeyedHintIfLoaded(host);
const optimization_guide::proto::PageHint* matched_page_hint =
loaded_hint ? GetPageHintForNavigation(navigation_handle, loaded_hint)
: nullptr;
......@@ -788,7 +788,7 @@ OptimizationGuideHintsManager::CanApplyOptimization(
// Check if we have a hint already loaded for this navigation.
const optimization_guide::proto::Hint* loaded_hint =
hint_cache_->GetHintIfLoaded(host);
hint_cache_->GetHostKeyedHintIfLoaded(host);
bool has_hint_in_cache = hint_cache_->HasHint(host);
const optimization_guide::proto::PageHint* matched_page_hint =
loaded_hint ? GetPageHintForNavigation(navigation_handle, loaded_hint)
......
......@@ -39,6 +39,8 @@ static_library("optimization_guide") {
"store_update_data.cc",
"store_update_data.h",
"top_host_provider.h",
"url_keyed_hint.cc",
"url_keyed_hint.h",
"url_pattern_with_wildcards.cc",
"url_pattern_with_wildcards.h",
]
......
......@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/bind.h"
#include "base/time/default_clock.h"
#include "components/optimization_guide/hints_processing_util.h"
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/store_update_data.h"
......@@ -16,19 +17,23 @@ namespace optimization_guide {
namespace {
// The default number of hints retained within the memory cache. When the limit
// is exceeded, the least recently used hint is purged from the cache.
const size_t kDefaultMaxMemoryCacheHints = 20;
// The default number of host-keyed hints retained within the host keyed cache.
// When the limit is exceeded, the least recently used hint is purged from
// |host_keyed_cache_|.
const size_t kDefaultMaxMemoryCacheHostKeyedHints = 20;
} // namespace
HintCache::HintCache(
std::unique_ptr<OptimizationGuideStore> optimization_guide_store,
base::Optional<int> max_memory_cache_hints /*= base::Optional<int>()*/)
base::Optional<int>
max_memory_cache_host_keyed_hints /*= base::Optional<int>()*/)
: optimization_guide_store_(std::move(optimization_guide_store)),
memory_cache_(
std::max(max_memory_cache_hints.value_or(kDefaultMaxMemoryCacheHints),
1)) {
host_keyed_cache_(std::max(max_memory_cache_host_keyed_hints.value_or(
kDefaultMaxMemoryCacheHostKeyedHints),
1)),
url_keyed_hint_cache_(features::MaxURLKeyedHintCacheSize()),
clock_(base::DefaultClock::GetInstance()) {
DCHECK(optimization_guide_store_);
}
......@@ -65,9 +70,9 @@ void HintCache::UpdateComponentHints(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(component_data);
// Clear the memory cache prior to updating the store with the new component
// data.
memory_cache_.Clear();
// Clear the host-keyed cache prior to updating the store with the new
// component data.
host_keyed_cache_.Clear();
optimization_guide_store_->UpdateComponentHints(std::move(component_data),
std::move(callback));
......@@ -86,8 +91,8 @@ void HintCache::UpdateFetchedHints(
}
std::unique_ptr<StoreUpdateData> fetched_hints_update_data =
CreateUpdateDataForFetchedHints(update_time, expiry_time);
ProcessHints(get_hints_response.get()->mutable_hints(),
fetched_hints_update_data.get());
ProcessAndCacheHints(get_hints_response.get()->mutable_hints(),
fetched_hints_update_data.get());
optimization_guide_store_->UpdateFetchedHints(
std::move(fetched_hints_update_data), std::move(callback));
}
......@@ -95,8 +100,10 @@ void HintCache::UpdateFetchedHints(
void HintCache::ClearFetchedHints() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(optimization_guide_store_);
// TODO(mcrouse): Update to remove only fetched hints from |memory_cache_|.
memory_cache_.Clear();
// TODO(mcrouse): Update to remove only fetched hints from
// |host_keyed_cache_|.
host_keyed_cache_.Clear();
url_keyed_hint_cache_.Clear();
optimization_guide_store_->ClearFetchedHintsFromDatabase();
}
......@@ -115,10 +122,10 @@ void HintCache::LoadHint(const std::string& host, HintLoadedCallback callback) {
return;
}
// Search for the entry key in the memory cache; if it is not already there,
// then asynchronously load it from the store and return.
auto hint_it = memory_cache_.Get(hint_entry_key);
if (hint_it == memory_cache_.end()) {
// Search for the entry key in the host-keyed cache; if it is not already
// there, then asynchronously load it from the store and return.
auto hint_it = host_keyed_cache_.Get(hint_entry_key);
if (hint_it == host_keyed_cache_.end()) {
optimization_guide_store_->LoadHint(
hint_entry_key,
base::BindOnce(&HintCache::OnLoadStoreHint, base::Unretained(this),
......@@ -126,11 +133,12 @@ void HintCache::LoadHint(const std::string& host, HintLoadedCallback callback) {
return;
}
// Run the callback with the hint from the memory cache.
// Run the callback with the hint from the host-keyed cache.
std::move(callback).Run(hint_it->second.get());
}
const proto::Hint* HintCache::GetHintIfLoaded(const std::string& host) {
const proto::Hint* HintCache::GetHostKeyedHintIfLoaded(
const std::string& host) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Try to retrieve the hint entry key for the host. If no hint exists for the
......@@ -140,16 +148,35 @@ const proto::Hint* HintCache::GetHintIfLoaded(const std::string& host) {
return nullptr;
}
// Find the hint within the memory cache. It will only be available here if
// it has been loaded recently enough to be retained within the MRU cache.
auto hint_it = memory_cache_.Get(hint_entry_key);
if (hint_it != memory_cache_.end()) {
// Find the hint within the host-keyed cache. It will only be available here
// if it has been loaded recently enough to be retained within the MRU cache.
auto hint_it = host_keyed_cache_.Get(hint_entry_key);
if (hint_it != host_keyed_cache_.end()) {
return hint_it->second.get();
}
return nullptr;
}
proto::Hint* HintCache::GetURLKeyedHint(const GURL& url) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!IsValidURLForURLKeyedHint(url))
return nullptr;
auto hint_it = url_keyed_hint_cache_.Get(url.spec());
if (hint_it == url_keyed_hint_cache_.end())
return nullptr;
URLKeyedHint* hint = hint_it->second.get();
if (hint->expiration_time() > clock_->Now())
return hint->url_keyed_hint();
// The hint is expired so remove it from the cache.
url_keyed_hint_cache_.Erase(hint_it);
return nullptr;
}
base::Time HintCache::GetFetchedHintsUpdateTime() const {
if (!optimization_guide_store_) {
return base::Time();
......@@ -172,15 +199,67 @@ void HintCache::OnLoadStoreHint(
return;
}
// Check if the hint was cached in memory after the load was requested from
// the store. This can occur if multiple loads for the same entry key occur
// consecutively prior to any returning.
auto hint_it = memory_cache_.Get(hint_entry_key);
if (hint_it == memory_cache_.end()) {
hint_it = memory_cache_.Put(hint_entry_key, std::move(hint));
// Check if the hint was cached in the host-keyed cache after the load was
// requested from the store. This can occur if multiple loads for the same
// entry key occur consecutively prior to any returning.
auto hint_it = host_keyed_cache_.Get(hint_entry_key);
if (hint_it == host_keyed_cache_.end()) {
hint_it = host_keyed_cache_.Put(hint_entry_key, std::move(hint));
}
std::move(callback).Run(hint_it->second.get());
}
bool HintCache::ProcessAndCacheHints(
google::protobuf::RepeatedPtrField<proto::Hint>* hints,
optimization_guide::StoreUpdateData* update_data) {
// If there's no update data, then there's nothing to do.
if (!update_data)
return false;
bool processed_hints_to_store = false;
// Process each hint in the the hint configuration. The hints are mutable
// because once processing is completed on each individual hint, it is moved
// into the component update data. This eliminates the need to make any
// additional copies of the hints.
for (auto& hint : *hints) {
const std::string& hint_key = hint.key();
// Validate configuration keys.
DCHECK(!hint_key.empty());
if (hint_key.empty())
continue;
if (hint.page_hints().empty())
continue;
base::Time expiry_time =
hint.has_max_cache_duration()
? clock_->Now() + base::TimeDelta().FromSeconds(
hint.max_cache_duration().seconds())
: clock_->Now() + features::URLKeyedHintValidCacheDuration();
switch (hint.key_representation()) {
case proto::HOST_SUFFIX:
update_data->MoveHintIntoUpdateData(std::move(hint));
processed_hints_to_store = true;
break;
case proto::FULL_URL:
if (IsValidURLForURLKeyedHint(GURL(hint_key))) {
url_keyed_hint_cache_.Put(
hint_key,
std::make_unique<URLKeyedHint>(expiry_time, std::move(hint)));
}
break;
case proto::REPRESENTATION_UNSPECIFIED:
NOTREACHED();
break;
}
}
return processed_hints_to_store;
}
void HintCache::SetClockForTesting(const base::Clock* clock) {
clock_ = clock;
}
} // namespace optimization_guide
......@@ -12,8 +12,12 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/clock.h"
#include "components/optimization_guide/optimization_guide_store.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/optimization_guide/url_keyed_hint.h"
class GURL;
namespace optimization_guide {
class StoreUpdateData;
......@@ -23,12 +27,13 @@ using HintLoadedCallback = base::OnceCallback<void(const proto::Hint*)>;
// Contains a set of optimization hints received from the Cacao service. This
// may include hints received from the ComponentUpdater and hints fetched from a
// Cacao Optimization Guide Service API. The availability of hints is queryable
// via host name. The cache itself consists of a backing store, which allows for
// asynchronous loading of any available hint, and an MRU memory cache, which
// can be used to synchronously retrieve recently loaded hints.
// via host name and full URL. The cache itself consists of a backing store,
// which allows for asynchronous loading of any available host-keyed hint, and
// an MRU host-keyed cache and a url-keyed cache, which can be used to
// synchronously retrieve recently loaded hints keyed by URL or host.
class HintCache {
public:
// Construct the HintCache with a backing store and an optional max memory
// Construct the HintCache with a backing store and an optional max host-keyed
// cache size. While |optimization_guide_store| is required,
// |max_memory_cache_hints| is optional and the default max size will be used
// if it is not provided.
......@@ -78,12 +83,12 @@ class HintCache {
base::Time update_time,
base::OnceClosure callback);
// Purge fetched hints from the owned |optimization_guide_store_| and reset
// the |memory_cache_|.
// Purges fetched hints from the owned |optimization_guide_store_| and resets
// the host-keyed cache.
void ClearFetchedHints();
// Returns whether the cache has a hint data for |host| locally (whether
// in memory or persisted on disk).
// in the host-keyed cache or persisted on disk).
bool HasHint(const std::string& host) const;
// Requests that hint data for |host| be loaded asynchronously and passed to
......@@ -95,20 +100,44 @@ class HintCache {
// not initialized, base::Time() is returned.
base::Time GetFetchedHintsUpdateTime() const;
// Returns the hint data for |host| if found in memory, otherwise nullptr.
const proto::Hint* GetHintIfLoaded(const std::string& host);
// Returns the hint data for |host| if found in the host-keyed cache,
// otherwise nullptr.
const proto::Hint* GetHostKeyedHintIfLoaded(const std::string& host);
// Returns an unepxired hint data for |url| if found in the url-keyed cache,
// otherwise nullptr. If the hint is expired, it is removed from the URL-keyed
// cache. Only HTTP/HTTPS URLs without username and password are supported by
// the URL-keyed cache, if |url| does not meet this criteria, nullptr is
// returned. The returned hint is not guaranteed to remain valid and will
// become invalid if any additional URL-keyed hints are added to the cache
// that evicts the returned hint.
proto::Hint* GetURLKeyedHint(const GURL& url);
// Verifies and processes |hints| and moves the ones it supports into
// |update_data| and caches any valid URL keyed hints.
//
// Returns true if there was at least one hint is moved into |update_data|.
bool ProcessAndCacheHints(
google::protobuf::RepeatedPtrField<proto::Hint>* hints,
StoreUpdateData* update_data);
// Override |clock_| for testing.
void SetClockForTesting(const base::Clock* clock);
private:
using StoreHintMemoryCache =
using HostKeyedHintCache =
base::HashingMRUCache<OptimizationGuideStore::EntryKey,
std::unique_ptr<proto::Hint>>;
using URLKeyedHintCache =
base::HashingMRUCache<std::string, std::unique_ptr<URLKeyedHint>>;
// The callback run after the store finishes initialization. This then runs
// the callback initially provided by the Initialize() call.
void OnStoreInitialized(base::OnceClosure callback);
// The callback run after the store finishes loading a hint. This adds the
// loaded hint to |memory_cache_|, potentially purging the least recently
// loaded hint to |host_keyed_cache_|, potentially purging the least recently
// used element, and then runs the callback initially provided by the
// LoadHint() call.
void OnLoadStoreHint(
......@@ -119,13 +148,21 @@ class HintCache {
// The backing store used with this hint cache. Set during construction.
const std::unique_ptr<OptimizationGuideStore> optimization_guide_store_;
// The in-memory cache of hints loaded from the store. Maps store EntryKey to
// Hint proto. This servers two purposes:
// The cache of host-keyed hints loaded from the store. Maps store
// EntryKey to Hint proto. This serves two purposes:
// 1. Allows hints to be requested on navigation and retained in memory until
// commit, when they can be synchronously retrieved from the cache.
// 2. Reduces churn of needing to reload hints from frequently visited sites
// multiple times during a session.
StoreHintMemoryCache memory_cache_;
HostKeyedHintCache host_keyed_cache_;
// The in-memory cache of URL-keyed hints fetched from the remote optimization
// guide. Maps a full URL to Hint proto. All available URL-keyed hints are
// maintained within the cache and are not persisted to disk.
URLKeyedHintCache url_keyed_hint_cache_;
// The clock used to determine if hints have expired.
const base::Clock* clock_;
SEQUENCE_CHECKER(sequence_checker_);
......
......@@ -12,6 +12,7 @@
#include "components/optimization_guide/optimization_guide_features.h"
#include "components/optimization_guide/store_update_data.h"
#include "components/optimization_guide/url_pattern_with_wildcards.h"
#include "net/base/url_util.h"
#include "url/gurl.h"
namespace optimization_guide {
......@@ -89,55 +90,6 @@ std::string HashHostForDictionary(const std::string& host) {
return base::StringPrintf("%x", base::PersistentHash(host));
}
bool ProcessHints(google::protobuf::RepeatedPtrField<proto::Hint>* hints,
optimization_guide::StoreUpdateData* update_data) {
// If there's no update data, then there's nothing to do.
if (!update_data)
return false;
base::flat_set<std::string> seen_host_suffixes;
bool did_process_hints = false;
// Process each hint in the the hint configuration. The hints are mutable
// because once processing is completed on each individual hint, it is moved
// into the component update data. This eliminates the need to make any
// additional copies of the hints.
for (auto& hint : *hints) {
// We only support host suffixes at the moment. Skip anything else.
// One |hint| applies to one host URL suffix.
if (hint.key_representation() != proto::HOST_SUFFIX) {
continue;
}
const std::string& hint_key = hint.key();
// Validate configuration keys.
DCHECK(!hint_key.empty());
if (hint_key.empty()) {
continue;
}
auto seen_host_suffixes_iter = seen_host_suffixes.find(hint_key);
DCHECK(seen_host_suffixes_iter == seen_host_suffixes.end());
if (seen_host_suffixes_iter != seen_host_suffixes.end()) {
DLOG(WARNING) << "Received config with duplicate key";
continue;
}
seen_host_suffixes.insert(hint_key);
if (!hint.page_hints().empty()) {
// Now that processing is finished on |hint|, move it into the update
// data.
// WARNING: Do not use |hint| after this call. Its contents will no
// longer be valid.
update_data->MoveHintIntoUpdateData(std::move(hint));
did_process_hints = true;
}
}
return did_process_hints;
}
net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
proto::EffectiveConnectionType proto_ect) {
switch (proto_ect) {
......@@ -156,4 +108,18 @@ net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
}
}
bool IsValidURLForURLKeyedHint(const GURL& url) {
if (!url.has_host())
return false;
if (net::IsLocalhost(url))
return false;
if (url.HostIsIPAddress())
return false;
if (!url.SchemeIsHTTPOrHTTPS())
return false;
if (url.has_username() || url.has_password())
return false;
return true;
}
} // namespace optimization_guide
......@@ -13,7 +13,6 @@
class GURL;
namespace optimization_guide {
class StoreUpdateData;
// Returns the string representation of the optimization type.
std::string GetStringNameForOptimizationType(
......@@ -41,17 +40,13 @@ const proto::PageHint* FindPageHintForURL(const GURL& gurl,
// practically zero.
std::string HashHostForDictionary(const std::string& host);
// Verifies and processes |hints| and places the ones it supports into
// |update_data|.
//
// Returns true if there was at least one hint moved into |update_data|.
bool ProcessHints(google::protobuf::RepeatedPtrField<proto::Hint>* hints,
StoreUpdateData* update_data);
// Converts |proto_ect| into a net::EffectiveConnectionType.
net::EffectiveConnectionType ConvertProtoEffectiveConnectionType(
proto::EffectiveConnectionType proto_ect);
// Validates a URL used for URL-keyed hints.
bool IsValidURLForURLKeyedHint(const GURL& url);
} // namespace optimization_guide
#endif // COMPONENTS_OPTIMIZATION_GUIDE_HINTS_PROCESSING_UTIL_H_
......@@ -57,64 +57,6 @@ TEST(HintsProcessingUtilTest, FindPageHintForSubstringPagePattern) {
EXPECT_EQ(page_hint3, FindPageHintForURL(
GURL("https://www.foo.org/bar/three.jpg"), &hint1));
}
TEST(HintsProcessingUtilTest, ProcessHintsNoUpdateData) {
proto::Hint hint;
hint.set_key("whatever.com");
hint.set_key_representation(proto::HOST_SUFFIX);
proto::PageHint* page_hint = hint.add_page_hints();
page_hint->set_page_pattern("foo.org/*/one/");
google::protobuf::RepeatedPtrField<proto::Hint> hints;
*(hints.Add()) = hint;
EXPECT_FALSE(ProcessHints(&hints, nullptr));
}
TEST(HintsProcessingUtilTest, ProcessHintsWithNoPageHintsAndUpdateData) {
proto::Hint hint;
hint.set_key("whatever.com");
hint.set_key_representation(proto::HOST_SUFFIX);
google::protobuf::RepeatedPtrField<proto::Hint> hints;
*(hints.Add()) = hint;
std::unique_ptr<StoreUpdateData> update_data =
StoreUpdateData::CreateComponentStoreUpdateData(base::Version("1.0.0"));
EXPECT_FALSE(ProcessHints(&hints, update_data.get()));
// Verify there is 1 store entries: 1 for the metadata entry.
EXPECT_EQ(1ul, update_data->TakeUpdateEntries()->size());
}
TEST(HintsProcessingUtilTest, ProcessHintsWithPageHintsAndUpdateData) {
google::protobuf::RepeatedPtrField<proto::Hint> hints;
proto::Hint hint;
hint.set_key("foo.org");
hint.set_key_representation(proto::HOST_SUFFIX);
proto::PageHint* page_hint = hint.add_page_hints();
page_hint->set_page_pattern("foo.org/*/one/");
*(hints.Add()) = hint;
proto::Hint no_host_suffix_hint;
no_host_suffix_hint.set_key("foo2.org");
proto::PageHint* page_hint3 = no_host_suffix_hint.add_page_hints();
page_hint3->set_page_pattern("foo2.org/blahh");
*(hints.Add()) = no_host_suffix_hint;
proto::Hint no_page_hints_hint;
no_page_hints_hint.set_key("whatever.com");
no_page_hints_hint.set_key_representation(proto::HOST_SUFFIX);
*(hints.Add()) = no_page_hints_hint;
std::unique_ptr<StoreUpdateData> update_data =
StoreUpdateData::CreateComponentStoreUpdateData(base::Version("1.0.0"));
EXPECT_TRUE(ProcessHints(&hints, update_data.get()));
// Verify there are 2 store entries: 1 for the metadata entry plus
// the 1 added hint entries.
EXPECT_EQ(2ul, update_data->TakeUpdateEntries()->size());
}
TEST(HintsProcessingUtilTest, ConvertProtoEffectiveConnectionType) {
EXPECT_EQ(
ConvertProtoEffectiveConnectionType(
......@@ -139,4 +81,16 @@ TEST(HintsProcessingUtilTest, ConvertProtoEffectiveConnectionType) {
net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G);
}
TEST(HintsProcessingUtilTest, IsValidURLForURLKeyedHints) {
EXPECT_TRUE(IsValidURLForURLKeyedHint(GURL("https://blerg.com")));
EXPECT_TRUE(IsValidURLForURLKeyedHint(GURL("http://blerg.com")));
EXPECT_FALSE(IsValidURLForURLKeyedHint(GURL("file://blerg")));
EXPECT_FALSE(IsValidURLForURLKeyedHint(GURL("chrome://blerg")));
EXPECT_FALSE(IsValidURLForURLKeyedHint(
GURL("https://username:password@www.example.com/")));
EXPECT_FALSE(IsValidURLForURLKeyedHint(GURL("https://localhost:5000")));
EXPECT_FALSE(IsValidURLForURLKeyedHint(GURL("https://192.168.1.1")));
}
} // namespace optimization_guide
......@@ -193,6 +193,12 @@ base::TimeDelta StoredHostModelFeaturesFreshnessDuration() {
"max_store_duration_for_host_model_features_in_days", 7));
}
base::TimeDelta URLKeyedHintValidCacheDuration() {
return base::TimeDelta::FromSeconds(GetFieldTrialParamByFeatureAsInt(
kOptimizationHints, "max_url_keyed_hint_valid_cache_duration_in_seconds",
60 * 60 /* 1 hour */));
}
size_t MaxHostsForOptimizationGuideServiceModelsFetch() {
return GetFieldTrialParamByFeatureAsInt(
kOptimizationTargetPrediction,
......@@ -204,6 +210,11 @@ size_t MaxHostModelFeaturesCacheSize() {
kOptimizationTargetPrediction, "max_host_model_features_cache_size", 100);
}
size_t MaxURLKeyedHintCacheSize() {
return GetFieldTrialParamByFeatureAsInt(kOptimizationHints,
"max_url_keyed_hint_cache_size", 20);
}
bool IsOptimizationTargetPredictionEnabled() {
return base::FeatureList::IsEnabled(kOptimizationTargetPrediction);
}
......
......@@ -99,6 +99,10 @@ bool IsOptimizationTargetPredictionEnabled();
// to be used and remain in the OptimizationGuideStore.
base::TimeDelta StoredHostModelFeaturesFreshnessDuration();
// The amount of time URL-keyed hints within the hint cache will be
// allowed to be used and not be purged.
base::TimeDelta URLKeyedHintValidCacheDuration();
// The maximum number of hosts allowed to be requested by the client to the
// remote Optimzation Guide Service for use by prediction models.
size_t MaxHostsForOptimizationGuideServiceModelsFetch();
......@@ -107,6 +111,10 @@ size_t MaxHostsForOptimizationGuideServiceModelsFetch();
// cache by the prediction manager.
size_t MaxHostModelFeaturesCacheSize();
// The maximum number of hints allowed to be maintained in a least-recently-used
// cache.
size_t MaxURLKeyedHintCacheSize();
// Returns true if the optimization target decision for |optimization_target|
// should not be propagated to the caller in an effort to fully understand the
// statistics for the served model and not taint the resulting data.
......
......@@ -211,14 +211,13 @@ message PageHint {
}
message Hint {
reserved 3;
// Describes the granularity of the key field.
optional KeyRepresentation key_representation = 1;
// The key that applies to this hint. The key_representation field describes
// the form in which this key takes. Guaranteed to be non-empty.
optional string key = 2;
// Top-level optimizations are currently unused on the client as of M-72. This
// may change in the future as new optimization types are added.
repeated Optimization whitelisted_optimizations = 3;
// An ordered set of per-page hints. Only the first PageHint record
// that matches a committed page URL should be used for that page load.
repeated PageHint page_hints = 4;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/optimization_guide/url_keyed_hint.h"
URLKeyedHint::URLKeyedHint(const base::Time expiration_time,
optimization_guide::proto::Hint&& url_keyed_hint)
: expiration_time_(expiration_time),
url_keyed_hint_(
std::make_unique<optimization_guide::proto::Hint>(url_keyed_hint)) {}
URLKeyedHint::~URLKeyedHint() = default;
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_OPTIMIZATION_GUIDE_URL_KEYED_HINT_H_
#define COMPONENTS_OPTIMIZATION_GUIDE_URL_KEYED_HINT_H_
#include "base/time/time.h"
#include "components/optimization_guide/proto/hints.pb.h"
// Holds a hint keyed by URL and its expiration time, used to maintain URL-keyed
// hints in memory.
class URLKeyedHint {
public:
URLKeyedHint(const base::Time expiration_time,
optimization_guide::proto::Hint&& url_keyed_hint);
~URLKeyedHint();
const base::Time expiration_time() const { return expiration_time_; }
optimization_guide::proto::Hint* url_keyed_hint() const {
return url_keyed_hint_.get();
}
private:
const base::Time expiration_time_;
std::unique_ptr<optimization_guide::proto::Hint> url_keyed_hint_;
DISALLOW_COPY_AND_ASSIGN(URLKeyedHint);
};
#endif // COMPONENTS_OPTIMIZATION_GUIDE_URL_KEYED_HINT_H_
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment