Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: net/disk_cache/simple/simple_index.cc

Issue 2922973003: RFC: use some in-memory state in SimpleCache to quickly cache-miss some CantConditionalize cases
Patch Set: - Implement support for oracle bytes in MockHttpCache, so the code actually gets exercised in tests… Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/disk_cache/simple/simple_index.h" 5 #include "net/disk_cache/simple/simple_index.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 namespace disk_cache { 54 namespace disk_cache {
55 55
56 EntryMetadata::EntryMetadata() 56 EntryMetadata::EntryMetadata()
57 : last_used_time_seconds_since_epoch_(0), 57 : last_used_time_seconds_since_epoch_(0),
58 entry_size_(0) { 58 entry_size_(0) {
59 } 59 }
60 60
61 EntryMetadata::EntryMetadata(base::Time last_used_time, 61 EntryMetadata::EntryMetadata(base::Time last_used_time,
62 base::StrictNumeric<uint32_t> entry_size) 62 base::StrictNumeric<uint32_t> entry_size)
63 : last_used_time_seconds_since_epoch_(0), entry_size_(entry_size) { 63 : last_used_time_seconds_since_epoch_(0), entry_size_(0) {
64 SetEntrySize(entry_size); // to round/pack properly.
64 SetLastUsedTime(last_used_time); 65 SetLastUsedTime(last_used_time);
65 } 66 }
66 67
67 base::Time EntryMetadata::GetLastUsedTime() const { 68 base::Time EntryMetadata::GetLastUsedTime() const {
68 // Preserve nullity. 69 // Preserve nullity.
69 if (last_used_time_seconds_since_epoch_ == 0) 70 if (last_used_time_seconds_since_epoch_ == 0)
70 return base::Time(); 71 return base::Time();
71 72
72 return base::Time::UnixEpoch() + 73 return base::Time::UnixEpoch() +
73 base::TimeDelta::FromSeconds(last_used_time_seconds_since_epoch_); 74 base::TimeDelta::FromSeconds(last_used_time_seconds_since_epoch_);
74 } 75 }
75 76
76 void EntryMetadata::SetLastUsedTime(const base::Time& last_used_time) { 77 void EntryMetadata::SetLastUsedTime(const base::Time& last_used_time) {
77 // Preserve nullity. 78 // Preserve nullity.
78 if (last_used_time.is_null()) { 79 if (last_used_time.is_null()) {
79 last_used_time_seconds_since_epoch_ = 0; 80 last_used_time_seconds_since_epoch_ = 0;
80 return; 81 return;
81 } 82 }
82 83
83 last_used_time_seconds_since_epoch_ = base::saturated_cast<uint32_t>( 84 last_used_time_seconds_since_epoch_ = base::saturated_cast<uint32_t>(
84 (last_used_time - base::Time::UnixEpoch()).InSeconds()); 85 (last_used_time - base::Time::UnixEpoch()).InSeconds());
85 // Avoid accidental nullity. 86 // Avoid accidental nullity.
86 if (last_used_time_seconds_since_epoch_ == 0) 87 if (last_used_time_seconds_since_epoch_ == 0)
87 last_used_time_seconds_since_epoch_ = 1; 88 last_used_time_seconds_since_epoch_ = 1;
88 } 89 }
89 90
90 uint32_t EntryMetadata::GetEntrySize() const { 91 uint32_t EntryMetadata::GetEntrySize() const {
91 return entry_size_; 92 return entry_size_ & 0xFFFFFF00;
jkarlin 2017/06/08 14:44:06 I'd rather add a byte (or a uint32_t even) to the
93 }
94
95 uint8_t EntryMetadata::GetOracleByte() const {
96 return entry_size_ & 0xFF;
92 } 97 }
93 98
94 void EntryMetadata::SetEntrySize(base::StrictNumeric<uint32_t> entry_size) { 99 void EntryMetadata::SetEntrySize(base::StrictNumeric<uint32_t> entry_size) {
95 entry_size_ = entry_size; 100 uint8_t save_oracle_byte = GetOracleByte();
101 // ### what happens if we overflow here?
102 entry_size_ = ((static_cast<uint32_t>(entry_size) + 255) & 0xFFFFFF00) |
103 save_oracle_byte;
104 }
105
106 void EntryMetadata::SetOracleByte(uint8_t oracle_byte) {
107 uint32_t save_size = GetEntrySize();
108 entry_size_ = (save_size | oracle_byte);
96 } 109 }
97 110
98 void EntryMetadata::Serialize(base::Pickle* pickle) const { 111 void EntryMetadata::Serialize(base::Pickle* pickle) const {
99 DCHECK(pickle); 112 DCHECK(pickle);
100 int64_t internal_last_used_time = GetLastUsedTime().ToInternalValue(); 113 int64_t internal_last_used_time = GetLastUsedTime().ToInternalValue();
101 // If you modify the size of the size of the pickle, be sure to update 114 // If you modify the size of the size of the pickle, be sure to update
102 // kOnDiskSizeBytes. 115 // kOnDiskSizeBytes.
103 pickle->WriteInt64(internal_last_used_time); 116 pickle->WriteInt64(internal_last_used_time);
104 pickle->WriteUInt64(entry_size_); 117 pickle->WriteUInt64(entry_size_);
105 } 118 }
106 119
107 bool EntryMetadata::Deserialize(base::PickleIterator* it) { 120 bool EntryMetadata::Deserialize(base::PickleIterator* it,
121 bool has_oracle_byte) {
108 DCHECK(it); 122 DCHECK(it);
109 int64_t tmp_last_used_time; 123 int64_t tmp_last_used_time;
110 uint64_t tmp_entry_size; 124 uint64_t tmp_entry_size;
111 if (!it->ReadInt64(&tmp_last_used_time) || !it->ReadUInt64(&tmp_entry_size) || 125 if (!it->ReadInt64(&tmp_last_used_time) || !it->ReadUInt64(&tmp_entry_size) ||
112 tmp_entry_size > std::numeric_limits<decltype(entry_size_)>::max()) 126 tmp_entry_size > std::numeric_limits<decltype(entry_size_)>::max())
113 return false; 127 return false;
114 SetLastUsedTime(base::Time::FromInternalValue(tmp_last_used_time)); 128 SetLastUsedTime(base::Time::FromInternalValue(tmp_last_used_time));
115 entry_size_ = static_cast<uint32_t>(tmp_entry_size); 129 if (has_oracle_byte) {
130 entry_size_ = static_cast<uint32_t>(tmp_entry_size);
131 } else {
132 SetEntrySize(static_cast<uint32_t>(tmp_entry_size));
133 SetOracleByte(0);
134 }
116 return true; 135 return true;
117 } 136 }
118 137
119 SimpleIndex::SimpleIndex( 138 SimpleIndex::SimpleIndex(
120 const scoped_refptr<base::SingleThreadTaskRunner>& io_thread, 139 const scoped_refptr<base::SingleThreadTaskRunner>& io_thread,
121 SimpleIndexDelegate* delegate, 140 SimpleIndexDelegate* delegate,
122 net::CacheType cache_type, 141 net::CacheType cache_type,
123 std::unique_ptr<SimpleIndexFile> index_file) 142 std::unique_ptr<SimpleIndexFile> index_file)
124 : delegate_(delegate), 143 : delegate_(delegate),
125 cache_type_(cache_type), 144 cache_type_(cache_type),
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 removed_entries_.insert(entry_hash); 293 removed_entries_.insert(entry_hash);
275 PostponeWritingToDisk(); 294 PostponeWritingToDisk();
276 } 295 }
277 296
278 bool SimpleIndex::Has(uint64_t hash) const { 297 bool SimpleIndex::Has(uint64_t hash) const {
279 DCHECK(io_thread_checker_.CalledOnValidThread()); 298 DCHECK(io_thread_checker_.CalledOnValidThread());
280 // If not initialized, always return true, forcing it to go to the disk. 299 // If not initialized, always return true, forcing it to go to the disk.
281 return !initialized_ || entries_set_.count(hash) > 0; 300 return !initialized_ || entries_set_.count(hash) > 0;
282 } 301 }
283 302
303 bool SimpleIndex::HasWithOracleByte(uint64_t entry_hash, uint8_t* oracle_byte) {
304 EntrySet::iterator it = entries_set_.find(entry_hash);
305 if (it == entries_set_.end())
306 // If not initialized, always return true, forcing it to go to the disk.
307 return !initialized_;
308 *oracle_byte = it->second.GetOracleByte();
309 return true;
310 }
311
284 bool SimpleIndex::UseIfExists(uint64_t entry_hash) { 312 bool SimpleIndex::UseIfExists(uint64_t entry_hash) {
285 DCHECK(io_thread_checker_.CalledOnValidThread()); 313 DCHECK(io_thread_checker_.CalledOnValidThread());
286 // Always update the last used time, even if it is during initialization. 314 // Always update the last used time, even if it is during initialization.
287 // It will be merged later. 315 // It will be merged later.
288 EntrySet::iterator it = entries_set_.find(entry_hash); 316 EntrySet::iterator it = entries_set_.find(entry_hash);
289 if (it == entries_set_.end()) 317 if (it == entries_set_.end())
290 // If not initialized, always return true, forcing it to go to the disk. 318 // If not initialized, always return true, forcing it to go to the disk.
291 return !initialized_; 319 return !initialized_;
292 it->second.SetLastUsedTime(base::Time::Now()); 320 it->second.SetLastUsedTime(base::Time::Now());
293 PostponeWritingToDisk(); 321 PostponeWritingToDisk();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 EntrySet::iterator it = entries_set_.find(entry_hash); 384 EntrySet::iterator it = entries_set_.find(entry_hash);
357 if (it == entries_set_.end()) 385 if (it == entries_set_.end())
358 return false; 386 return false;
359 387
360 UpdateEntryIteratorSize(&it, entry_size); 388 UpdateEntryIteratorSize(&it, entry_size);
361 PostponeWritingToDisk(); 389 PostponeWritingToDisk();
362 StartEvictionIfNeeded(); 390 StartEvictionIfNeeded();
363 return true; 391 return true;
364 } 392 }
365 393
394 void SimpleIndex::UpdateEntryOracleByte(uint64_t entry_hash,
395 uint8_t oracle_byte) {
396 DCHECK(io_thread_checker_.CalledOnValidThread());
397 EntrySet::iterator it = entries_set_.find(entry_hash);
398 if (it == entries_set_.end())
399 return;
400 it->second.SetOracleByte(oracle_byte);
401 PostponeWritingToDisk();
402 }
403
366 void SimpleIndex::EvictionDone(int result) { 404 void SimpleIndex::EvictionDone(int result) {
367 DCHECK(io_thread_checker_.CalledOnValidThread()); 405 DCHECK(io_thread_checker_.CalledOnValidThread());
368 406
369 // Ignore the result of eviction. We did our best. 407 // Ignore the result of eviction. We did our best.
370 eviction_in_progress_ = false; 408 eviction_in_progress_ = false;
371 SIMPLE_CACHE_UMA(BOOLEAN, "Eviction.Result", cache_type_, result == net::OK); 409 SIMPLE_CACHE_UMA(BOOLEAN, "Eviction.Result", cache_type_, result == net::OK);
372 SIMPLE_CACHE_UMA(TIMES, 410 SIMPLE_CACHE_UMA(TIMES,
373 "Eviction.TimeToDone", cache_type_, 411 "Eviction.TimeToDone", cache_type_,
374 base::TimeTicks::Now() - eviction_start_time_); 412 base::TimeTicks::Now() - eviction_start_time_);
375 SIMPLE_CACHE_UMA( 413 SIMPLE_CACHE_UMA(
(...skipping 27 matching lines...) Expand all
403 FROM_HERE, base::TimeDelta::FromMilliseconds(delay), write_to_disk_cb_); 441 FROM_HERE, base::TimeDelta::FromMilliseconds(delay), write_to_disk_cb_);
404 } 442 }
405 443
406 void SimpleIndex::UpdateEntryIteratorSize( 444 void SimpleIndex::UpdateEntryIteratorSize(
407 EntrySet::iterator* it, 445 EntrySet::iterator* it,
408 base::StrictNumeric<uint32_t> entry_size) { 446 base::StrictNumeric<uint32_t> entry_size) {
409 // Update the total cache size with the new entry size. 447 // Update the total cache size with the new entry size.
410 DCHECK(io_thread_checker_.CalledOnValidThread()); 448 DCHECK(io_thread_checker_.CalledOnValidThread());
411 DCHECK_GE(cache_size_, (*it)->second.GetEntrySize()); 449 DCHECK_GE(cache_size_, (*it)->second.GetEntrySize());
412 cache_size_ -= (*it)->second.GetEntrySize(); 450 cache_size_ -= (*it)->second.GetEntrySize();
413 cache_size_ += static_cast<uint32_t>(entry_size);
414 (*it)->second.SetEntrySize(entry_size); 451 (*it)->second.SetEntrySize(entry_size);
452 // We use GetEntrySize to get consistent rounding.
453 cache_size_ += (*it)->second.GetEntrySize();
415 } 454 }
416 455
417 void SimpleIndex::MergeInitializingSet( 456 void SimpleIndex::MergeInitializingSet(
418 std::unique_ptr<SimpleIndexLoadResult> load_result) { 457 std::unique_ptr<SimpleIndexLoadResult> load_result) {
419 DCHECK(io_thread_checker_.CalledOnValidThread()); 458 DCHECK(io_thread_checker_.CalledOnValidThread());
420 DCHECK(load_result->did_load); 459 DCHECK(load_result->did_load);
421 460
422 EntrySet* index_file_entries = &load_result->entries; 461 EntrySet* index_file_entries = &load_result->entries;
423 462
424 for (std::unordered_set<uint64_t>::const_iterator it = 463 for (std::unordered_set<uint64_t>::const_iterator it =
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 start - last_write_to_disk_); 553 start - last_write_to_disk_);
515 } 554 }
516 } 555 }
517 last_write_to_disk_ = start; 556 last_write_to_disk_ = start;
518 557
519 index_file_->WriteToDisk(reason, entries_set_, cache_size_, start, 558 index_file_->WriteToDisk(reason, entries_set_, cache_size_, start,
520 app_on_background_, base::Closure()); 559 app_on_background_, base::Closure());
521 } 560 }
522 561
523 } // namespace disk_cache 562 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698