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