Chromium Code Reviews| 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 "net/sdch/sdch_owner.h" | 5 #include "net/sdch/sdch_owner.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/alias.h" | 8 #include "base/debug/alias.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| 11 #include "base/prefs/persistent_pref_store.h" | 11 #include "base/prefs/persistent_pref_store.h" |
| 12 #include "base/prefs/value_map_pref_store.h" | 12 #include "base/prefs/value_map_pref_store.h" |
| 13 #include "base/process/process_info.h" | |
| 13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 14 #include "base/time/default_clock.h" | 15 #include "base/time/default_clock.h" |
| 15 #include "base/values.h" | 16 #include "base/values.h" |
| 16 #include "net/base/sdch_manager.h" | 17 #include "net/base/sdch_manager.h" |
| 17 #include "net/base/sdch_net_log_params.h" | 18 #include "net/base/sdch_net_log_params.h" |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 explicit DictionaryPreferenceIterator(WriteablePrefStore* pref_store); | 171 explicit DictionaryPreferenceIterator(WriteablePrefStore* pref_store); |
| 171 | 172 |
| 172 bool IsAtEnd() const; | 173 bool IsAtEnd() const; |
| 173 void Advance(); | 174 void Advance(); |
| 174 | 175 |
| 175 const std::string& server_hash() const { return server_hash_; } | 176 const std::string& server_hash() const { return server_hash_; } |
| 176 const GURL url() const { return url_; } | 177 const GURL url() const { return url_; } |
| 177 base::Time last_used() const { return last_used_; } | 178 base::Time last_used() const { return last_used_; } |
| 178 int use_count() const { return use_count_; } | 179 int use_count() const { return use_count_; } |
| 179 int size() const { return size_; } | 180 int size() const { return size_; } |
| 181 base::Time load_time() const { return load_time_; } | |
| 180 | 182 |
| 181 private: | 183 private: |
| 182 void LoadDictionaryOrDie(); | 184 void LoadDictionaryOrDie(); |
| 183 | 185 |
| 184 std::string server_hash_; | 186 std::string server_hash_; |
| 185 GURL url_; | 187 GURL url_; |
| 186 base::Time last_used_; | 188 base::Time last_used_; |
| 187 int use_count_; | 189 int use_count_; |
| 188 int size_; | 190 int size_; |
| 191 base::Time load_time_; | |
|
Randy Smith (Not in Mondays)
2015/04/03 13:25:29
I'm probably missing something really obvious, but
Elly Fong-Jones
2015/04/03 15:21:00
Yeah, this was vestigal. Removed.
| |
| 189 | 192 |
| 190 base::DictionaryValue::Iterator dictionary_iterator_; | 193 base::DictionaryValue::Iterator dictionary_iterator_; |
| 191 }; | 194 }; |
| 192 | 195 |
| 193 DictionaryPreferenceIterator::DictionaryPreferenceIterator( | 196 DictionaryPreferenceIterator::DictionaryPreferenceIterator( |
| 194 WriteablePrefStore* pref_store) | 197 WriteablePrefStore* pref_store) |
| 195 : dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) { | 198 : dictionary_iterator_(*GetPersistentStoreDictionaryMap(pref_store)) { |
| 196 if (!IsAtEnd()) | 199 if (!IsAtEnd()) |
| 197 LoadDictionaryOrDie(); | 200 LoadDictionaryOrDie(); |
| 198 } | 201 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 CHECK(manager_.get()); | 306 CHECK(manager_.get()); |
| 304 #endif | 307 #endif |
| 305 | 308 |
| 306 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); | 309 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); |
| 307 it.Advance()) { | 310 it.Advance()) { |
| 308 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; | 311 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; |
| 309 DictionaryFate fate = IsPersistingDictionaries() ? | 312 DictionaryFate fate = IsPersistingDictionaries() ? |
| 310 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION : | 313 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION : |
| 311 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION; | 314 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION; |
| 312 RecordDictionaryEvictionOrUnload(new_uses, fate); | 315 RecordDictionaryEvictionOrUnload(new_uses, fate); |
| 316 RecordDictionaryLifetime(it.server_hash(), it.size()); | |
| 313 } | 317 } |
| 314 manager_->RemoveObserver(this); | 318 manager_->RemoveObserver(this); |
| 315 | 319 |
| 316 // This object only observes the external store during loading, | 320 // This object only observes the external store during loading, |
| 317 // i.e. before it's made the default preferences store. | 321 // i.e. before it's made the default preferences store. |
| 318 if (external_pref_store_) | 322 if (external_pref_store_) |
| 319 external_pref_store_->RemoveObserver(this); | 323 external_pref_store_->RemoveObserver(this); |
| 320 | 324 |
| 321 #if defined(OS_CHROMEOS) | 325 #if defined(OS_CHROMEOS) |
| 322 destroyed_ = 0xdeadbeef; | 326 destroyed_ = 0xdeadbeef; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 344 void SdchOwner::OnDictionaryFetched(base::Time last_used, | 348 void SdchOwner::OnDictionaryFetched(base::Time last_used, |
| 345 int use_count, | 349 int use_count, |
| 346 const std::string& dictionary_text, | 350 const std::string& dictionary_text, |
| 347 const GURL& dictionary_url, | 351 const GURL& dictionary_url, |
| 348 const net::BoundNetLog& net_log) { | 352 const net::BoundNetLog& net_log) { |
| 349 struct DictionaryItem { | 353 struct DictionaryItem { |
| 350 base::Time last_used; | 354 base::Time last_used; |
| 351 std::string server_hash; | 355 std::string server_hash; |
| 352 int use_count; | 356 int use_count; |
| 353 size_t dictionary_size; | 357 size_t dictionary_size; |
| 358 base::Time load_time; | |
| 354 | 359 |
| 355 DictionaryItem() : use_count(0), dictionary_size(0) {} | 360 DictionaryItem() : use_count(0), dictionary_size(0) {} |
| 356 DictionaryItem(const base::Time& last_used, | 361 DictionaryItem(const base::Time& last_used, |
| 357 const std::string& server_hash, | 362 const std::string& server_hash, |
| 358 int use_count, | 363 int use_count, |
| 359 size_t dictionary_size) | 364 size_t dictionary_size, |
| 365 const base::Time& load_time) | |
| 360 : last_used(last_used), | 366 : last_used(last_used), |
| 361 server_hash(server_hash), | 367 server_hash(server_hash), |
| 362 use_count(use_count), | 368 use_count(use_count), |
| 363 dictionary_size(dictionary_size) {} | 369 dictionary_size(dictionary_size), |
| 370 load_time(load_time) {} | |
| 364 DictionaryItem(const DictionaryItem& rhs) = default; | 371 DictionaryItem(const DictionaryItem& rhs) = default; |
| 365 DictionaryItem& operator=(const DictionaryItem& rhs) = default; | 372 DictionaryItem& operator=(const DictionaryItem& rhs) = default; |
| 366 bool operator<(const DictionaryItem& rhs) const { | 373 bool operator<(const DictionaryItem& rhs) const { |
| 367 return last_used < rhs.last_used; | 374 return last_used < rhs.last_used; |
| 368 } | 375 } |
| 369 }; | 376 }; |
| 370 | 377 |
| 371 #if defined(OS_CHROMEOS) | 378 #if defined(OS_CHROMEOS) |
| 372 // For debugging http://crbug.com/454198; remove when resolved. | 379 // For debugging http://crbug.com/454198; remove when resolved. |
| 373 CHECK_EQ(0u, destroyed_); | 380 CHECK_EQ(0u, destroyed_); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 386 now - base::TimeDelta::FromHours(kFreshnessLifetimeHours)); | 393 now - base::TimeDelta::FromHours(kFreshnessLifetimeHours)); |
| 387 // Dictionaries that have never been used and are from before | 394 // Dictionaries that have never been used and are from before |
| 388 // |never_used_stale_boundary| are candidates for eviction if necessary. | 395 // |never_used_stale_boundary| are candidates for eviction if necessary. |
| 389 base::Time never_used_stale_boundary( | 396 base::Time never_used_stale_boundary( |
| 390 now - base::TimeDelta::FromHours(kNeverUsedFreshnessLifetimeHours)); | 397 now - base::TimeDelta::FromHours(kNeverUsedFreshnessLifetimeHours)); |
| 391 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); | 398 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); |
| 392 it.Advance()) { | 399 it.Advance()) { |
| 393 if (it.last_used() < stale_boundary || | 400 if (it.last_used() < stale_boundary || |
| 394 (it.use_count() == 0 && it.last_used() < never_used_stale_boundary)) { | 401 (it.use_count() == 0 && it.last_used() < never_used_stale_boundary)) { |
| 395 stale_dictionary_list.push_back(DictionaryItem( | 402 stale_dictionary_list.push_back(DictionaryItem( |
| 396 it.last_used(), it.server_hash(), it.use_count(), it.size())); | 403 it.last_used(), it.server_hash(), it.use_count(), it.size(), |
| 404 it.load_time())); | |
|
Randy Smith (Not in Mondays)
2015/04/03 13:25:29
Shouldn't this be a lookup in the load_times_ map?
Elly Fong-Jones
2015/04/03 15:20:59
Done.
| |
| 397 recoverable_bytes += it.size(); | 405 recoverable_bytes += it.size(); |
| 398 } | 406 } |
| 399 } | 407 } |
| 400 | 408 |
| 401 #if defined(OS_CHROMEOS) | 409 #if defined(OS_CHROMEOS) |
| 402 // For debugging http://crbug.com/454198; remove when resolved. | 410 // For debugging http://crbug.com/454198; remove when resolved. |
| 403 CHECK_EQ(0u, destroyed_); | 411 CHECK_EQ(0u, destroyed_); |
| 404 CHECK(clock_.get()); | 412 CHECK(clock_.get()); |
| 405 #endif | 413 #endif |
| 406 | 414 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 bool success = pref_dictionary_map->RemoveWithoutPathExpansion( | 453 bool success = pref_dictionary_map->RemoveWithoutPathExpansion( |
| 446 stale_it->server_hash, nullptr); | 454 stale_it->server_hash, nullptr); |
| 447 DCHECK(success); | 455 DCHECK(success); |
| 448 | 456 |
| 449 avail_bytes += stale_it->dictionary_size; | 457 avail_bytes += stale_it->dictionary_size; |
| 450 | 458 |
| 451 int new_uses = stale_it->use_count - | 459 int new_uses = stale_it->use_count - |
| 452 use_counts_at_load_[stale_it->server_hash]; | 460 use_counts_at_load_[stale_it->server_hash]; |
| 453 RecordDictionaryEvictionOrUnload(new_uses, | 461 RecordDictionaryEvictionOrUnload(new_uses, |
| 454 DICTIONARY_FATE_EVICT_FOR_DICT); | 462 DICTIONARY_FATE_EVICT_FOR_DICT); |
| 463 RecordDictionaryLifetime(stale_it->server_hash, stale_it->dictionary_size); | |
| 455 | 464 |
| 456 ++stale_it; | 465 ++stale_it; |
| 457 } | 466 } |
| 458 DCHECK_GE(avail_bytes, dictionary_text.size()); | 467 DCHECK_GE(avail_bytes, dictionary_text.size()); |
| 459 | 468 |
| 460 RecordDictionaryFate( | 469 RecordDictionaryFate( |
| 461 // Distinguish between loads triggered by network responses and | 470 // Distinguish between loads triggered by network responses and |
| 462 // loads triggered by persistence. | 471 // loads triggered by persistence. |
| 463 last_used.is_null() ? DICTIONARY_FATE_ADD_RESPONSE_TRIGGERED | 472 last_used.is_null() ? DICTIONARY_FATE_ADD_RESPONSE_TRIGGERED |
| 464 : DICTIONARY_FATE_ADD_PERSISTENCE_TRIGGERED); | 473 : DICTIONARY_FATE_ADD_PERSISTENCE_TRIGGERED); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 480 // Record the addition in the pref store. | 489 // Record the addition in the pref store. |
| 481 scoped_ptr<base::DictionaryValue> dictionary_description( | 490 scoped_ptr<base::DictionaryValue> dictionary_description( |
| 482 new base::DictionaryValue()); | 491 new base::DictionaryValue()); |
| 483 dictionary_description->SetString(kDictionaryUrlKey, dictionary_url.spec()); | 492 dictionary_description->SetString(kDictionaryUrlKey, dictionary_url.spec()); |
| 484 dictionary_description->SetDouble(kDictionaryLastUsedKey, | 493 dictionary_description->SetDouble(kDictionaryLastUsedKey, |
| 485 last_used.ToDoubleT()); | 494 last_used.ToDoubleT()); |
| 486 dictionary_description->SetInteger(kDictionaryUseCountKey, use_count); | 495 dictionary_description->SetInteger(kDictionaryUseCountKey, use_count); |
| 487 dictionary_description->SetInteger(kDictionarySizeKey, | 496 dictionary_description->SetInteger(kDictionarySizeKey, |
| 488 dictionary_text.size()); | 497 dictionary_text.size()); |
| 489 pref_dictionary_map->Set(server_hash, dictionary_description.Pass()); | 498 pref_dictionary_map->Set(server_hash, dictionary_description.Pass()); |
| 499 load_times_[server_hash] = clock_->Now(); | |
| 490 } | 500 } |
| 491 | 501 |
| 492 void SdchOwner::OnDictionaryUsed(SdchManager* manager, | 502 void SdchOwner::OnDictionaryUsed(SdchManager* manager, |
| 493 const std::string& server_hash) { | 503 const std::string& server_hash) { |
| 494 base::Time now(clock_->Now()); | 504 base::Time now(clock_->Now()); |
| 495 base::DictionaryValue* pref_dictionary_map = | 505 base::DictionaryValue* pref_dictionary_map = |
| 496 GetPersistentStoreDictionaryMap(pref_store_); | 506 GetPersistentStoreDictionaryMap(pref_store_); |
| 497 ScopedPrefNotifier scoped_pref_notifier(pref_store_); | 507 ScopedPrefNotifier scoped_pref_notifier(pref_store_); |
| 498 | 508 |
| 499 base::Value* value = nullptr; | 509 base::Value* value = nullptr; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 base::Time::FromDoubleT(last_used), use_count)); | 783 base::Time::FromDoubleT(last_used), use_count)); |
| 774 } | 784 } |
| 775 | 785 |
| 776 return true; | 786 return true; |
| 777 } | 787 } |
| 778 | 788 |
| 779 bool SdchOwner::IsPersistingDictionaries() const { | 789 bool SdchOwner::IsPersistingDictionaries() const { |
| 780 return in_memory_pref_store_.get() != nullptr; | 790 return in_memory_pref_store_.get() != nullptr; |
| 781 } | 791 } |
| 782 | 792 |
| 793 void SdchOwner::RecordDictionaryLifetime(const std::string& server_hash, | |
| 794 size_t size) { | |
| 795 if (load_times_.count(server_hash) == 0) | |
|
Randy Smith (Not in Mondays)
2015/04/03 13:25:29
When will this happen? Shouldn't this be a DCHECK
Elly Fong-Jones
2015/04/03 15:21:00
Done.
| |
| 796 return; | |
| 797 base::Time now = clock_->Now(); | |
| 798 base::TimeDelta dict_lifetime = now - load_times_[server_hash]; | |
| 799 base::TimeDelta process_lifetime = now - | |
| 800 base::CurrentProcessInfo::CreationTime(); | |
| 801 int64 frac = (size * dict_lifetime.InMilliseconds()) / | |
| 802 process_lifetime.InMilliseconds(); | |
| 803 UMA_HISTOGRAM_COUNTS("Sdch3.TimeWeightedMemoryUse", frac); | |
| 804 } | |
| 805 | |
| 783 } // namespace net | 806 } // namespace net |
| OLD | NEW |