| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <memory> |
| 5 #include <set> | 6 #include <set> |
| 6 #include <utility> | 7 #include <utility> |
| 7 #include <vector> | 8 #include <vector> |
| 8 | 9 |
| 9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 12 #include "chrome/browser/predictors/predictor_database.h" | 13 #include "chrome/browser/predictors/predictor_database.h" |
| 13 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" | 14 #include "chrome/browser/predictors/resource_prefetch_predictor_tables.h" |
| 14 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" | 15 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 35 void TestDeleteSingleDataPoint(); | 36 void TestDeleteSingleDataPoint(); |
| 36 void TestDeleteAllData(); | 37 void TestDeleteAllData(); |
| 37 | 38 |
| 38 base::MessageLoop loop_; | 39 base::MessageLoop loop_; |
| 39 content::TestBrowserThread db_thread_; | 40 content::TestBrowserThread db_thread_; |
| 40 TestingProfile profile_; | 41 TestingProfile profile_; |
| 41 std::unique_ptr<PredictorDatabase> db_; | 42 std::unique_ptr<PredictorDatabase> db_; |
| 42 scoped_refptr<ResourcePrefetchPredictorTables> tables_; | 43 scoped_refptr<ResourcePrefetchPredictorTables> tables_; |
| 43 | 44 |
| 44 using PrefetchDataMap = ResourcePrefetchPredictorTables::PrefetchDataMap; | 45 using PrefetchDataMap = ResourcePrefetchPredictorTables::PrefetchDataMap; |
| 46 using RedirectDataMap = ResourcePrefetchPredictorTables::RedirectDataMap; |
| 45 | 47 |
| 46 private: | 48 private: |
| 47 using PrefetchData = ResourcePrefetchPredictorTables::PrefetchData; | 49 using PrefetchData = ResourcePrefetchPredictorTables::PrefetchData; |
| 48 | 50 |
| 49 // Initializes the tables, |test_url_data_| and |test_host_data_|. | 51 // Initializes the tables, |test_url_data_| and |test_host_data_|. |
| 50 void InitializeSampleData(); | 52 void InitializeSampleData(); |
| 51 | 53 |
| 52 // Checks that the input PrefetchData are the same, although the resources | 54 // Checks that the input PrefetchData are the same, although the resources |
| 53 // can be in different order. | 55 // can be in different order. |
| 54 void TestPrefetchDataAreEqual(const PrefetchDataMap& lhs, | 56 void TestPrefetchDataAreEqual(const PrefetchDataMap& lhs, |
| 55 const PrefetchDataMap& rhs) const; | 57 const PrefetchDataMap& rhs) const; |
| 56 void TestResourcesAreEqual(const std::vector<ResourceData>& lhs, | 58 void TestResourcesAreEqual(const std::vector<ResourceData>& lhs, |
| 57 const std::vector<ResourceData>& rhs) const; | 59 const std::vector<ResourceData>& rhs) const; |
| 58 | 60 |
| 61 // Checks that the input RedirectData are the same, although the redirects |
| 62 // can be in different order. |
| 63 void TestRedirectDataAreEqual(const RedirectDataMap& lhs, |
| 64 const RedirectDataMap& rhs) const; |
| 65 void TestRedirectsAreEqual(const std::vector<RedirectStat>& lhs, |
| 66 const std::vector<RedirectStat>& rhs) const; |
| 67 |
| 59 void AddKey(PrefetchDataMap* m, const std::string& key) const; | 68 void AddKey(PrefetchDataMap* m, const std::string& key) const; |
| 69 void AddKey(RedirectDataMap* m, const std::string& key) const; |
| 60 | 70 |
| 61 PrefetchDataMap test_url_data_; | 71 PrefetchDataMap test_url_data_; |
| 62 PrefetchDataMap test_host_data_; | 72 PrefetchDataMap test_host_data_; |
| 73 RedirectDataMap test_url_redirect_data_; |
| 74 RedirectDataMap test_host_redirect_data_; |
| 63 }; | 75 }; |
| 64 | 76 |
| 65 class ResourcePrefetchPredictorTablesReopenTest | 77 class ResourcePrefetchPredictorTablesReopenTest |
| 66 : public ResourcePrefetchPredictorTablesTest { | 78 : public ResourcePrefetchPredictorTablesTest { |
| 67 public: | 79 public: |
| 68 void SetUp() override { | 80 void SetUp() override { |
| 69 // Write data to the table, and then reopen the db. | 81 // Write data to the table, and then reopen the db. |
| 70 ResourcePrefetchPredictorTablesTest::SetUp(); | 82 ResourcePrefetchPredictorTablesTest::SetUp(); |
| 71 ResourcePrefetchPredictorTablesTest::TearDown(); | 83 ResourcePrefetchPredictorTablesTest::TearDown(); |
| 72 | 84 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 91 } | 103 } |
| 92 | 104 |
| 93 void ResourcePrefetchPredictorTablesTest::TearDown() { | 105 void ResourcePrefetchPredictorTablesTest::TearDown() { |
| 94 tables_ = NULL; | 106 tables_ = NULL; |
| 95 db_.reset(); | 107 db_.reset(); |
| 96 base::RunLoop().RunUntilIdle(); | 108 base::RunLoop().RunUntilIdle(); |
| 97 } | 109 } |
| 98 | 110 |
| 99 void ResourcePrefetchPredictorTablesTest::TestGetAllData() { | 111 void ResourcePrefetchPredictorTablesTest::TestGetAllData() { |
| 100 PrefetchDataMap actual_url_data, actual_host_data; | 112 PrefetchDataMap actual_url_data, actual_host_data; |
| 101 tables_->GetAllData(&actual_url_data, &actual_host_data); | 113 RedirectDataMap actual_url_redirect_data, actual_host_redirect_data; |
| 114 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 115 &actual_url_redirect_data, &actual_host_redirect_data); |
| 102 | 116 |
| 103 TestPrefetchDataAreEqual(test_url_data_, actual_url_data); | 117 TestPrefetchDataAreEqual(test_url_data_, actual_url_data); |
| 104 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); | 118 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); |
| 119 TestRedirectDataAreEqual(test_url_redirect_data_, actual_url_redirect_data); |
| 120 TestRedirectDataAreEqual(test_host_redirect_data_, actual_host_redirect_data); |
| 105 } | 121 } |
| 106 | 122 |
| 107 void ResourcePrefetchPredictorTablesTest::TestDeleteData() { | 123 void ResourcePrefetchPredictorTablesTest::TestDeleteData() { |
| 108 std::vector<std::string> urls_to_delete, hosts_to_delete; | 124 std::vector<std::string> urls_to_delete = {"http://www.google.com", |
| 109 urls_to_delete.push_back("http://www.google.com"); | 125 "http://www.yahoo.com"}; |
| 110 urls_to_delete.push_back("http://www.yahoo.com"); | 126 std::vector<std::string> hosts_to_delete = {"www.yahoo.com"}; |
| 111 hosts_to_delete.push_back("www.yahoo.com"); | |
| 112 | 127 |
| 113 tables_->DeleteData(urls_to_delete, hosts_to_delete); | 128 tables_->DeleteResourceData(urls_to_delete, hosts_to_delete); |
| 129 |
| 130 urls_to_delete = {"http://fb.com/google", "http://google.com"}; |
| 131 hosts_to_delete = {"microsoft.com"}; |
| 132 |
| 133 tables_->DeleteRedirectData(urls_to_delete, hosts_to_delete); |
| 114 | 134 |
| 115 PrefetchDataMap actual_url_data, actual_host_data; | 135 PrefetchDataMap actual_url_data, actual_host_data; |
| 116 tables_->GetAllData(&actual_url_data, &actual_host_data); | 136 RedirectDataMap actual_url_redirect_data, actual_host_redirect_data; |
| 137 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 138 &actual_url_redirect_data, &actual_host_redirect_data); |
| 117 | 139 |
| 118 PrefetchDataMap expected_url_data, expected_host_data; | 140 PrefetchDataMap expected_url_data, expected_host_data; |
| 141 RedirectDataMap expected_url_redirect_data, expected_host_redirect_data; |
| 119 AddKey(&expected_url_data, "http://www.reddit.com"); | 142 AddKey(&expected_url_data, "http://www.reddit.com"); |
| 120 AddKey(&expected_host_data, "www.facebook.com"); | 143 AddKey(&expected_host_data, "www.facebook.com"); |
| 144 AddKey(&expected_url_redirect_data, "http://nyt.com"); |
| 145 AddKey(&expected_host_redirect_data, "bbc.com"); |
| 121 | 146 |
| 122 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | 147 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 123 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | 148 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); |
| 149 TestRedirectDataAreEqual(expected_url_redirect_data, |
| 150 actual_url_redirect_data); |
| 151 TestRedirectDataAreEqual(expected_host_redirect_data, |
| 152 actual_host_redirect_data); |
| 124 } | 153 } |
| 125 | 154 |
| 126 void ResourcePrefetchPredictorTablesTest::TestDeleteSingleDataPoint() { | 155 void ResourcePrefetchPredictorTablesTest::TestDeleteSingleDataPoint() { |
| 127 // Delete a URL. | 156 // Delete a URL. |
| 128 tables_->DeleteSingleDataPoint("http://www.reddit.com", | 157 tables_->DeleteSingleResourceDataPoint("http://www.reddit.com", |
| 129 PREFETCH_KEY_TYPE_URL); | 158 PREFETCH_KEY_TYPE_URL); |
| 130 | 159 |
| 131 PrefetchDataMap actual_url_data, actual_host_data; | 160 PrefetchDataMap actual_url_data, actual_host_data; |
| 132 tables_->GetAllData(&actual_url_data, &actual_host_data); | 161 RedirectDataMap actual_url_redirect_data, actual_host_redirect_data; |
| 162 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 163 &actual_url_redirect_data, &actual_host_redirect_data); |
| 133 | 164 |
| 134 PrefetchDataMap expected_url_data; | 165 PrefetchDataMap expected_url_data; |
| 135 AddKey(&expected_url_data, "http://www.google.com"); | 166 AddKey(&expected_url_data, "http://www.google.com"); |
| 136 AddKey(&expected_url_data, "http://www.yahoo.com"); | 167 AddKey(&expected_url_data, "http://www.yahoo.com"); |
| 137 | 168 |
| 138 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | 169 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 139 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); | 170 TestPrefetchDataAreEqual(test_host_data_, actual_host_data); |
| 171 TestRedirectDataAreEqual(test_url_redirect_data_, actual_url_redirect_data); |
| 172 TestRedirectDataAreEqual(test_host_redirect_data_, actual_host_redirect_data); |
| 140 | 173 |
| 141 // Delete a host. | 174 // Delete a host. |
| 142 tables_->DeleteSingleDataPoint("www.facebook.com", PREFETCH_KEY_TYPE_HOST); | 175 tables_->DeleteSingleResourceDataPoint("www.facebook.com", |
| 176 PREFETCH_KEY_TYPE_HOST); |
| 143 actual_url_data.clear(); | 177 actual_url_data.clear(); |
| 144 actual_host_data.clear(); | 178 actual_host_data.clear(); |
| 145 tables_->GetAllData(&actual_url_data, &actual_host_data); | 179 actual_url_redirect_data.clear(); |
| 180 actual_host_redirect_data.clear(); |
| 181 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 182 &actual_url_redirect_data, &actual_host_redirect_data); |
| 146 | 183 |
| 147 PrefetchDataMap expected_host_data; | 184 PrefetchDataMap expected_host_data; |
| 148 AddKey(&expected_host_data, "www.yahoo.com"); | 185 AddKey(&expected_host_data, "www.yahoo.com"); |
| 149 | 186 |
| 150 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | 187 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 151 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | 188 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); |
| 189 TestRedirectDataAreEqual(test_url_redirect_data_, actual_url_redirect_data); |
| 190 TestRedirectDataAreEqual(test_host_redirect_data_, actual_host_redirect_data); |
| 191 |
| 192 // Delete a URL redirect. |
| 193 tables_->DeleteSingleRedirectDataPoint("http://nyt.com", |
| 194 PREFETCH_KEY_TYPE_URL); |
| 195 actual_url_data.clear(); |
| 196 actual_host_data.clear(); |
| 197 actual_url_redirect_data.clear(); |
| 198 actual_host_redirect_data.clear(); |
| 199 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 200 &actual_url_redirect_data, &actual_host_redirect_data); |
| 201 |
| 202 RedirectDataMap expected_url_redirect_data; |
| 203 AddKey(&expected_url_redirect_data, "http://fb.com/google"); |
| 204 AddKey(&expected_url_redirect_data, "http://google.com"); |
| 205 |
| 206 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 207 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); |
| 208 TestRedirectDataAreEqual(expected_url_redirect_data, |
| 209 actual_url_redirect_data); |
| 210 TestRedirectDataAreEqual(test_host_redirect_data_, actual_host_redirect_data); |
| 211 |
| 212 // Delete a host redirect. |
| 213 tables_->DeleteSingleRedirectDataPoint("bbc.com", PREFETCH_KEY_TYPE_HOST); |
| 214 actual_url_data.clear(); |
| 215 actual_host_data.clear(); |
| 216 actual_url_redirect_data.clear(); |
| 217 actual_host_redirect_data.clear(); |
| 218 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 219 &actual_url_redirect_data, &actual_host_redirect_data); |
| 220 |
| 221 RedirectDataMap expected_host_redirect_data; |
| 222 AddKey(&expected_host_redirect_data, "microsoft.com"); |
| 223 |
| 224 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 225 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); |
| 226 TestRedirectDataAreEqual(expected_url_redirect_data, |
| 227 actual_url_redirect_data); |
| 228 TestRedirectDataAreEqual(expected_host_redirect_data, |
| 229 actual_host_redirect_data); |
| 152 } | 230 } |
| 153 | 231 |
| 154 void ResourcePrefetchPredictorTablesTest::TestUpdateData() { | 232 void ResourcePrefetchPredictorTablesTest::TestUpdateData() { |
| 155 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); | 233 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); |
| 156 google.last_visit = base::Time::FromInternalValue(10); | 234 google.last_visit = base::Time::FromInternalValue(10); |
| 157 google.resources.push_back(CreateResourceData( | 235 google.resources.push_back(CreateResourceData( |
| 158 "http://www.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET, 6, | 236 "http://www.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET, 6, |
| 159 2, 0, 1.0, net::MEDIUM, true, false)); | 237 2, 0, 1.0, net::MEDIUM, true, false)); |
| 160 google.resources.push_back(CreateResourceData( | 238 google.resources.push_back(CreateResourceData( |
| 161 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 6, 4, 1, | 239 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 6, 4, 1, |
| 162 4.2, net::MEDIUM, false, false)); | 240 4.2, net::MEDIUM, false, false)); |
| 163 google.resources.push_back(CreateResourceData( | 241 google.resources.push_back(CreateResourceData( |
| 164 "http://www.google.com/a.xml", content::RESOURCE_TYPE_LAST_TYPE, 1, 0, 0, | 242 "http://www.google.com/a.xml", content::RESOURCE_TYPE_LAST_TYPE, 1, 0, 0, |
| 165 6.1, net::MEDIUM, false, false)); | 243 6.1, net::MEDIUM, false, false)); |
| 166 google.resources.push_back(CreateResourceData( | 244 google.resources.push_back(CreateResourceData( |
| 167 "http://www.resources.google.com/script.js", | 245 "http://www.resources.google.com/script.js", |
| 168 content::RESOURCE_TYPE_SCRIPT, 12, 0, 0, 8.5, net::MEDIUM, true, true)); | 246 content::RESOURCE_TYPE_SCRIPT, 12, 0, 0, 8.5, net::MEDIUM, true, true)); |
| 169 | 247 |
| 170 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); | 248 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); |
| 171 yahoo.last_visit = base::Time::FromInternalValue(7); | 249 yahoo.last_visit = base::Time::FromInternalValue(7); |
| 172 yahoo.resources.push_back(CreateResourceData( | 250 yahoo.resources.push_back(CreateResourceData( |
| 173 "http://www.yahoo.com/image.png", content::RESOURCE_TYPE_IMAGE, 120, 1, 1, | 251 "http://www.yahoo.com/image.png", content::RESOURCE_TYPE_IMAGE, 120, 1, 1, |
| 174 10.0, net::MEDIUM, true, false)); | 252 10.0, net::MEDIUM, true, false)); |
| 175 | 253 |
| 176 tables_->UpdateData(google, yahoo); | 254 RedirectData facebook; |
| 255 facebook.set_primary_key("http://fb.com/google"); |
| 256 facebook.set_last_visit_time(20); |
| 257 InitializeRedirectStat(facebook.add_redirects(), "https://facebook.fr/google", |
| 258 4, 2, 1); |
| 259 |
| 260 RedirectData microsoft; |
| 261 microsoft.set_primary_key("microsoft.com"); |
| 262 microsoft.set_last_visit_time(21); |
| 263 InitializeRedirectStat(microsoft.add_redirects(), "m.microsoft.com", 5, 7, 1); |
| 264 InitializeRedirectStat(microsoft.add_redirects(), "microsoft.org", 7, 2, 0); |
| 265 |
| 266 tables_->UpdateData(google, yahoo, facebook, microsoft); |
| 177 | 267 |
| 178 PrefetchDataMap actual_url_data, actual_host_data; | 268 PrefetchDataMap actual_url_data, actual_host_data; |
| 179 tables_->GetAllData(&actual_url_data, &actual_host_data); | 269 RedirectDataMap actual_url_redirect_data, actual_host_redirect_data; |
| 270 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 271 &actual_url_redirect_data, &actual_host_redirect_data); |
| 180 | 272 |
| 181 PrefetchDataMap expected_url_data, expected_host_data; | 273 PrefetchDataMap expected_url_data, expected_host_data; |
| 274 RedirectDataMap expected_url_redirect_data, expected_host_redirect_data; |
| 182 AddKey(&expected_url_data, "http://www.reddit.com"); | 275 AddKey(&expected_url_data, "http://www.reddit.com"); |
| 183 AddKey(&expected_url_data, "http://www.yahoo.com"); | 276 AddKey(&expected_url_data, "http://www.yahoo.com"); |
| 184 expected_url_data.insert(std::make_pair("http://www.google.com", google)); | 277 expected_url_data.insert(std::make_pair("http://www.google.com", google)); |
| 185 | 278 |
| 186 AddKey(&expected_host_data, "www.facebook.com"); | 279 AddKey(&expected_host_data, "www.facebook.com"); |
| 187 expected_host_data.insert(std::make_pair("www.yahoo.com", yahoo)); | 280 expected_host_data.insert(std::make_pair("www.yahoo.com", yahoo)); |
| 188 | 281 |
| 282 AddKey(&expected_url_redirect_data, "http://nyt.com"); |
| 283 AddKey(&expected_url_redirect_data, "http://google.com"); |
| 284 expected_url_redirect_data.insert( |
| 285 std::make_pair("http://fb.com/google", facebook)); |
| 286 |
| 287 AddKey(&expected_host_redirect_data, "bbc.com"); |
| 288 expected_host_redirect_data.insert( |
| 289 std::make_pair("microsoft.com", microsoft)); |
| 290 |
| 189 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); | 291 TestPrefetchDataAreEqual(expected_url_data, actual_url_data); |
| 190 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); | 292 TestPrefetchDataAreEqual(expected_host_data, actual_host_data); |
| 293 TestRedirectDataAreEqual(expected_url_redirect_data, |
| 294 actual_url_redirect_data); |
| 295 TestRedirectDataAreEqual(expected_host_redirect_data, |
| 296 actual_host_redirect_data); |
| 191 } | 297 } |
| 192 | 298 |
| 193 void ResourcePrefetchPredictorTablesTest::TestDeleteAllData() { | 299 void ResourcePrefetchPredictorTablesTest::TestDeleteAllData() { |
| 194 tables_->DeleteAllData(); | 300 tables_->DeleteAllData(); |
| 195 | 301 |
| 196 PrefetchDataMap actual_url_data, actual_host_data; | 302 PrefetchDataMap actual_url_data, actual_host_data; |
| 197 tables_->GetAllData(&actual_url_data, &actual_host_data); | 303 RedirectDataMap actual_url_redirect_data, actual_host_redirect_data; |
| 304 tables_->GetAllData(&actual_url_data, &actual_host_data, |
| 305 &actual_url_redirect_data, &actual_host_redirect_data); |
| 198 EXPECT_TRUE(actual_url_data.empty()); | 306 EXPECT_TRUE(actual_url_data.empty()); |
| 199 EXPECT_TRUE(actual_host_data.empty()); | 307 EXPECT_TRUE(actual_host_data.empty()); |
| 308 EXPECT_TRUE(actual_url_redirect_data.empty()); |
| 309 EXPECT_TRUE(actual_host_redirect_data.empty()); |
| 200 } | 310 } |
| 201 | 311 |
| 202 void ResourcePrefetchPredictorTablesTest::TestPrefetchDataAreEqual( | 312 void ResourcePrefetchPredictorTablesTest::TestPrefetchDataAreEqual( |
| 203 const PrefetchDataMap& lhs, | 313 const PrefetchDataMap& lhs, |
| 204 const PrefetchDataMap& rhs) const { | 314 const PrefetchDataMap& rhs) const { |
| 205 EXPECT_EQ(lhs.size(), rhs.size()); | 315 EXPECT_EQ(lhs.size(), rhs.size()); |
| 206 | 316 |
| 207 for (const std::pair<std::string, PrefetchData>& p : rhs) { | 317 for (const std::pair<std::string, PrefetchData>& p : rhs) { |
| 208 PrefetchDataMap::const_iterator lhs_it = lhs.find(p.first); | 318 const auto lhs_it = lhs.find(p.first); |
| 209 ASSERT_TRUE(lhs_it != lhs.end()) << p.first; | 319 ASSERT_TRUE(lhs_it != lhs.end()) << p.first; |
| 320 EXPECT_TRUE(lhs_it->second.key_type == p.second.key_type); |
| 321 EXPECT_TRUE(lhs_it->second.last_visit == p.second.last_visit); |
| 210 | 322 |
| 211 TestResourcesAreEqual(lhs_it->second.resources, p.second.resources); | 323 TestResourcesAreEqual(lhs_it->second.resources, p.second.resources); |
| 212 } | 324 } |
| 213 } | 325 } |
| 214 | 326 |
| 215 void ResourcePrefetchPredictorTablesTest::TestResourcesAreEqual( | 327 void ResourcePrefetchPredictorTablesTest::TestResourcesAreEqual( |
| 216 const std::vector<ResourceData>& lhs, | 328 const std::vector<ResourceData>& lhs, |
| 217 const std::vector<ResourceData>& rhs) const { | 329 const std::vector<ResourceData>& rhs) const { |
| 218 EXPECT_EQ(lhs.size(), rhs.size()); | 330 EXPECT_EQ(lhs.size(), rhs.size()); |
| 219 | 331 |
| 220 std::set<std::string> resources_seen; | 332 std::set<std::string> resources_seen; |
| 221 for (const auto& rhs_resource : rhs) { | 333 for (const auto& rhs_resource : rhs) { |
| 222 const std::string& resource = rhs_resource.resource_url(); | 334 const std::string& resource = rhs_resource.resource_url(); |
| 223 EXPECT_FALSE(base::ContainsKey(resources_seen, resource)); | 335 EXPECT_FALSE(base::ContainsKey(resources_seen, resource)); |
| 224 | 336 |
| 225 for (const auto& lhs_resource : lhs) { | 337 for (const auto& lhs_resource : lhs) { |
| 226 if (lhs_resource == rhs_resource) { | 338 if (lhs_resource == rhs_resource) { |
| 227 resources_seen.insert(resource); | 339 resources_seen.insert(resource); |
| 228 break; | 340 break; |
| 229 } | 341 } |
| 230 } | 342 } |
| 231 EXPECT_TRUE(base::ContainsKey(resources_seen, resource)); | 343 EXPECT_TRUE(base::ContainsKey(resources_seen, resource)); |
| 232 } | 344 } |
| 233 EXPECT_EQ(lhs.size(), resources_seen.size()); | 345 EXPECT_EQ(lhs.size(), resources_seen.size()); |
| 234 } | 346 } |
| 235 | 347 |
| 348 void ResourcePrefetchPredictorTablesTest::TestRedirectDataAreEqual( |
| 349 const RedirectDataMap& lhs, |
| 350 const RedirectDataMap& rhs) const { |
| 351 EXPECT_EQ(lhs.size(), rhs.size()); |
| 352 |
| 353 for (const auto& p : rhs) { |
| 354 const auto lhs_it = lhs.find(p.first); |
| 355 ASSERT_TRUE(lhs_it != lhs.end()) << p.first; |
| 356 EXPECT_EQ(lhs_it->second.primary_key(), p.second.primary_key()); |
| 357 EXPECT_EQ(lhs_it->second.last_visit_time(), p.second.last_visit_time()); |
| 358 |
| 359 std::vector<RedirectStat> lhs_redirects(lhs_it->second.redirects().begin(), |
| 360 lhs_it->second.redirects().end()); |
| 361 std::vector<RedirectStat> rhs_redirects(p.second.redirects().begin(), |
| 362 p.second.redirects().end()); |
| 363 |
| 364 TestRedirectsAreEqual(lhs_redirects, rhs_redirects); |
| 365 } |
| 366 } |
| 367 |
| 368 void ResourcePrefetchPredictorTablesTest::TestRedirectsAreEqual( |
| 369 const std::vector<RedirectStat>& lhs, |
| 370 const std::vector<RedirectStat>& rhs) const { |
| 371 EXPECT_EQ(lhs.size(), rhs.size()); |
| 372 |
| 373 std::map<std::string, RedirectStat> lhs_index; |
| 374 // Repeated redirects are not allowed. |
| 375 for (const auto& r : lhs) |
| 376 EXPECT_TRUE(lhs_index.insert(std::make_pair(r.url(), r)).second); |
| 377 |
| 378 for (const auto& r : rhs) { |
| 379 auto lhs_it = lhs_index.find(r.url()); |
| 380 if (lhs_it != lhs_index.end()) { |
| 381 EXPECT_EQ(r, lhs_it->second); |
| 382 lhs_index.erase(lhs_it); |
| 383 } else { |
| 384 ADD_FAILURE() << r.url(); |
| 385 } |
| 386 } |
| 387 |
| 388 EXPECT_TRUE(lhs_index.empty()); |
| 389 } |
| 390 |
| 236 void ResourcePrefetchPredictorTablesTest::AddKey(PrefetchDataMap* m, | 391 void ResourcePrefetchPredictorTablesTest::AddKey(PrefetchDataMap* m, |
| 237 const std::string& key) const { | 392 const std::string& key) const { |
| 238 PrefetchDataMap::const_iterator it = test_url_data_.find(key); | 393 PrefetchDataMap::const_iterator it = test_url_data_.find(key); |
| 239 if (it != test_url_data_.end()) { | 394 if (it != test_url_data_.end()) { |
| 240 m->insert(std::make_pair(it->first, it->second)); | 395 m->insert(*it); |
| 241 return; | 396 return; |
| 242 } | 397 } |
| 243 it = test_host_data_.find(key); | 398 it = test_host_data_.find(key); |
| 244 ASSERT_TRUE(it != test_host_data_.end()); | 399 ASSERT_TRUE(it != test_host_data_.end()); |
| 245 m->insert(std::make_pair(it->first, it->second)); | 400 m->insert(*it); |
| 401 } |
| 402 |
| 403 void ResourcePrefetchPredictorTablesTest::AddKey(RedirectDataMap* m, |
| 404 const std::string& key) const { |
| 405 auto it = test_url_redirect_data_.find(key); |
| 406 if (it != test_url_redirect_data_.end()) { |
| 407 m->insert(*it); |
| 408 return; |
| 409 } |
| 410 it = test_host_redirect_data_.find(key); |
| 411 ASSERT_TRUE(it != test_host_redirect_data_.end()); |
| 412 m->insert(*it); |
| 246 } | 413 } |
| 247 | 414 |
| 248 void ResourcePrefetchPredictorTablesTest::InitializeSampleData() { | 415 void ResourcePrefetchPredictorTablesTest::InitializeSampleData() { |
| 416 PrefetchData empty_url_data(PREFETCH_KEY_TYPE_URL, std::string()); |
| 417 PrefetchData empty_host_data(PREFETCH_KEY_TYPE_HOST, std::string()); |
| 418 RedirectData empty_url_redirect_data; |
| 419 RedirectData empty_host_redirect_data; |
| 420 |
| 249 { // Url data. | 421 { // Url data. |
| 250 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); | 422 PrefetchData google(PREFETCH_KEY_TYPE_URL, "http://www.google.com"); |
| 251 google.last_visit = base::Time::FromInternalValue(1); | 423 google.last_visit = base::Time::FromInternalValue(1); |
| 252 google.resources.push_back(CreateResourceData( | 424 google.resources.push_back(CreateResourceData( |
| 253 "http://www.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET, 5, | 425 "http://www.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET, 5, |
| 254 2, 1, 1.1, net::MEDIUM, false, false)); | 426 2, 1, 1.1, net::MEDIUM, false, false)); |
| 255 google.resources.push_back(CreateResourceData( | 427 google.resources.push_back(CreateResourceData( |
| 256 "http://www.google.com/script.js", content::RESOURCE_TYPE_SCRIPT, 4, 0, | 428 "http://www.google.com/script.js", content::RESOURCE_TYPE_SCRIPT, 4, 0, |
| 257 1, 2.1, net::MEDIUM, false, false)); | 429 1, 2.1, net::MEDIUM, false, false)); |
| 258 google.resources.push_back(CreateResourceData( | 430 google.resources.push_back(CreateResourceData( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 279 yahoo.last_visit = base::Time::FromInternalValue(3); | 451 yahoo.last_visit = base::Time::FromInternalValue(3); |
| 280 yahoo.resources.push_back(CreateResourceData( | 452 yahoo.resources.push_back(CreateResourceData( |
| 281 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 20, 1, | 453 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 20, 1, |
| 282 0, 10.0, net::MEDIUM, false, false)); | 454 0, 10.0, net::MEDIUM, false, false)); |
| 283 | 455 |
| 284 test_url_data_.clear(); | 456 test_url_data_.clear(); |
| 285 test_url_data_.insert(std::make_pair("http://www.google.com", google)); | 457 test_url_data_.insert(std::make_pair("http://www.google.com", google)); |
| 286 test_url_data_.insert(std::make_pair("http://www.reddit.com", reddit)); | 458 test_url_data_.insert(std::make_pair("http://www.reddit.com", reddit)); |
| 287 test_url_data_.insert(std::make_pair("http://www.yahoo.com", yahoo)); | 459 test_url_data_.insert(std::make_pair("http://www.yahoo.com", yahoo)); |
| 288 | 460 |
| 289 PrefetchData empty_host_data(PREFETCH_KEY_TYPE_HOST, std::string()); | 461 tables_->UpdateData(google, empty_host_data, empty_url_redirect_data, |
| 290 tables_->UpdateData(google, empty_host_data); | 462 empty_host_redirect_data); |
| 291 tables_->UpdateData(reddit, empty_host_data); | 463 tables_->UpdateData(reddit, empty_host_data, empty_url_redirect_data, |
| 292 tables_->UpdateData(yahoo, empty_host_data); | 464 empty_host_redirect_data); |
| 465 tables_->UpdateData(yahoo, empty_host_data, empty_url_redirect_data, |
| 466 empty_host_redirect_data); |
| 293 } | 467 } |
| 294 | 468 |
| 295 { // Host data. | 469 { // Host data. |
| 296 PrefetchData facebook(PREFETCH_KEY_TYPE_HOST, "www.facebook.com"); | 470 PrefetchData facebook(PREFETCH_KEY_TYPE_HOST, "www.facebook.com"); |
| 297 facebook.last_visit = base::Time::FromInternalValue(4); | 471 facebook.last_visit = base::Time::FromInternalValue(4); |
| 298 facebook.resources.push_back(CreateResourceData( | 472 facebook.resources.push_back(CreateResourceData( |
| 299 "http://www.facebook.com/style.css", content::RESOURCE_TYPE_STYLESHEET, | 473 "http://www.facebook.com/style.css", content::RESOURCE_TYPE_STYLESHEET, |
| 300 5, 2, 1, 1.1, net::MEDIUM, false, false)); | 474 5, 2, 1, 1.1, net::MEDIUM, false, false)); |
| 301 facebook.resources.push_back(CreateResourceData( | 475 facebook.resources.push_back(CreateResourceData( |
| 302 "http://www.facebook.com/script.js", content::RESOURCE_TYPE_SCRIPT, 4, | 476 "http://www.facebook.com/script.js", content::RESOURCE_TYPE_SCRIPT, 4, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 315 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); | 489 PrefetchData yahoo(PREFETCH_KEY_TYPE_HOST, "www.yahoo.com"); |
| 316 yahoo.last_visit = base::Time::FromInternalValue(5); | 490 yahoo.last_visit = base::Time::FromInternalValue(5); |
| 317 yahoo.resources.push_back(CreateResourceData( | 491 yahoo.resources.push_back(CreateResourceData( |
| 318 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 20, 1, | 492 "http://www.google.com/image.png", content::RESOURCE_TYPE_IMAGE, 20, 1, |
| 319 0, 10.0, net::MEDIUM, false, false)); | 493 0, 10.0, net::MEDIUM, false, false)); |
| 320 | 494 |
| 321 test_host_data_.clear(); | 495 test_host_data_.clear(); |
| 322 test_host_data_.insert(std::make_pair("www.facebook.com", facebook)); | 496 test_host_data_.insert(std::make_pair("www.facebook.com", facebook)); |
| 323 test_host_data_.insert(std::make_pair("www.yahoo.com", yahoo)); | 497 test_host_data_.insert(std::make_pair("www.yahoo.com", yahoo)); |
| 324 | 498 |
| 325 PrefetchData empty_url_data(PREFETCH_KEY_TYPE_URL, std::string()); | 499 tables_->UpdateData(empty_url_data, facebook, empty_url_redirect_data, |
| 326 tables_->UpdateData(empty_url_data, facebook); | 500 empty_host_redirect_data); |
| 327 tables_->UpdateData(empty_url_data, yahoo); | 501 tables_->UpdateData(empty_url_data, yahoo, empty_url_redirect_data, |
| 502 empty_host_redirect_data); |
| 503 } |
| 504 |
| 505 { // Url redirect data. |
| 506 RedirectData facebook; |
| 507 facebook.set_primary_key("http://fb.com/google"); |
| 508 facebook.set_last_visit_time(6); |
| 509 InitializeRedirectStat(facebook.add_redirects(), |
| 510 "https://facebook.com/google", 5, 1, 0); |
| 511 InitializeRedirectStat(facebook.add_redirects(), |
| 512 "https://facebook.com/login", 3, 5, 1); |
| 513 |
| 514 RedirectData nytimes; |
| 515 nytimes.set_primary_key("http://nyt.com"); |
| 516 nytimes.set_last_visit_time(7); |
| 517 InitializeRedirectStat(nytimes.add_redirects(), "https://nytimes.com", 2, 0, |
| 518 0); |
| 519 |
| 520 RedirectData google; |
| 521 google.set_primary_key("http://google.com"); |
| 522 google.set_last_visit_time(8); |
| 523 InitializeRedirectStat(google.add_redirects(), "https://google.com", 3, 0, |
| 524 0); |
| 525 |
| 526 test_url_redirect_data_.clear(); |
| 527 test_url_redirect_data_.insert( |
| 528 std::make_pair(facebook.primary_key(), facebook)); |
| 529 test_url_redirect_data_.insert( |
| 530 std::make_pair(nytimes.primary_key(), nytimes)); |
| 531 test_url_redirect_data_.insert( |
| 532 std::make_pair(google.primary_key(), google)); |
| 533 |
| 534 tables_->UpdateData(empty_url_data, empty_host_data, facebook, |
| 535 empty_host_redirect_data); |
| 536 tables_->UpdateData(empty_url_data, empty_host_data, nytimes, |
| 537 empty_host_redirect_data); |
| 538 tables_->UpdateData(empty_url_data, empty_host_data, google, |
| 539 empty_host_redirect_data); |
| 540 } |
| 541 |
| 542 { // Host redirect data. |
| 543 RedirectData bbc; |
| 544 bbc.set_primary_key("bbc.com"); |
| 545 bbc.set_last_visit_time(9); |
| 546 InitializeRedirectStat(bbc.add_redirects(), "www.bbc.com", 8, 4, 1); |
| 547 InitializeRedirectStat(bbc.add_redirects(), "m.bbc.com", 5, 8, 0); |
| 548 InitializeRedirectStat(bbc.add_redirects(), "bbc.co.uk", 1, 3, 0); |
| 549 |
| 550 RedirectData microsoft; |
| 551 microsoft.set_primary_key("microsoft.com"); |
| 552 microsoft.set_last_visit_time(10); |
| 553 InitializeRedirectStat(microsoft.add_redirects(), "www.microsoft.com", 10, |
| 554 0, 0); |
| 555 |
| 556 test_host_redirect_data_.clear(); |
| 557 test_host_redirect_data_.insert(std::make_pair(bbc.primary_key(), bbc)); |
| 558 test_host_redirect_data_.insert( |
| 559 std::make_pair(microsoft.primary_key(), microsoft)); |
| 560 tables_->UpdateData(empty_url_data, empty_host_data, |
| 561 empty_url_redirect_data, bbc); |
| 562 tables_->UpdateData(empty_url_data, empty_host_data, |
| 563 empty_url_redirect_data, microsoft); |
| 328 } | 564 } |
| 329 } | 565 } |
| 330 | 566 |
| 331 void ResourcePrefetchPredictorTablesTest::ReopenDatabase() { | 567 void ResourcePrefetchPredictorTablesTest::ReopenDatabase() { |
| 332 db_.reset(new PredictorDatabase(&profile_)); | 568 db_.reset(new PredictorDatabase(&profile_)); |
| 333 base::RunLoop().RunUntilIdle(); | 569 base::RunLoop().RunUntilIdle(); |
| 334 tables_ = db_->resource_prefetch_tables(); | 570 tables_ = db_->resource_prefetch_tables(); |
| 335 } | 571 } |
| 336 | 572 |
| 337 // Test cases. | 573 // Test cases. |
| 338 | 574 |
| 339 TEST_F(ResourcePrefetchPredictorTablesTest, ComputeScore) { | 575 TEST_F(ResourcePrefetchPredictorTablesTest, ComputeResourceScore) { |
| 340 ResourceData js_resource = CreateResourceData( | 576 ResourceData js_resource = CreateResourceData( |
| 341 "http://www.resources.google.com/script.js", | 577 "http://www.resources.google.com/script.js", |
| 342 content::RESOURCE_TYPE_SCRIPT, 11, 0, 0, 1., net::MEDIUM, false, false); | 578 content::RESOURCE_TYPE_SCRIPT, 11, 0, 0, 1., net::MEDIUM, false, false); |
| 343 ResourceData image_resource = CreateResourceData( | 579 ResourceData image_resource = CreateResourceData( |
| 344 "http://www.resources.google.com/image.jpg", content::RESOURCE_TYPE_IMAGE, | 580 "http://www.resources.google.com/image.jpg", content::RESOURCE_TYPE_IMAGE, |
| 345 11, 0, 0, 1., net::MEDIUM, false, false); | 581 11, 0, 0, 1., net::MEDIUM, false, false); |
| 346 ResourceData css_resource = | 582 ResourceData css_resource = |
| 347 CreateResourceData("http://www.resources.google.com/stylesheet.css", | 583 CreateResourceData("http://www.resources.google.com/stylesheet.css", |
| 348 content::RESOURCE_TYPE_STYLESHEET, 11, 0, 0, 1., | 584 content::RESOURCE_TYPE_STYLESHEET, 11, 0, 0, 1., |
| 349 net::MEDIUM, false, false); | 585 net::MEDIUM, false, false); |
| 350 ResourceData font_resource = | 586 ResourceData font_resource = |
| 351 CreateResourceData("http://www.resources.google.com/font.woff", | 587 CreateResourceData("http://www.resources.google.com/font.woff", |
| 352 content::RESOURCE_TYPE_FONT_RESOURCE, 11, 0, 0, 1., | 588 content::RESOURCE_TYPE_FONT_RESOURCE, 11, 0, 0, 1., |
| 353 net::MEDIUM, false, false); | 589 net::MEDIUM, false, false); |
| 354 float js_resource_score = | 590 float js_resource_score = |
| 355 ResourcePrefetchPredictorTables::ComputeScore(js_resource); | 591 ResourcePrefetchPredictorTables::ComputeResourceScore(js_resource); |
| 356 float css_resource_score = | 592 float css_resource_score = |
| 357 ResourcePrefetchPredictorTables::ComputeScore(css_resource); | 593 ResourcePrefetchPredictorTables::ComputeResourceScore(css_resource); |
| 358 float font_resource_score = | 594 float font_resource_score = |
| 359 ResourcePrefetchPredictorTables::ComputeScore(font_resource); | 595 ResourcePrefetchPredictorTables::ComputeResourceScore(font_resource); |
| 360 float image_resource_score = | 596 float image_resource_score = |
| 361 ResourcePrefetchPredictorTables::ComputeScore(image_resource); | 597 ResourcePrefetchPredictorTables::ComputeResourceScore(image_resource); |
| 362 | 598 |
| 363 EXPECT_TRUE(js_resource_score == css_resource_score); | 599 EXPECT_TRUE(js_resource_score == css_resource_score); |
| 364 EXPECT_TRUE(js_resource_score == font_resource_score); | 600 EXPECT_TRUE(js_resource_score == font_resource_score); |
| 365 EXPECT_NEAR(199., js_resource_score, 1e-4); | 601 EXPECT_NEAR(199., js_resource_score, 1e-4); |
| 366 EXPECT_NEAR(99., image_resource_score, 1e-4); | 602 EXPECT_NEAR(99., image_resource_score, 1e-4); |
| 367 } | 603 } |
| 368 | 604 |
| 369 TEST_F(ResourcePrefetchPredictorTablesTest, GetAllData) { | 605 TEST_F(ResourcePrefetchPredictorTablesTest, GetAllData) { |
| 370 TestGetAllData(); | 606 TestGetAllData(); |
| 371 } | 607 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 399 ResourcePrefetchPredictorTables::SetDatabaseVersion(db, version + 1)); | 635 ResourcePrefetchPredictorTables::SetDatabaseVersion(db, version + 1)); |
| 400 EXPECT_EQ(version + 1, | 636 EXPECT_EQ(version + 1, |
| 401 ResourcePrefetchPredictorTables::GetDatabaseVersion(db)); | 637 ResourcePrefetchPredictorTables::GetDatabaseVersion(db)); |
| 402 | 638 |
| 403 ReopenDatabase(); | 639 ReopenDatabase(); |
| 404 | 640 |
| 405 db = tables_->DB(); | 641 db = tables_->DB(); |
| 406 ASSERT_EQ(version, ResourcePrefetchPredictorTables::GetDatabaseVersion(db)); | 642 ASSERT_EQ(version, ResourcePrefetchPredictorTables::GetDatabaseVersion(db)); |
| 407 | 643 |
| 408 PrefetchDataMap url_data, host_data; | 644 PrefetchDataMap url_data, host_data; |
| 409 tables_->GetAllData(&url_data, &host_data); | 645 RedirectDataMap url_redirect_data, host_redirect_data; |
| 646 tables_->GetAllData(&url_data, &host_data, &url_redirect_data, |
| 647 &host_redirect_data); |
| 410 EXPECT_TRUE(url_data.empty()); | 648 EXPECT_TRUE(url_data.empty()); |
| 411 EXPECT_TRUE(host_data.empty()); | 649 EXPECT_TRUE(host_data.empty()); |
| 412 } | 650 } |
| 413 | 651 |
| 414 TEST_F(ResourcePrefetchPredictorTablesReopenTest, GetAllData) { | 652 TEST_F(ResourcePrefetchPredictorTablesReopenTest, GetAllData) { |
| 415 TestGetAllData(); | 653 TestGetAllData(); |
| 416 } | 654 } |
| 417 | 655 |
| 418 TEST_F(ResourcePrefetchPredictorTablesReopenTest, UpdateData) { | 656 TEST_F(ResourcePrefetchPredictorTablesReopenTest, UpdateData) { |
| 419 TestUpdateData(); | 657 TestUpdateData(); |
| 420 } | 658 } |
| 421 | 659 |
| 422 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteData) { | 660 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteData) { |
| 423 TestDeleteData(); | 661 TestDeleteData(); |
| 424 } | 662 } |
| 425 | 663 |
| 426 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteSingleDataPoint) { | 664 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteSingleDataPoint) { |
| 427 TestDeleteSingleDataPoint(); | 665 TestDeleteSingleDataPoint(); |
| 428 } | 666 } |
| 429 | 667 |
| 430 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteAllData) { | 668 TEST_F(ResourcePrefetchPredictorTablesReopenTest, DeleteAllData) { |
| 431 TestDeleteAllData(); | 669 TestDeleteAllData(); |
| 432 } | 670 } |
| 433 | 671 |
| 434 } // namespace predictors | 672 } // namespace predictors |
| OLD | NEW |