OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/entry_impl.h" | 5 #include "net/disk_cache/entry_impl.h" |
6 | 6 |
7 #include "base/histogram.h" | 7 #include "base/histogram.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
11 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
12 #include "net/disk_cache/backend_impl.h" | 12 #include "net/disk_cache/backend_impl.h" |
| 13 #include "net/disk_cache/bitmap.h" |
13 #include "net/disk_cache/cache_util.h" | 14 #include "net/disk_cache/cache_util.h" |
14 #include "net/disk_cache/histogram_macros.h" | 15 #include "net/disk_cache/histogram_macros.h" |
| 16 #include "net/disk_cache/sparse_control.h" |
15 | 17 |
16 using base::Time; | 18 using base::Time; |
17 using base::TimeDelta; | 19 using base::TimeDelta; |
18 | 20 |
19 namespace { | 21 namespace { |
20 | 22 |
21 // Index for the file used to store the key, if any (files_[kKeyFileIndex]). | 23 // Index for the file used to store the key, if any (files_[kKeyFileIndex]). |
22 const int kKeyFileIndex = 3; | 24 const int kKeyFileIndex = 3; |
23 | 25 |
24 // This class implements FileIOCallback to buffer the callback from a file IO | 26 // This class implements FileIOCallback to buffer the callback from a file IO |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 } | 86 } |
85 } | 87 } |
86 | 88 |
87 // When an entry is deleted from the cache, we clean up all the data associated | 89 // When an entry is deleted from the cache, we clean up all the data associated |
88 // with it for two reasons: to simplify the reuse of the block (we know that any | 90 // with it for two reasons: to simplify the reuse of the block (we know that any |
89 // unused block is filled with zeros), and to simplify the handling of write / | 91 // unused block is filled with zeros), and to simplify the handling of write / |
90 // read partial information from an entry (don't have to worry about returning | 92 // read partial information from an entry (don't have to worry about returning |
91 // data related to a previous cache entry because the range was not fully | 93 // data related to a previous cache entry because the range was not fully |
92 // written before). | 94 // written before). |
93 EntryImpl::~EntryImpl() { | 95 EntryImpl::~EntryImpl() { |
| 96 // Save the sparse info to disk before deleting this entry. |
| 97 sparse_.reset(); |
| 98 |
94 if (doomed_) { | 99 if (doomed_) { |
95 DeleteEntryData(true); | 100 DeleteEntryData(true); |
96 } else { | 101 } else { |
97 bool ret = true; | 102 bool ret = true; |
98 for (int index = 0; index < NUM_STREAMS; index++) { | 103 for (int index = 0; index < NUM_STREAMS; index++) { |
99 if (user_buffers_[index].get()) { | 104 if (user_buffers_[index].get()) { |
100 if (!(ret = Flush(index, entry_.Data()->data_size[index], false))) | 105 if (!(ret = Flush(index, entry_.Data()->data_size[index], false))) |
101 LOG(ERROR) << "Failed to save user data"; | 106 LOG(ERROR) << "Failed to save user data"; |
102 } else if (unreported_size_[index]) { | 107 } else if (unreported_size_[index]) { |
103 backend_->ModifyStorageSize( | 108 backend_->ModifyStorageSize( |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 if (io_callback && completed) | 351 if (io_callback && completed) |
347 io_callback->Discard(); | 352 io_callback->Discard(); |
348 | 353 |
349 if (backend_->cache_type() == net::DISK_CACHE) | 354 if (backend_->cache_type() == net::DISK_CACHE) |
350 stats.AddTime(Time::Now() - start); | 355 stats.AddTime(Time::Now() - start); |
351 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; | 356 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; |
352 } | 357 } |
353 | 358 |
354 int EntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 359 int EntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
355 net::CompletionCallback* completion_callback) { | 360 net::CompletionCallback* completion_callback) { |
356 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 361 DCHECK(node_.Data()->dirty); |
| 362 int result = InitSparseData(); |
| 363 if (net::OK != result) |
| 364 return result; |
| 365 |
| 366 return sparse_->StartIO(SparseControl::kReadOperation, offset, buf, buf_len, |
| 367 completion_callback); |
357 } | 368 } |
358 | 369 |
359 int EntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 370 int EntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
360 net::CompletionCallback* completion_callback) { | 371 net::CompletionCallback* completion_callback) { |
361 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 372 DCHECK(node_.Data()->dirty); |
| 373 int result = InitSparseData(); |
| 374 if (net::OK != result) |
| 375 return result; |
| 376 |
| 377 return sparse_->StartIO(SparseControl::kWriteOperation, offset, buf, buf_len, |
| 378 completion_callback); |
362 } | 379 } |
363 | 380 |
364 int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { | 381 int EntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { |
365 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 382 int result = InitSparseData(); |
| 383 if (net::OK != result) |
| 384 return result; |
| 385 |
| 386 return sparse_->GetAvailableRange(offset, len, start); |
366 } | 387 } |
367 | 388 |
368 uint32 EntryImpl::GetHash() { | 389 uint32 EntryImpl::GetHash() { |
369 return entry_.Data()->hash; | 390 return entry_.Data()->hash; |
370 } | 391 } |
371 | 392 |
372 bool EntryImpl::CreateEntry(Addr node_address, const std::string& key, | 393 bool EntryImpl::CreateEntry(Addr node_address, const std::string& key, |
373 uint32 hash) { | 394 uint32 hash) { |
374 Trace("Create entry In"); | 395 Trace("Create entry In"); |
375 EntryStore* entry_store = entry_.Data(); | 396 EntryStore* entry_store = entry_.Data(); |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 return false; | 827 return false; |
807 user_buffers_[index].reset(NULL); | 828 user_buffers_[index].reset(NULL); |
808 } | 829 } |
809 | 830 |
810 // The buffer is deleted from the PostWrite operation. | 831 // The buffer is deleted from the PostWrite operation. |
811 user_buffers_[index].release(); | 832 user_buffers_[index].release(); |
812 | 833 |
813 return true; | 834 return true; |
814 } | 835 } |
815 | 836 |
| 837 int EntryImpl::InitSparseData() { |
| 838 if (sparse_.get()) |
| 839 return net::OK; |
| 840 |
| 841 sparse_.reset(new SparseControl(this)); |
| 842 int result = sparse_->Init(); |
| 843 if (net::OK != result) |
| 844 sparse_.reset(); |
| 845 return result; |
| 846 } |
| 847 |
816 void EntryImpl::Log(const char* msg) { | 848 void EntryImpl::Log(const char* msg) { |
817 void* pointer = NULL; | 849 void* pointer = NULL; |
818 int dirty = 0; | 850 int dirty = 0; |
819 if (node_.HasData()) { | 851 if (node_.HasData()) { |
820 pointer = node_.Data()->pointer; | 852 pointer = node_.Data()->pointer; |
821 dirty = node_.Data()->dirty; | 853 dirty = node_.Data()->dirty; |
822 } | 854 } |
823 | 855 |
824 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), | 856 Trace("%s 0x%p 0x%x 0x%x", msg, reinterpret_cast<void*>(this), |
825 entry_.address().value(), node_.address().value()); | 857 entry_.address().value(), node_.address().value()); |
826 | 858 |
827 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 859 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
828 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 860 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
829 | 861 |
830 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); | 862 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); |
831 } | 863 } |
832 | 864 |
833 } // namespace disk_cache | 865 } // namespace disk_cache |
OLD | NEW |