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 |