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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 CHECK(manager_.get()); | 304 CHECK(manager_.get()); |
| 304 #endif | 305 #endif |
| 305 | 306 |
| 306 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); | 307 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); |
| 307 it.Advance()) { | 308 it.Advance()) { |
| 308 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; | 309 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; |
| 309 DictionaryFate fate = IsPersistingDictionaries() ? | 310 DictionaryFate fate = IsPersistingDictionaries() ? |
| 310 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION : | 311 DICTIONARY_FATE_UNLOAD_FOR_DESTRUCTION : |
| 311 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION; | 312 DICTIONARY_FATE_EVICT_FOR_DESTRUCTION; |
| 312 RecordDictionaryEvictionOrUnload(new_uses, fate); | 313 RecordDictionaryEvictionOrUnload(new_uses, fate); |
| 314 RecordDictionaryLifetime(it.server_hash(), it.size()); | |
| 313 } | 315 } |
| 314 manager_->RemoveObserver(this); | 316 manager_->RemoveObserver(this); |
| 315 | 317 |
| 316 // This object only observes the external store during loading, | 318 // This object only observes the external store during loading, |
| 317 // i.e. before it's made the default preferences store. | 319 // i.e. before it's made the default preferences store. |
| 318 if (external_pref_store_) | 320 if (external_pref_store_) |
| 319 external_pref_store_->RemoveObserver(this); | 321 external_pref_store_->RemoveObserver(this); |
| 320 | 322 |
| 321 #if defined(OS_CHROMEOS) | 323 #if defined(OS_CHROMEOS) |
| 322 destroyed_ = 0xdeadbeef; | 324 destroyed_ = 0xdeadbeef; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 344 void SdchOwner::OnDictionaryFetched(base::Time last_used, | 346 void SdchOwner::OnDictionaryFetched(base::Time last_used, |
| 345 int use_count, | 347 int use_count, |
| 346 const std::string& dictionary_text, | 348 const std::string& dictionary_text, |
| 347 const GURL& dictionary_url, | 349 const GURL& dictionary_url, |
| 348 const net::BoundNetLog& net_log) { | 350 const net::BoundNetLog& net_log) { |
| 349 struct DictionaryItem { | 351 struct DictionaryItem { |
| 350 base::Time last_used; | 352 base::Time last_used; |
| 351 std::string server_hash; | 353 std::string server_hash; |
| 352 int use_count; | 354 int use_count; |
| 353 size_t dictionary_size; | 355 size_t dictionary_size; |
| 356 base::Time load_time; | |
|
Randy Smith (Not in Mondays)
2015/04/03 16:08:18
??
Elly Fong-Jones
2015/04/03 20:24:23
Done.
| |
| 354 | 357 |
| 355 DictionaryItem() : use_count(0), dictionary_size(0) {} | 358 DictionaryItem() : use_count(0), dictionary_size(0) {} |
| 356 DictionaryItem(const base::Time& last_used, | 359 DictionaryItem(const base::Time& last_used, |
| 357 const std::string& server_hash, | 360 const std::string& server_hash, |
| 358 int use_count, | 361 int use_count, |
| 359 size_t dictionary_size) | 362 size_t dictionary_size) |
| 360 : last_used(last_used), | 363 : last_used(last_used), |
| 361 server_hash(server_hash), | 364 server_hash(server_hash), |
| 362 use_count(use_count), | 365 use_count(use_count), |
| 363 dictionary_size(dictionary_size) {} | 366 dictionary_size(dictionary_size) {} |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 bool success = pref_dictionary_map->RemoveWithoutPathExpansion( | 448 bool success = pref_dictionary_map->RemoveWithoutPathExpansion( |
| 446 stale_it->server_hash, nullptr); | 449 stale_it->server_hash, nullptr); |
| 447 DCHECK(success); | 450 DCHECK(success); |
| 448 | 451 |
| 449 avail_bytes += stale_it->dictionary_size; | 452 avail_bytes += stale_it->dictionary_size; |
| 450 | 453 |
| 451 int new_uses = stale_it->use_count - | 454 int new_uses = stale_it->use_count - |
| 452 use_counts_at_load_[stale_it->server_hash]; | 455 use_counts_at_load_[stale_it->server_hash]; |
| 453 RecordDictionaryEvictionOrUnload(new_uses, | 456 RecordDictionaryEvictionOrUnload(new_uses, |
| 454 DICTIONARY_FATE_EVICT_FOR_DICT); | 457 DICTIONARY_FATE_EVICT_FOR_DICT); |
| 458 RecordDictionaryLifetime(stale_it->server_hash, stale_it->dictionary_size); | |
| 455 | 459 |
| 456 ++stale_it; | 460 ++stale_it; |
| 457 } | 461 } |
| 458 DCHECK_GE(avail_bytes, dictionary_text.size()); | 462 DCHECK_GE(avail_bytes, dictionary_text.size()); |
| 459 | 463 |
| 460 RecordDictionaryFate( | 464 RecordDictionaryFate( |
| 461 // Distinguish between loads triggered by network responses and | 465 // Distinguish between loads triggered by network responses and |
| 462 // loads triggered by persistence. | 466 // loads triggered by persistence. |
| 463 last_used.is_null() ? DICTIONARY_FATE_ADD_RESPONSE_TRIGGERED | 467 last_used.is_null() ? DICTIONARY_FATE_ADD_RESPONSE_TRIGGERED |
| 464 : DICTIONARY_FATE_ADD_PERSISTENCE_TRIGGERED); | 468 : DICTIONARY_FATE_ADD_PERSISTENCE_TRIGGERED); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 480 // Record the addition in the pref store. | 484 // Record the addition in the pref store. |
| 481 scoped_ptr<base::DictionaryValue> dictionary_description( | 485 scoped_ptr<base::DictionaryValue> dictionary_description( |
| 482 new base::DictionaryValue()); | 486 new base::DictionaryValue()); |
| 483 dictionary_description->SetString(kDictionaryUrlKey, dictionary_url.spec()); | 487 dictionary_description->SetString(kDictionaryUrlKey, dictionary_url.spec()); |
| 484 dictionary_description->SetDouble(kDictionaryLastUsedKey, | 488 dictionary_description->SetDouble(kDictionaryLastUsedKey, |
| 485 last_used.ToDoubleT()); | 489 last_used.ToDoubleT()); |
| 486 dictionary_description->SetInteger(kDictionaryUseCountKey, use_count); | 490 dictionary_description->SetInteger(kDictionaryUseCountKey, use_count); |
| 487 dictionary_description->SetInteger(kDictionarySizeKey, | 491 dictionary_description->SetInteger(kDictionarySizeKey, |
| 488 dictionary_text.size()); | 492 dictionary_text.size()); |
| 489 pref_dictionary_map->Set(server_hash, dictionary_description.Pass()); | 493 pref_dictionary_map->Set(server_hash, dictionary_description.Pass()); |
| 494 load_times_[server_hash] = clock_->Now(); | |
| 490 } | 495 } |
| 491 | 496 |
| 492 void SdchOwner::OnDictionaryUsed(SdchManager* manager, | 497 void SdchOwner::OnDictionaryUsed(SdchManager* manager, |
| 493 const std::string& server_hash) { | 498 const std::string& server_hash) { |
| 494 base::Time now(clock_->Now()); | 499 base::Time now(clock_->Now()); |
| 495 base::DictionaryValue* pref_dictionary_map = | 500 base::DictionaryValue* pref_dictionary_map = |
| 496 GetPersistentStoreDictionaryMap(pref_store_); | 501 GetPersistentStoreDictionaryMap(pref_store_); |
| 497 ScopedPrefNotifier scoped_pref_notifier(pref_store_); | 502 ScopedPrefNotifier scoped_pref_notifier(pref_store_); |
| 498 | 503 |
| 499 base::Value* value = nullptr; | 504 base::Value* value = nullptr; |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 713 } | 718 } |
| 714 | 719 |
| 715 void SdchOwner::OnMemoryPressure( | 720 void SdchOwner::OnMemoryPressure( |
| 716 base::MemoryPressureListener::MemoryPressureLevel level) { | 721 base::MemoryPressureListener::MemoryPressureLevel level) { |
| 717 DCHECK_NE(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE, level); | 722 DCHECK_NE(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE, level); |
| 718 | 723 |
| 719 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); | 724 for (DictionaryPreferenceIterator it(pref_store_); !it.IsAtEnd(); |
| 720 it.Advance()) { | 725 it.Advance()) { |
| 721 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; | 726 int new_uses = it.use_count() - use_counts_at_load_[it.server_hash()]; |
| 722 RecordDictionaryEvictionOrUnload(new_uses, | 727 RecordDictionaryEvictionOrUnload(new_uses, |
| 723 DICTIONARY_FATE_EVICT_FOR_MEMORY); | 728 DICTIONARY_FATE_EVICT_FOR_MEMORY); |
|
Randy Smith (Not in Mondays)
2015/04/03 16:08:18
Why isn't there a RecordDictionaryLifetime here?
Elly Fong-Jones
2015/04/03 20:24:23
Done.
| |
| 724 } | 729 } |
| 725 | 730 |
| 726 // TODO(rdsmith): Make a distinction between moderate and critical | 731 // TODO(rdsmith): Make a distinction between moderate and critical |
| 727 // memory pressure. | 732 // memory pressure. |
| 728 manager_->ClearData(); | 733 manager_->ClearData(); |
| 729 } | 734 } |
| 730 | 735 |
| 731 bool SdchOwner::SchedulePersistedDictionaryLoads( | 736 bool SdchOwner::SchedulePersistedDictionaryLoads( |
| 732 const base::DictionaryValue& persisted_info) { | 737 const base::DictionaryValue& persisted_info) { |
| 733 // Any schema error will result in dropping the persisted info. | 738 // Any schema error will result in dropping the persisted info. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 773 base::Time::FromDoubleT(last_used), use_count)); | 778 base::Time::FromDoubleT(last_used), use_count)); |
| 774 } | 779 } |
| 775 | 780 |
| 776 return true; | 781 return true; |
| 777 } | 782 } |
| 778 | 783 |
| 779 bool SdchOwner::IsPersistingDictionaries() const { | 784 bool SdchOwner::IsPersistingDictionaries() const { |
| 780 return in_memory_pref_store_.get() != nullptr; | 785 return in_memory_pref_store_.get() != nullptr; |
| 781 } | 786 } |
| 782 | 787 |
| 788 void SdchOwner::RecordDictionaryLifetime(const std::string& server_hash, | |
| 789 size_t size) { | |
| 790 DCHECK(load_times_.count(server_hash) == 1); | |
| 791 base::Time now = clock_->Now(); | |
| 792 base::TimeDelta dict_lifetime = now - load_times_[server_hash]; | |
| 793 base::TimeDelta process_lifetime = now - | |
| 794 base::CurrentProcessInfo::CreationTime(); | |
|
Randy Smith (Not in Mondays)
2015/04/03 16:08:18
I'm not sure this is the right value. Specificall
Elly Fong-Jones
2015/04/03 20:24:23
Done.
| |
| 795 int64 frac = (size * dict_lifetime.InMilliseconds()) / | |
| 796 process_lifetime.InMilliseconds(); | |
| 797 UMA_HISTOGRAM_COUNTS("Sdch3.TimeWeightedMemoryUse", frac); | |
| 798 } | |
| 799 | |
| 783 } // namespace net | 800 } // namespace net |
| OLD | NEW |