store_update_data.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/optimization_guide/core/store_update_data.h"
  5. #include "base/memory/ptr_util.h"
  6. #include "base/strings/string_number_conversions.h"
  7. #include "components/optimization_guide/core/optimization_guide_features.h"
  8. #include "components/optimization_guide/core/optimization_guide_store.h"
  9. #include "components/optimization_guide/proto/hint_cache.pb.h"
  10. #include "components/optimization_guide/proto/hints.pb.h"
  11. #include "components/optimization_guide/proto/models.pb.h"
  12. namespace optimization_guide {
  13. // static
  14. std::unique_ptr<StoreUpdateData>
  15. StoreUpdateData::CreateComponentStoreUpdateData(
  16. const base::Version& component_version) {
  17. return base::WrapUnique<StoreUpdateData>(new StoreUpdateData(
  18. absl::optional<base::Version>(component_version),
  19. absl::optional<base::Time>(), absl::optional<base::Time>()));
  20. }
  21. // static
  22. std::unique_ptr<StoreUpdateData> StoreUpdateData::CreateFetchedStoreUpdateData(
  23. base::Time fetch_update_time) {
  24. return base::WrapUnique<StoreUpdateData>(
  25. new StoreUpdateData(absl::optional<base::Version>(),
  26. absl::optional<base::Time>(fetch_update_time),
  27. absl::optional<base::Time>()));
  28. }
  29. // static
  30. std::unique_ptr<StoreUpdateData>
  31. StoreUpdateData::CreatePredictionModelStoreUpdateData(base::Time expiry_time) {
  32. return base::WrapUnique<StoreUpdateData>(new StoreUpdateData(expiry_time));
  33. }
  34. StoreUpdateData::StoreUpdateData(base::Time expiry_time)
  35. : expiry_time_(expiry_time),
  36. entries_to_save_(std::make_unique<EntryVector>()) {
  37. entry_key_prefix_ =
  38. OptimizationGuideStore::GetPredictionModelEntryKeyPrefix();
  39. // |this| may be modified on another thread after construction but all
  40. // future modifications, from that call forward, must be made on the same
  41. // thread.
  42. DETACH_FROM_SEQUENCE(sequence_checker_);
  43. }
  44. StoreUpdateData::StoreUpdateData(
  45. absl::optional<base::Version> component_version,
  46. absl::optional<base::Time> fetch_update_time,
  47. absl::optional<base::Time> expiry_time)
  48. : component_version_(component_version),
  49. update_time_(fetch_update_time),
  50. expiry_time_(expiry_time),
  51. entries_to_save_(std::make_unique<EntryVector>()) {
  52. DCHECK_NE(!component_version_, !update_time_);
  53. if (component_version_.has_value()) {
  54. entry_key_prefix_ = OptimizationGuideStore::GetComponentHintEntryKeyPrefix(
  55. *component_version_);
  56. // Add a component metadata entry for the component's version.
  57. proto::StoreEntry metadata_component_entry;
  58. metadata_component_entry.set_entry_type(static_cast<proto::StoreEntryType>(
  59. OptimizationGuideStore::StoreEntryType::kMetadata));
  60. metadata_component_entry.set_version(component_version_->GetString());
  61. entries_to_save_->emplace_back(
  62. OptimizationGuideStore::GetMetadataTypeEntryKey(
  63. OptimizationGuideStore::MetadataType::kComponent),
  64. std::move(metadata_component_entry));
  65. } else if (update_time_.has_value()) {
  66. entry_key_prefix_ = OptimizationGuideStore::GetFetchedHintEntryKeyPrefix();
  67. proto::StoreEntry metadata_fetched_entry;
  68. metadata_fetched_entry.set_entry_type(static_cast<proto::StoreEntryType>(
  69. OptimizationGuideStore::StoreEntryType::kMetadata));
  70. metadata_fetched_entry.set_update_time_secs(
  71. update_time_->ToDeltaSinceWindowsEpoch().InSeconds());
  72. entries_to_save_->emplace_back(
  73. OptimizationGuideStore::GetMetadataTypeEntryKey(
  74. OptimizationGuideStore::MetadataType::kFetched),
  75. std::move(metadata_fetched_entry));
  76. } else {
  77. NOTREACHED();
  78. }
  79. // |this| may be modified on another thread after construction but all
  80. // future modifications, from that call forward, must be made on the same
  81. // thread.
  82. DETACH_FROM_SEQUENCE(sequence_checker_);
  83. }
  84. StoreUpdateData::~StoreUpdateData() = default;
  85. void StoreUpdateData::MoveHintIntoUpdateData(proto::Hint&& hint) {
  86. // All future modifications must be made by the same thread. Note, |this| may
  87. // have been constructed on another thread.
  88. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  89. DCHECK(!entry_key_prefix_.empty());
  90. // To avoid any unnecessary copying, the hint is moved into proto::StoreEntry.
  91. OptimizationGuideStore::EntryKey hint_entry_key =
  92. entry_key_prefix_ + hint.key();
  93. proto::StoreEntry entry_proto;
  94. if (component_version()) {
  95. entry_proto.set_entry_type(static_cast<proto::StoreEntryType>(
  96. OptimizationGuideStore::StoreEntryType::kComponentHint));
  97. } else if (update_time()) {
  98. base::TimeDelta expiry_duration;
  99. if (hint.has_max_cache_duration()) {
  100. expiry_duration = base::Seconds(hint.max_cache_duration().seconds());
  101. } else {
  102. expiry_duration = features::StoredFetchedHintsFreshnessDuration();
  103. }
  104. entry_proto.set_expiry_time_secs((base::Time::Now() + expiry_duration)
  105. .ToDeltaSinceWindowsEpoch()
  106. .InSeconds());
  107. entry_proto.set_entry_type(static_cast<proto::StoreEntryType>(
  108. OptimizationGuideStore::StoreEntryType::kFetchedHint));
  109. }
  110. entry_proto.set_allocated_hint(new proto::Hint(std::move(hint)));
  111. entries_to_save_->emplace_back(std::move(hint_entry_key),
  112. std::move(entry_proto));
  113. }
  114. void StoreUpdateData::CopyPredictionModelIntoUpdateData(
  115. const proto::PredictionModel& prediction_model) {
  116. // All future modifications must be made by the same thread. Note, |this| may
  117. // have been constructed on another thread.
  118. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  119. DCHECK(!entry_key_prefix_.empty());
  120. DCHECK(expiry_time_);
  121. // To avoid any unnecessary copying, the prediction model is moved into
  122. // proto::StoreEntry.
  123. OptimizationGuideStore::EntryKey prediction_model_entry_key =
  124. entry_key_prefix_ +
  125. base::NumberToString(static_cast<int>(
  126. prediction_model.model_info().optimization_target()));
  127. proto::StoreEntry entry_proto;
  128. entry_proto.set_entry_type(static_cast<proto::StoreEntryType>(
  129. OptimizationGuideStore::StoreEntryType::kPredictionModel));
  130. base::TimeDelta expiry_duration;
  131. if (prediction_model.model_info().has_valid_duration()) {
  132. expiry_duration =
  133. base::Seconds(prediction_model.model_info().valid_duration().seconds());
  134. } else {
  135. expiry_duration = features::StoredModelsValidDuration();
  136. }
  137. expiry_time_ = base::Time::Now() + expiry_duration;
  138. entry_proto.set_expiry_time_secs(
  139. expiry_time_.value().ToDeltaSinceWindowsEpoch().InSeconds());
  140. entry_proto.set_keep_beyond_valid_duration(
  141. prediction_model.model_info().keep_beyond_valid_duration());
  142. entry_proto.mutable_prediction_model()->CopyFrom(prediction_model);
  143. entries_to_save_->emplace_back(std::move(prediction_model_entry_key),
  144. std::move(entry_proto));
  145. }
  146. std::unique_ptr<EntryVector> StoreUpdateData::TakeUpdateEntries() {
  147. // TakeUpdateEntries is not be sequence checked as it only gives up ownership
  148. // of the entries_to_save_ and does not modify any state.
  149. DCHECK(entries_to_save_);
  150. return std::move(entries_to_save_);
  151. }
  152. } // namespace optimization_guide