OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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" | |
11 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
12 #include "net/disk_cache/backend_impl.h" | 11 #include "net/disk_cache/backend_impl.h" |
13 #include "net/disk_cache/cache_util.h" | 12 #include "net/disk_cache/cache_util.h" |
14 | 13 |
15 using base::Time; | 14 using base::Time; |
16 using base::TimeDelta; | 15 using base::TimeDelta; |
17 | 16 |
18 namespace { | 17 namespace { |
19 | 18 |
20 // Index for the file used to store the key, if any (files_[kKeyFileIndex]). | 19 // Index for the file used to store the key, if any (files_[kKeyFileIndex]). |
21 const int kKeyFileIndex = 3; | 20 const int kKeyFileIndex = 3; |
22 | 21 |
23 // This class implements FileIOCallback to buffer the callback from a file IO | 22 // This class implements FileIOCallback to buffer the callback from a file IO |
24 // operation from the actual net class. | 23 // operation from the actual net class. |
25 class SyncCallback: public disk_cache::FileIOCallback { | 24 class SyncCallback: public disk_cache::FileIOCallback { |
26 public: | 25 public: |
27 SyncCallback(disk_cache::EntryImpl* entry, net::IOBuffer* buffer, | 26 SyncCallback(disk_cache::EntryImpl* entry, |
28 net::CompletionCallback* callback ) | 27 net::CompletionCallback* callback ) |
29 : entry_(entry), callback_(callback), buf_(buffer) { | 28 : entry_(entry), callback_(callback) { |
30 entry->AddRef(); | 29 entry->AddRef(); |
31 entry->IncrementIoCount(); | 30 entry->IncrementIoCount(); |
32 } | 31 } |
33 ~SyncCallback() {} | 32 ~SyncCallback() {} |
34 | 33 |
35 virtual void OnFileIOComplete(int bytes_copied); | 34 virtual void OnFileIOComplete(int bytes_copied); |
36 void Discard(); | 35 void Discard(); |
37 private: | 36 private: |
38 disk_cache::EntryImpl* entry_; | 37 disk_cache::EntryImpl* entry_; |
39 net::CompletionCallback* callback_; | 38 net::CompletionCallback* callback_; |
40 scoped_refptr<net::IOBuffer> buf_; | |
41 | 39 |
42 DISALLOW_EVIL_CONSTRUCTORS(SyncCallback); | 40 DISALLOW_EVIL_CONSTRUCTORS(SyncCallback); |
43 }; | 41 }; |
44 | 42 |
45 void SyncCallback::OnFileIOComplete(int bytes_copied) { | 43 void SyncCallback::OnFileIOComplete(int bytes_copied) { |
46 entry_->DecrementIoCount(); | 44 entry_->DecrementIoCount(); |
47 entry_->Release(); | 45 entry_->Release(); |
48 if (callback_) | 46 if (callback_) |
49 callback_->Run(bytes_copied); | 47 callback_->Run(bytes_copied); |
50 delete this; | 48 delete this; |
51 } | 49 } |
52 | 50 |
53 void SyncCallback::Discard() { | 51 void SyncCallback::Discard() { |
54 callback_ = NULL; | 52 callback_ = NULL; |
55 buf_ = NULL; | |
56 OnFileIOComplete(0); | 53 OnFileIOComplete(0); |
57 } | 54 } |
58 | 55 |
59 // Clears buffer before offset and after valid_len, knowing that the size of | 56 // Clears buffer before offset and after valid_len, knowing that the size of |
60 // buffer is kMaxBlockSize. | 57 // buffer is kMaxBlockSize. |
61 void ClearInvalidData(char* buffer, int offset, int valid_len) { | 58 void ClearInvalidData(char* buffer, int offset, int valid_len) { |
62 DCHECK(offset >= 0); | 59 DCHECK(offset >= 0); |
63 DCHECK(valid_len >= 0); | 60 DCHECK(valid_len >= 0); |
64 DCHECK(disk_cache::kMaxBlockSize >= offset + valid_len); | 61 DCHECK(disk_cache::kMaxBlockSize >= offset + valid_len); |
65 if (offset) | 62 if (offset) |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } | 187 } |
191 | 188 |
192 int32 EntryImpl::GetDataSize(int index) const { | 189 int32 EntryImpl::GetDataSize(int index) const { |
193 if (index < 0 || index >= NUM_STREAMS) | 190 if (index < 0 || index >= NUM_STREAMS) |
194 return 0; | 191 return 0; |
195 | 192 |
196 CacheEntryBlock* entry = const_cast<CacheEntryBlock*>(&entry_); | 193 CacheEntryBlock* entry = const_cast<CacheEntryBlock*>(&entry_); |
197 return entry->Data()->data_size[index]; | 194 return entry->Data()->data_size[index]; |
198 } | 195 } |
199 | 196 |
200 int EntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, int buf_len, | 197 int EntryImpl::ReadData(int index, int offset, char* buf, int buf_len, |
201 net::CompletionCallback* completion_callback) { | 198 net::CompletionCallback* completion_callback) { |
202 DCHECK(node_.Data()->dirty); | 199 DCHECK(node_.Data()->dirty); |
203 if (index < 0 || index >= NUM_STREAMS) | 200 if (index < 0 || index >= NUM_STREAMS) |
204 return net::ERR_INVALID_ARGUMENT; | 201 return net::ERR_INVALID_ARGUMENT; |
205 | 202 |
206 int entry_size = entry_.Data()->data_size[index]; | 203 int entry_size = entry_.Data()->data_size[index]; |
207 if (offset >= entry_size || offset < 0 || !buf_len) | 204 if (offset >= entry_size || offset < 0 || !buf_len) |
208 return 0; | 205 return 0; |
209 | 206 |
210 if (buf_len < 0) | 207 if (buf_len < 0) |
211 return net::ERR_INVALID_ARGUMENT; | 208 return net::ERR_INVALID_ARGUMENT; |
212 | 209 |
213 Time start = Time::Now(); | 210 Time start = Time::Now(); |
214 static Histogram stats(L"DiskCache.ReadTime", TimeDelta::FromMilliseconds(1), | 211 static Histogram stats(L"DiskCache.ReadTime", TimeDelta::FromMilliseconds(1), |
215 TimeDelta::FromSeconds(10), 50); | 212 TimeDelta::FromSeconds(10), 50); |
216 stats.SetFlags(kUmaTargetedHistogramFlag); | 213 stats.SetFlags(kUmaTargetedHistogramFlag); |
217 | 214 |
218 if (offset + buf_len > entry_size) | 215 if (offset + buf_len > entry_size) |
219 buf_len = entry_size - offset; | 216 buf_len = entry_size - offset; |
220 | 217 |
221 UpdateRank(false); | 218 UpdateRank(false); |
222 | 219 |
223 backend_->OnEvent(Stats::READ_DATA); | 220 backend_->OnEvent(Stats::READ_DATA); |
224 | 221 |
225 if (user_buffers_[index].get()) { | 222 if (user_buffers_[index].get()) { |
226 // Complete the operation locally. | 223 // Complete the operation locally. |
227 DCHECK(kMaxBlockSize >= offset + buf_len); | 224 DCHECK(kMaxBlockSize >= offset + buf_len); |
228 memcpy(buf->data() , user_buffers_[index].get() + offset, buf_len); | 225 memcpy(buf , user_buffers_[index].get() + offset, buf_len); |
229 stats.AddTime(Time::Now() - start); | 226 stats.AddTime(Time::Now() - start); |
230 return buf_len; | 227 return buf_len; |
231 } | 228 } |
232 | 229 |
233 Addr address(entry_.Data()->data_addr[index]); | 230 Addr address(entry_.Data()->data_addr[index]); |
234 DCHECK(address.is_initialized()); | 231 DCHECK(address.is_initialized()); |
235 if (!address.is_initialized()) | 232 if (!address.is_initialized()) |
236 return net::ERR_FAILED; | 233 return net::ERR_FAILED; |
237 | 234 |
238 File* file = GetBackingFile(address, index); | 235 File* file = GetBackingFile(address, index); |
239 if (!file) | 236 if (!file) |
240 return net::ERR_FAILED; | 237 return net::ERR_FAILED; |
241 | 238 |
242 size_t file_offset = offset; | 239 size_t file_offset = offset; |
243 if (address.is_block_file()) | 240 if (address.is_block_file()) |
244 file_offset += address.start_block() * address.BlockSize() + | 241 file_offset += address.start_block() * address.BlockSize() + |
245 kBlockHeaderSize; | 242 kBlockHeaderSize; |
246 | 243 |
247 SyncCallback* io_callback = NULL; | 244 SyncCallback* io_callback = NULL; |
248 if (completion_callback) | 245 if (completion_callback) |
249 io_callback = new SyncCallback(this, buf, completion_callback); | 246 io_callback = new SyncCallback(this, completion_callback); |
250 | 247 |
251 bool completed; | 248 bool completed; |
252 if (!file->Read(buf->data(), buf_len, file_offset, io_callback, &completed)) { | 249 if (!file->Read(buf, buf_len, file_offset, io_callback, &completed)) { |
253 if (io_callback) | 250 if (io_callback) |
254 io_callback->Discard(); | 251 io_callback->Discard(); |
255 return net::ERR_FAILED; | 252 return net::ERR_FAILED; |
256 } | 253 } |
257 | 254 |
258 if (io_callback && completed) | 255 if (io_callback && completed) |
259 io_callback->Discard(); | 256 io_callback->Discard(); |
260 | 257 |
261 stats.AddTime(Time::Now() - start); | 258 stats.AddTime(Time::Now() - start); |
262 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; | 259 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; |
263 } | 260 } |
264 | 261 |
265 int EntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, int buf_len, | 262 int EntryImpl::WriteData(int index, int offset, const char* buf, int buf_len, |
266 net::CompletionCallback* completion_callback, | 263 net::CompletionCallback* completion_callback, |
267 bool truncate) { | 264 bool truncate) { |
268 DCHECK(node_.Data()->dirty); | 265 DCHECK(node_.Data()->dirty); |
269 if (index < 0 || index >= NUM_STREAMS) | 266 if (index < 0 || index >= NUM_STREAMS) |
270 return net::ERR_INVALID_ARGUMENT; | 267 return net::ERR_INVALID_ARGUMENT; |
271 | 268 |
272 if (offset < 0 || buf_len < 0) | 269 if (offset < 0 || buf_len < 0) |
273 return net::ERR_INVALID_ARGUMENT; | 270 return net::ERR_INVALID_ARGUMENT; |
274 | 271 |
275 int max_file_size = backend_->MaxFileSize(); | 272 int max_file_size = backend_->MaxFileSize(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 } | 311 } |
315 } | 312 } |
316 | 313 |
317 UpdateRank(true); | 314 UpdateRank(true); |
318 | 315 |
319 backend_->OnEvent(Stats::WRITE_DATA); | 316 backend_->OnEvent(Stats::WRITE_DATA); |
320 | 317 |
321 if (user_buffers_[index].get()) { | 318 if (user_buffers_[index].get()) { |
322 // Complete the operation locally. | 319 // Complete the operation locally. |
323 DCHECK(kMaxBlockSize >= offset + buf_len); | 320 DCHECK(kMaxBlockSize >= offset + buf_len); |
324 memcpy(user_buffers_[index].get() + offset, buf->data(), buf_len); | 321 memcpy(user_buffers_[index].get() + offset, buf, buf_len); |
325 stats.AddTime(Time::Now() - start); | 322 stats.AddTime(Time::Now() - start); |
326 return buf_len; | 323 return buf_len; |
327 } | 324 } |
328 | 325 |
329 Addr address(entry_.Data()->data_addr[index]); | 326 Addr address(entry_.Data()->data_addr[index]); |
330 File* file = GetBackingFile(address, index); | 327 File* file = GetBackingFile(address, index); |
331 if (!file) | 328 if (!file) |
332 return net::ERR_FAILED; | 329 return net::ERR_FAILED; |
333 | 330 |
334 size_t file_offset = offset; | 331 size_t file_offset = offset; |
335 if (address.is_block_file()) { | 332 if (address.is_block_file()) { |
336 file_offset += address.start_block() * address.BlockSize() + | 333 file_offset += address.start_block() * address.BlockSize() + |
337 kBlockHeaderSize; | 334 kBlockHeaderSize; |
338 } else if (truncate) { | 335 } else if (truncate) { |
339 if (!file->SetLength(offset + buf_len)) | 336 if (!file->SetLength(offset + buf_len)) |
340 return net::ERR_FAILED; | 337 return net::ERR_FAILED; |
341 } | 338 } |
342 | 339 |
343 if (!buf_len) | 340 if (!buf_len) |
344 return 0; | 341 return 0; |
345 | 342 |
346 SyncCallback* io_callback = NULL; | 343 SyncCallback* io_callback = NULL; |
347 if (completion_callback) | 344 if (completion_callback) |
348 io_callback = new SyncCallback(this, buf, completion_callback); | 345 io_callback = new SyncCallback(this, completion_callback); |
349 | 346 |
350 bool completed; | 347 bool completed; |
351 if (!file->Write(buf->data(), buf_len, file_offset, io_callback, | 348 if (!file->Write(buf, buf_len, file_offset, io_callback, &completed)) { |
352 &completed)) { | |
353 if (io_callback) | 349 if (io_callback) |
354 io_callback->Discard(); | 350 io_callback->Discard(); |
355 return net::ERR_FAILED; | 351 return net::ERR_FAILED; |
356 } | 352 } |
357 | 353 |
358 if (io_callback && completed) | 354 if (io_callback && completed) |
359 io_callback->Discard(); | 355 io_callback->Discard(); |
360 | 356 |
361 stats.AddTime(Time::Now() - start); | 357 stats.AddTime(Time::Now() - start); |
362 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; | 358 return (completed || !completion_callback) ? buf_len : net::ERR_IO_PENDING; |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 entry_.address().value(), node_.address().value()); | 772 entry_.address().value(), node_.address().value()); |
777 | 773 |
778 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], | 774 Trace(" data: 0x%x 0x%x 0x%x", entry_.Data()->data_addr[0], |
779 entry_.Data()->data_addr[1], entry_.Data()->long_key); | 775 entry_.Data()->data_addr[1], entry_.Data()->long_key); |
780 | 776 |
781 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); | 777 Trace(" doomed: %d 0x%p 0x%x", doomed_, pointer, dirty); |
782 } | 778 } |
783 | 779 |
784 } // namespace disk_cache | 780 } // namespace disk_cache |
785 | 781 |
OLD | NEW |