OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |