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 |