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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 : cache_size_(0), | 158 : cache_size_(0), |
159 max_size_(0), | 159 max_size_(0), |
160 high_watermark_(0), | 160 high_watermark_(0), |
161 low_watermark_(0), | 161 low_watermark_(0), |
162 eviction_in_progress_(false), | 162 eviction_in_progress_(false), |
163 initialized_(false), | 163 initialized_(false), |
164 index_filename_(path.AppendASCII("the-real-index")), | 164 index_filename_(path.AppendASCII("the-real-index")), |
165 cache_thread_(cache_thread), | 165 cache_thread_(cache_thread), |
166 io_thread_(io_thread), | 166 io_thread_(io_thread), |
167 app_on_background_(false) { | 167 app_on_background_(false) { |
168 // Creating the callback once so it is reused every time | |
169 // write_to_disk_timer_.Start() is called. | |
170 write_to_disk_cb_ = base::Bind(&SimpleIndex::WriteToDisk, AsWeakPtr()); | |
168 } | 171 } |
169 | 172 |
170 SimpleIndex::~SimpleIndex() { | 173 SimpleIndex::~SimpleIndex() { |
171 DCHECK(io_thread_checker_.CalledOnValidThread()); | 174 DCHECK(io_thread_checker_.CalledOnValidThread()); |
172 | 175 |
173 // Fail all callbacks waiting for the index to come up. | 176 // Fail all callbacks waiting for the index to come up. |
174 for (CallbackList::iterator it = to_run_when_initialized_.begin(), | 177 for (CallbackList::iterator it = to_run_when_initialized_.begin(), |
175 end = to_run_when_initialized_.end(); it != end; ++it) { | 178 end = to_run_when_initialized_.end(); it != end; ++it) { |
176 it->Run(net::ERR_ABORTED); | 179 it->Run(net::ERR_ABORTED); |
177 } | 180 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 const uint64 hash_key = simple_util::GetEntryHashKey(key); | 256 const uint64 hash_key = simple_util::GetEntryHashKey(key); |
254 InsertInEntrySet(EntryMetadata(hash_key, base::Time::Now(), 0), | 257 InsertInEntrySet(EntryMetadata(hash_key, base::Time::Now(), 0), |
255 &entries_set_); | 258 &entries_set_); |
256 if (!initialized_) | 259 if (!initialized_) |
257 removed_entries_.erase(hash_key); | 260 removed_entries_.erase(hash_key); |
258 PostponeWritingToDisk(); | 261 PostponeWritingToDisk(); |
259 } | 262 } |
260 | 263 |
261 void SimpleIndex::Remove(const std::string& key) { | 264 void SimpleIndex::Remove(const std::string& key) { |
262 DCHECK(io_thread_checker_.CalledOnValidThread()); | 265 DCHECK(io_thread_checker_.CalledOnValidThread()); |
263 UpdateEntrySize(key, 0); | |
264 const uint64 hash_key = simple_util::GetEntryHashKey(key); | 266 const uint64 hash_key = simple_util::GetEntryHashKey(key); |
265 entries_set_.erase(hash_key); | 267 EntrySet::iterator it = entries_set_.find(hash_key); |
268 if (it != entries_set_.end()) { | |
269 UpdateEntryIteratorSize(&it, 0); | |
pasko
2013/05/17 10:31:33
I am guessing the main purpose of this is to remov
digit1
2013/05/17 14:36:18
Yes.
pasko
2013/05/17 16:57:19
Thanks! After this overview I am a little scared:
| |
270 entries_set_.erase(it); | |
271 } | |
266 | 272 |
267 if (!initialized_) | 273 if (!initialized_) |
268 removed_entries_.insert(hash_key); | 274 removed_entries_.insert(hash_key); |
269 PostponeWritingToDisk(); | 275 PostponeWritingToDisk(); |
270 } | 276 } |
271 | 277 |
272 bool SimpleIndex::Has(const std::string& key) const { | 278 bool SimpleIndex::Has(const std::string& key) const { |
273 DCHECK(io_thread_checker_.CalledOnValidThread()); | 279 DCHECK(io_thread_checker_.CalledOnValidThread()); |
274 // If not initialized, always return true, forcing it to go to the disk. | 280 // If not initialized, always return true, forcing it to go to the disk. |
275 return !initialized_ || | 281 return !initialized_ || |
276 entries_set_.count(simple_util::GetEntryHashKey(key)) != 0; | 282 entries_set_.find(simple_util::GetEntryHashKey(key)) != |
283 entries_set_.end(); | |
277 } | 284 } |
278 | 285 |
279 bool SimpleIndex::UseIfExists(const std::string& key) { | 286 bool SimpleIndex::UseIfExists(const std::string& key) { |
280 DCHECK(io_thread_checker_.CalledOnValidThread()); | 287 DCHECK(io_thread_checker_.CalledOnValidThread()); |
281 // Always update the last used time, even if it is during initialization. | 288 // Always update the last used time, even if it is during initialization. |
282 // It will be merged later. | 289 // It will be merged later. |
283 EntrySet::iterator it = entries_set_.find(simple_util::GetEntryHashKey(key)); | 290 EntrySet::iterator it = entries_set_.find(simple_util::GetEntryHashKey(key)); |
284 if (it == entries_set_.end()) | 291 if (it == entries_set_.end()) |
285 // If not initialized, always return true, forcing it to go to the disk. | 292 // If not initialized, always return true, forcing it to go to the disk. |
286 return !initialized_; | 293 return !initialized_; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 base::Passed(&result)); | 344 base::Passed(&result)); |
338 base::WorkerPool::PostTaskAndReply(FROM_HERE, task, reply, true); | 345 base::WorkerPool::PostTaskAndReply(FROM_HERE, task, reply, true); |
339 } | 346 } |
340 | 347 |
341 bool SimpleIndex::UpdateEntrySize(const std::string& key, uint64 entry_size) { | 348 bool SimpleIndex::UpdateEntrySize(const std::string& key, uint64 entry_size) { |
342 DCHECK(io_thread_checker_.CalledOnValidThread()); | 349 DCHECK(io_thread_checker_.CalledOnValidThread()); |
343 EntrySet::iterator it = entries_set_.find(simple_util::GetEntryHashKey(key)); | 350 EntrySet::iterator it = entries_set_.find(simple_util::GetEntryHashKey(key)); |
344 if (it == entries_set_.end()) | 351 if (it == entries_set_.end()) |
345 return false; | 352 return false; |
346 | 353 |
347 // Update the total cache size with the new entry size. | 354 UpdateEntryIteratorSize(&it, entry_size); |
348 DCHECK(cache_size_ - it->second.GetEntrySize() <= cache_size_); | |
349 cache_size_ -= it->second.GetEntrySize(); | |
350 cache_size_ += entry_size; | |
351 it->second.SetEntrySize(entry_size); | |
352 PostponeWritingToDisk(); | 355 PostponeWritingToDisk(); |
353 StartEvictionIfNeeded(); | 356 StartEvictionIfNeeded(); |
354 return true; | 357 return true; |
355 } | 358 } |
356 | 359 |
357 void SimpleIndex::EvictionDone(scoped_ptr<int> result) { | 360 void SimpleIndex::EvictionDone(scoped_ptr<int> result) { |
358 DCHECK(io_thread_checker_.CalledOnValidThread()); | 361 DCHECK(io_thread_checker_.CalledOnValidThread()); |
359 DCHECK(result); | 362 DCHECK(result); |
360 | 363 |
361 // Ignore the result of eviction. We did our best. | 364 // Ignore the result of eviction. We did our best. |
(...skipping 13 matching lines...) Expand all Loading... | |
375 std::make_pair(entry_metadata.GetHashKey(), entry_metadata)); | 378 std::make_pair(entry_metadata.GetHashKey(), entry_metadata)); |
376 } | 379 } |
377 | 380 |
378 void SimpleIndex::PostponeWritingToDisk() { | 381 void SimpleIndex::PostponeWritingToDisk() { |
379 if (!initialized_) | 382 if (!initialized_) |
380 return; | 383 return; |
381 const int delay = app_on_background_ ? kWriteToDiskOnBackgroundDelayMSecs | 384 const int delay = app_on_background_ ? kWriteToDiskOnBackgroundDelayMSecs |
382 : kWriteToDiskDelayMSecs; | 385 : kWriteToDiskDelayMSecs; |
383 // If the timer is already active, Start() will just Reset it, postponing it. | 386 // If the timer is already active, Start() will just Reset it, postponing it. |
384 write_to_disk_timer_.Start( | 387 write_to_disk_timer_.Start( |
385 FROM_HERE, | 388 FROM_HERE, base::TimeDelta::FromMilliseconds(delay), write_to_disk_cb_); |
pasko
2013/05/17 10:31:33
nice
| |
386 base::TimeDelta::FromMilliseconds(delay), | 389 } |
387 base::Bind(&SimpleIndex::WriteToDisk, AsWeakPtr())); | 390 |
391 void SimpleIndex::UpdateEntryIteratorSize(EntrySet::iterator* it, | |
392 uint64 entry_size) { | |
393 // Update the total cache size with the new entry size. | |
394 DCHECK(cache_size_ - (*it)->second.GetEntrySize() <= cache_size_); | |
395 cache_size_ -= (*it)->second.GetEntrySize(); | |
396 cache_size_ += entry_size; | |
397 (*it)->second.SetEntrySize(entry_size); | |
388 } | 398 } |
389 | 399 |
390 // static | 400 // static |
391 bool SimpleIndex::IsIndexFileStale(const base::FilePath& index_filename) { | 401 bool SimpleIndex::IsIndexFileStale(const base::FilePath& index_filename) { |
392 base::Time index_mtime; | 402 base::Time index_mtime; |
393 base::Time dir_mtime; | 403 base::Time dir_mtime; |
394 if (!GetMTime(index_filename.DirName(), &dir_mtime)) | 404 if (!GetMTime(index_filename.DirName(), &dir_mtime)) |
395 return true; | 405 return true; |
396 if (!GetMTime(index_filename, &index_mtime)) | 406 if (!GetMTime(index_filename, &index_mtime)) |
397 return true; | 407 return true; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 using file_util::FileEnumerator; | 480 using file_util::FileEnumerator; |
471 LOG(INFO) << "Simple Cache Index is being restored from disk."; | 481 LOG(INFO) << "Simple Cache Index is being restored from disk."; |
472 | 482 |
473 file_util::Delete(index_filename, /* recursive = */ false); | 483 file_util::Delete(index_filename, /* recursive = */ false); |
474 scoped_ptr<EntrySet> index_file_entries(new EntrySet()); | 484 scoped_ptr<EntrySet> index_file_entries(new EntrySet()); |
475 | 485 |
476 // TODO(felipeg,gavinp): Fix this once we have a one-file per entry format. | 486 // TODO(felipeg,gavinp): Fix this once we have a one-file per entry format. |
477 COMPILE_ASSERT(kSimpleEntryFileCount == 3, | 487 COMPILE_ASSERT(kSimpleEntryFileCount == 3, |
478 file_pattern_must_match_file_count); | 488 file_pattern_must_match_file_count); |
479 | 489 |
480 const int kFileSuffixLenght = std::string("_0").size(); | 490 const int kFileSuffixLength = strlen("_0"); |
481 const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*_[0-2]"); | 491 const base::FilePath::StringType file_pattern = FILE_PATH_LITERAL("*_[0-2]"); |
482 FileEnumerator enumerator(index_filename.DirName(), | 492 FileEnumerator enumerator(index_filename.DirName(), |
483 false /* recursive */, | 493 false /* recursive */, |
484 FileEnumerator::FILES, | 494 FileEnumerator::FILES, |
485 file_pattern); | 495 file_pattern); |
486 for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); | 496 for (base::FilePath file_path = enumerator.Next(); !file_path.empty(); |
487 file_path = enumerator.Next()) { | 497 file_path = enumerator.Next()) { |
488 const base::FilePath::StringType base_name = file_path.BaseName().value(); | 498 const base::FilePath::StringType base_name = file_path.BaseName().value(); |
489 // Converting to std::string is OK since we never use UTF8 wide chars in our | 499 // Converting to std::string is OK since we never use UTF8 wide chars in our |
490 // file names. | 500 // file names. |
491 const std::string hash_name(base_name.begin(), base_name.end()); | 501 const std::string hash_key_string(base_name.begin(), |
492 const std::string hash_key_string = | 502 base_name.end() - kFileSuffixLength); |
pasko
2013/05/17 10:31:33
nice
| |
493 hash_name.substr(0, hash_name.size() - kFileSuffixLenght); | |
494 uint64 hash_key = 0; | 503 uint64 hash_key = 0; |
495 if (!simple_util::GetEntryHashKeyFromHexString( | 504 if (!simple_util::GetEntryHashKeyFromHexString( |
496 hash_key_string, &hash_key)) { | 505 hash_key_string, &hash_key)) { |
497 LOG(WARNING) << "Invalid Entry Hash Key filename while restoring " | 506 LOG(WARNING) << "Invalid Entry Hash Key filename while restoring " |
498 << "Simple Index from disk: " << hash_name; | 507 << "Simple Index from disk: " << base_name; |
499 // TODO(felipeg): Should we delete the invalid file here ? | 508 // TODO(felipeg): Should we delete the invalid file here ? |
500 continue; | 509 continue; |
501 } | 510 } |
502 | 511 |
503 FileEnumerator::FindInfo find_info = {}; | 512 FileEnumerator::FindInfo find_info = {}; |
504 enumerator.GetFindInfo(&find_info); | 513 enumerator.GetFindInfo(&find_info); |
505 base::Time last_used_time; | 514 base::Time last_used_time; |
506 #if defined(OS_POSIX) | 515 #if defined(OS_POSIX) |
507 // For POSIX systems, a last access time is available. However, it's not | 516 // For POSIX systems, a last access time is available. However, it's not |
508 // guaranteed to be more accurate than mtime. It is no worse though. | 517 // guaranteed to be more accurate than mtime. It is no worse though. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 entries_set_); | 635 entries_set_); |
627 cache_thread_->PostTask(FROM_HERE, base::Bind( | 636 cache_thread_->PostTask(FROM_HERE, base::Bind( |
628 &SimpleIndex::WriteToDiskInternal, | 637 &SimpleIndex::WriteToDiskInternal, |
629 index_filename_, | 638 index_filename_, |
630 base::Passed(&pickle), | 639 base::Passed(&pickle), |
631 start, | 640 start, |
632 app_on_background_)); | 641 app_on_background_)); |
633 } | 642 } |
634 | 643 |
635 } // namespace disk_cache | 644 } // namespace disk_cache |
OLD | NEW |