Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/precache/core/precache_fetcher.h" | 5 #include "components/precache/core/precache_fetcher.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/base64.h" | 13 #include "base/base64.h" |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
| 16 #include "base/callback.h" | 16 #include "base/callback.h" |
| 17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
| 18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 19 #include "base/containers/hash_tables.h" | 19 #include "base/containers/hash_tables.h" |
| 20 #include "base/location.h" | 20 #include "base/location.h" |
| 21 #include "base/logging.h" | 21 #include "base/logging.h" |
| 22 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" |
| 23 #include "base/memory/ref_counted.h" | 23 #include "base/memory/ref_counted.h" |
| 24 #include "base/metrics/histogram_macros.h" | 24 #include "base/metrics/histogram_macros.h" |
| 25 #include "base/optional.h" | |
| 25 #include "base/sha1.h" | 26 #include "base/sha1.h" |
| 26 #include "base/strings/string_piece.h" | 27 #include "base/strings/string_piece.h" |
| 27 #include "base/task_runner_util.h" | 28 #include "base/task_runner_util.h" |
| 28 #include "components/data_use_measurement/core/data_use_user_data.h" | 29 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 29 #include "components/precache/core/precache_database.h" | 30 #include "components/precache/core/precache_database.h" |
| 30 #include "components/precache/core/precache_switches.h" | 31 #include "components/precache/core/precache_switches.h" |
| 31 #include "components/precache/core/proto/quota.pb.h" | 32 #include "components/precache/core/proto/quota.pb.h" |
| 32 #include "components/precache/core/proto/unfinished_work.pb.h" | 33 #include "components/precache/core/proto/unfinished_work.pb.h" |
| 33 #include "net/base/completion_callback.h" | 34 #include "net/base/completion_callback.h" |
| 34 #include "net/base/escape.h" | 35 #include "net/base/escape.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 } | 119 } |
| 119 if (!message->ParseFromString(response_string)) { | 120 if (!message->ParseFromString(response_string)) { |
| 120 DLOG(WARNING) << "Unable to parse proto served from " | 121 DLOG(WARNING) << "Unable to parse proto served from " |
| 121 << source.GetOriginalURL().spec(); | 122 << source.GetOriginalURL().spec(); |
| 122 return false; | 123 return false; |
| 123 } | 124 } |
| 124 return true; | 125 return true; |
| 125 } | 126 } |
| 126 | 127 |
| 127 // Returns the resource selection bitset from the |manifest| for the given | 128 // Returns the resource selection bitset from the |manifest| for the given |
| 128 // |experiment_id|. By default all resource will be selected if the experiment | 129 // |experiment_id|. If the experiment group is not found, then this returns |
| 129 // group is not found. | 130 // nullopt, in which case all resources should be selected. |
| 130 uint64_t GetResourceBitset(const PrecacheManifest& manifest, | 131 base::Optional<std::vector<bool>> GetResourceBitset( |
| 131 uint32_t experiment_id) { | 132 const PrecacheManifest& manifest, |
| 133 uint32_t experiment_id) { | |
|
pasko
2017/02/24 13:42:33
Do I understand correctly that each server manifes
twifkak
2017/02/24 21:20:12
Yup.
pasko
2017/02/27 18:12:16
Ah, thank you for background. Naive question: why
twifkak
2017/02/27 21:46:28
Perhaps I misunderstand your question. The bitsets
pasko
2017/02/28 12:21:31
Oh, ah. Having bitsets _for_ filtering makes a lot
| |
| 134 base::Optional<std::vector<bool>> ret; | |
| 132 if (manifest.has_experiments()) { | 135 if (manifest.has_experiments()) { |
| 133 const auto& resource_bitset_map = | 136 const auto& resource_bitset_map = |
| 134 manifest.experiments().resources_by_experiment_group(); | 137 manifest.experiments().resources_by_experiment_group(); |
| 135 const auto& resource_bitset_it = resource_bitset_map.find(experiment_id); | 138 const auto& it = resource_bitset_map.find(experiment_id); |
| 136 if (resource_bitset_it != resource_bitset_map.end()) | 139 if (it != resource_bitset_map.end()) { |
| 137 return resource_bitset_it->second.bitset(); | 140 if (it->second.has_bitset()) { |
| 141 const std::string& bitset = it->second.bitset(); | |
| 142 ret.emplace(bitset.size() * 8); | |
| 143 for (size_t i = 0; i < bitset.size(); ++i) { | |
| 144 for (size_t j = 0; j < 8; ++j) { | |
| 145 if ((1 << j) & bitset[i]) | |
| 146 ret.value()[i * 8 + j] = true; | |
| 147 } | |
| 148 } | |
| 149 } else if (it->second.has_deprecated_bitset()) { | |
| 150 uint64_t bitset = it->second.deprecated_bitset(); | |
| 151 ret.emplace(64); | |
| 152 for (int i = 0; i < 64; ++i) { | |
| 153 if ((0x1ULL << i) & bitset) | |
| 154 ret.value()[i] = true; | |
| 155 } | |
| 156 } | |
| 157 } | |
| 138 } | 158 } |
| 139 return ~0ULL; | 159 // Only return one variable to ensure RVO triggers. |
|
pasko
2017/02/24 13:42:33
what is RVO? Render View Observer?
twifkak
2017/02/24 21:20:12
Return Value Optimization. Constructs the object o
pasko
2017/02/27 18:12:16
Acknowledged.
| |
| 160 return ret; | |
| 140 } | 161 } |
| 141 | 162 |
| 142 // URLFetcherResponseWriter that ignores the response body, in order to avoid | 163 // URLFetcherResponseWriter that ignores the response body, in order to avoid |
| 143 // the unnecessary memory usage. Use it rather than the default if you don't | 164 // the unnecessary memory usage. Use it rather than the default if you don't |
| 144 // care about parsing the response body. We use it below as a means to populate | 165 // care about parsing the response body. We use it below as a means to populate |
| 145 // the cache with requested resource URLs. | 166 // the cache with requested resource URLs. |
| 146 class URLFetcherNullWriter : public net::URLFetcherResponseWriter { | 167 class URLFetcherNullWriter : public net::URLFetcherResponseWriter { |
| 147 public: | 168 public: |
| 148 int Initialize(const net::CompletionCallback& callback) override { | 169 int Initialize(const net::CompletionCallback& callback) override { |
| 149 return net::OK; | 170 return net::OK; |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 UpdateStats(source.response_bytes(), source.network_response_bytes()); | 760 UpdateStats(source.response_bytes(), source.network_response_bytes()); |
| 740 if (source.network_url_fetcher() == nullptr) { | 761 if (source.network_url_fetcher() == nullptr) { |
| 741 pool_.DeleteAll(); // Cancel any other ongoing request. | 762 pool_.DeleteAll(); // Cancel any other ongoing request. |
| 742 } else { | 763 } else { |
| 743 PrecacheManifest manifest; | 764 PrecacheManifest manifest; |
| 744 | 765 |
| 745 if (ParseProtoFromFetchResponse(*source.network_url_fetcher(), &manifest)) { | 766 if (ParseProtoFromFetchResponse(*source.network_url_fetcher(), &manifest)) { |
| 746 const int32_t len = | 767 const int32_t len = |
| 747 std::min(manifest.resource_size(), | 768 std::min(manifest.resource_size(), |
| 748 unfinished_work_->config_settings().top_resources_count()); | 769 unfinished_work_->config_settings().top_resources_count()); |
| 749 const uint64_t resource_bitset = | 770 const base::Optional<std::vector<bool>> resource_bitset = |
| 750 GetResourceBitset(manifest, experiment_id_); | 771 GetResourceBitset(manifest, experiment_id_); |
| 751 for (int i = 0; i < len; ++i) { | 772 for (int i = 0; i < len; ++i) { |
| 752 if (((0x1ULL << i) & resource_bitset) && | 773 if ((!resource_bitset.has_value() || resource_bitset.value()[i]) && |
| 753 manifest.resource(i).has_url()) { | 774 manifest.resource(i).has_url()) { |
| 754 GURL url(manifest.resource(i).url()); | 775 GURL url(manifest.resource(i).url()); |
| 755 if (url.is_valid()) { | 776 if (url.is_valid()) { |
| 756 double weight = ResourceWeight( | 777 double weight = ResourceWeight( |
| 757 unfinished_work_->config_settings().resource_weight_function(), | 778 unfinished_work_->config_settings().resource_weight_function(), |
| 758 manifest.resource(i).weight_ratio(), host_visits); | 779 manifest.resource(i).weight_ratio(), host_visits); |
| 759 if (weight >= unfinished_work_->config_settings().min_weight()) | 780 if (weight >= unfinished_work_->config_settings().min_weight()) |
| 760 resources_to_rank_.emplace_back(url, source.referrer(), weight); | 781 resources_to_rank_.emplace_back(url, source.referrer(), weight); |
| 761 } | 782 } |
| 762 } | 783 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 remaining = 0; | 864 remaining = 0; |
| 844 quota_.set_remaining( | 865 quota_.set_remaining( |
| 845 used_bytes > quota_.remaining() ? 0U : quota_.remaining() - used_bytes); | 866 used_bytes > quota_.remaining() ? 0U : quota_.remaining() - used_bytes); |
| 846 db_task_runner_->PostTask( | 867 db_task_runner_->PostTask( |
| 847 FROM_HERE, | 868 FROM_HERE, |
| 848 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_)); | 869 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_)); |
| 849 } | 870 } |
| 850 } | 871 } |
| 851 | 872 |
| 852 } // namespace precache | 873 } // namespace precache |
| OLD | NEW |