| OLD | NEW |
| 1 // Copyright (c) 2006-2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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/mem_entry_impl.h" | 5 #include "net/disk_cache/mem_entry_impl.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stringprintf.h" |
| 8 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
| 9 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| 10 #include "net/disk_cache/mem_backend_impl.h" | 11 #include "net/disk_cache/mem_backend_impl.h" |
| 12 #include "net/disk_cache/net_log_parameters.h" |
| 11 | 13 |
| 12 using base::Time; | 14 using base::Time; |
| 13 | 15 |
| 14 namespace { | 16 namespace { |
| 15 | 17 |
| 16 const int kSparseData = 1; | 18 const int kSparseData = 1; |
| 17 | 19 |
| 18 // Maximum size of a sparse entry is 2 to the power of this number. | 20 // Maximum size of a sparse entry is 2 to the power of this number. |
| 19 const int kMaxSparseEntryBits = 12; | 21 const int kMaxSparseEntryBits = 12; |
| 20 | 22 |
| 21 // Sparse entry has maximum size of 4KB. | 23 // Sparse entry has maximum size of 4KB. |
| 22 const int kMaxSparseEntrySize = 1 << kMaxSparseEntryBits; | 24 const int kMaxSparseEntrySize = 1 << kMaxSparseEntryBits; |
| 23 | 25 |
| 24 // Convert global offset to child index. | 26 // Convert global offset to child index. |
| 25 inline int ToChildIndex(int64 offset) { | 27 inline int ToChildIndex(int64 offset) { |
| 26 return static_cast<int>(offset >> kMaxSparseEntryBits); | 28 return static_cast<int>(offset >> kMaxSparseEntryBits); |
| 27 } | 29 } |
| 28 | 30 |
| 29 // Convert global offset to offset in child entry. | 31 // Convert global offset to offset in child entry. |
| 30 inline int ToChildOffset(int64 offset) { | 32 inline int ToChildOffset(int64 offset) { |
| 31 return static_cast<int>(offset & (kMaxSparseEntrySize - 1)); | 33 return static_cast<int>(offset & (kMaxSparseEntrySize - 1)); |
| 32 } | 34 } |
| 33 | 35 |
| 34 } // nemespace | 36 // Returns a name for a child entry given the base_name of the parent and the |
| 37 // child_id. This name is only used for logging purposes. |
| 38 // If the entry is called entry_name, child entries will be named something |
| 39 // like Range_entry_name:YYY where YYY is the number of the particular child. |
| 40 std::string GenerateChildName(const std::string& base_name, int child_id) { |
| 41 return base::StringPrintf("Range_%s:%i", base_name.c_str(), child_id); |
| 42 } |
| 43 |
| 44 } // namespace |
| 35 | 45 |
| 36 namespace disk_cache { | 46 namespace disk_cache { |
| 37 | 47 |
| 38 MemEntryImpl::MemEntryImpl(MemBackendImpl* backend) { | 48 MemEntryImpl::MemEntryImpl(MemBackendImpl* backend) { |
| 39 doomed_ = false; | 49 doomed_ = false; |
| 40 backend_ = backend; | 50 backend_ = backend; |
| 41 ref_count_ = 0; | 51 ref_count_ = 0; |
| 42 parent_ = NULL; | 52 parent_ = NULL; |
| 43 child_id_ = 0; | 53 child_id_ = 0; |
| 44 child_first_pos_ = 0; | 54 child_first_pos_ = 0; |
| 45 next_ = NULL; | 55 next_ = NULL; |
| 46 prev_ = NULL; | 56 prev_ = NULL; |
| 47 for (int i = 0; i < NUM_STREAMS; i++) | 57 for (int i = 0; i < NUM_STREAMS; i++) |
| 48 data_size_[i] = 0; | 58 data_size_[i] = 0; |
| 49 } | 59 } |
| 50 | 60 |
| 51 // ------------------------------------------------------------------------ | 61 // ------------------------------------------------------------------------ |
| 52 | 62 |
| 53 bool MemEntryImpl::CreateEntry(const std::string& key) { | 63 bool MemEntryImpl::CreateEntry(const std::string& key, net::NetLog* net_log) { |
| 64 net_log_ = net::BoundNetLog::Make(net_log, |
| 65 net::NetLog::SOURCE_MEMORY_CACHE_ENTRY); |
| 66 net_log_.BeginEvent( |
| 67 net::NetLog::TYPE_DISK_CACHE_MEM_ENTRY_IMPL, |
| 68 make_scoped_refptr(new EntryCreationParameters(key, true))); |
| 54 key_ = key; | 69 key_ = key; |
| 55 Time current = Time::Now(); | 70 Time current = Time::Now(); |
| 56 last_modified_ = current; | 71 last_modified_ = current; |
| 57 last_used_ = current; | 72 last_used_ = current; |
| 58 Open(); | 73 Open(); |
| 59 backend_->ModifyStorageSize(0, static_cast<int32>(key.size())); | 74 backend_->ModifyStorageSize(0, static_cast<int32>(key.size())); |
| 60 return true; | 75 return true; |
| 61 } | 76 } |
| 62 | 77 |
| 63 void MemEntryImpl::InternalDoom() { | 78 void MemEntryImpl::InternalDoom() { |
| 79 net_log_.AddEvent(net::NetLog::TYPE_ENTRY_DOOM, NULL); |
| 64 doomed_ = true; | 80 doomed_ = true; |
| 65 if (!ref_count_) { | 81 if (!ref_count_) { |
| 66 if (type() == kParentEntry) { | 82 if (type() == kParentEntry) { |
| 67 // If this is a parent entry, we need to doom all the child entries. | 83 // If this is a parent entry, we need to doom all the child entries. |
| 68 if (children_.get()) { | 84 if (children_.get()) { |
| 69 EntryMap children; | 85 EntryMap children; |
| 70 children.swap(*children_); | 86 children.swap(*children_); |
| 71 for (EntryMap::iterator i = children.begin(); | 87 for (EntryMap::iterator i = children.begin(); |
| 72 i != children.end(); ++i) { | 88 i != children.end(); ++i) { |
| 73 // Since a pointer to this object is also saved in the map, avoid | 89 // Since a pointer to this object is also saved in the map, avoid |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 } | 161 } |
| 146 | 162 |
| 147 int32 MemEntryImpl::GetDataSize(int index) const { | 163 int32 MemEntryImpl::GetDataSize(int index) const { |
| 148 if (index < 0 || index >= NUM_STREAMS) | 164 if (index < 0 || index >= NUM_STREAMS) |
| 149 return 0; | 165 return 0; |
| 150 return data_size_[index]; | 166 return data_size_[index]; |
| 151 } | 167 } |
| 152 | 168 |
| 153 int MemEntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, | 169 int MemEntryImpl::ReadData(int index, int offset, net::IOBuffer* buf, |
| 154 int buf_len, net::CompletionCallback* completion_callback) { | 170 int buf_len, net::CompletionCallback* completion_callback) { |
| 171 if (net_log_.IsLoggingAllEvents()) { |
| 172 net_log_.BeginEvent( |
| 173 net::NetLog::TYPE_ENTRY_READ_DATA, |
| 174 make_scoped_refptr( |
| 175 new ReadWriteDataParameters(index, offset, buf_len, false))); |
| 176 } |
| 177 |
| 178 int result = InternalReadData(index, offset, buf, buf_len); |
| 179 |
| 180 if (net_log_.IsLoggingAllEvents()) { |
| 181 net_log_.EndEvent( |
| 182 net::NetLog::TYPE_ENTRY_READ_DATA, |
| 183 make_scoped_refptr(new ReadWriteCompleteParameters(result))); |
| 184 } |
| 185 return result; |
| 186 } |
| 187 |
| 188 int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, |
| 189 int buf_len, net::CompletionCallback* completion_callback, bool truncate) { |
| 190 if (net_log_.IsLoggingAllEvents()) { |
| 191 net_log_.BeginEvent( |
| 192 net::NetLog::TYPE_ENTRY_WRITE_DATA, |
| 193 make_scoped_refptr( |
| 194 new ReadWriteDataParameters(index, offset, buf_len, truncate))); |
| 195 } |
| 196 |
| 197 int result = InternalWriteData(index, offset, buf, buf_len, truncate); |
| 198 |
| 199 if (net_log_.IsLoggingAllEvents()) { |
| 200 net_log_.EndEvent( |
| 201 net::NetLog::TYPE_ENTRY_WRITE_DATA, |
| 202 make_scoped_refptr(new ReadWriteCompleteParameters(result))); |
| 203 } |
| 204 return result; |
| 205 } |
| 206 |
| 207 int MemEntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 208 net::CompletionCallback* completion_callback) { |
| 209 if (net_log_.IsLoggingAllEvents()) { |
| 210 net_log_.BeginEvent( |
| 211 net::NetLog::TYPE_SPARSE_READ, |
| 212 make_scoped_refptr( |
| 213 new SparseOperationParameters(offset, buf_len))); |
| 214 } |
| 215 int result = InternalReadSparseData(offset, buf, buf_len); |
| 216 if (net_log_.IsLoggingAllEvents()) |
| 217 net_log_.EndEvent(net::NetLog::TYPE_SPARSE_READ, NULL); |
| 218 return result; |
| 219 } |
| 220 |
| 221 int MemEntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, |
| 222 net::CompletionCallback* completion_callback) { |
| 223 if (net_log_.IsLoggingAllEvents()) { |
| 224 net_log_.BeginEvent(net::NetLog::TYPE_SPARSE_WRITE, |
| 225 make_scoped_refptr( |
| 226 new SparseOperationParameters(offset, buf_len))); |
| 227 } |
| 228 int result = InternalWriteSparseData(offset, buf, buf_len); |
| 229 if (net_log_.IsLoggingAllEvents()) |
| 230 net_log_.EndEvent(net::NetLog::TYPE_SPARSE_WRITE, NULL); |
| 231 return result; |
| 232 } |
| 233 |
| 234 int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start, |
| 235 CompletionCallback* callback) { |
| 236 if (net_log_.IsLoggingAllEvents()) { |
| 237 net_log_.BeginEvent( |
| 238 net::NetLog::TYPE_SPARSE_GET_RANGE, |
| 239 make_scoped_refptr( |
| 240 new SparseOperationParameters(offset, len))); |
| 241 } |
| 242 int result = GetAvailableRange(offset, len, start); |
| 243 if (net_log_.IsLoggingAllEvents()) { |
| 244 net_log_.EndEvent( |
| 245 net::NetLog::TYPE_SPARSE_GET_RANGE, |
| 246 make_scoped_refptr( |
| 247 new GetAvailableRangeResultParameters(*start, result))); |
| 248 } |
| 249 return result; |
| 250 } |
| 251 |
| 252 bool MemEntryImpl::CouldBeSparse() const { |
| 253 DCHECK_EQ(kParentEntry, type()); |
| 254 return (children_.get() != NULL); |
| 255 } |
| 256 |
| 257 int MemEntryImpl::ReadyForSparseIO( |
| 258 net::CompletionCallback* completion_callback) { |
| 259 return net::OK; |
| 260 } |
| 261 |
| 262 // ------------------------------------------------------------------------ |
| 263 |
| 264 MemEntryImpl::~MemEntryImpl() { |
| 265 for (int i = 0; i < NUM_STREAMS; i++) |
| 266 backend_->ModifyStorageSize(data_size_[i], 0); |
| 267 backend_->ModifyStorageSize(static_cast<int32>(key_.size()), 0); |
| 268 net_log_.EndEvent(net::NetLog::TYPE_DISK_CACHE_MEM_ENTRY_IMPL, NULL); |
| 269 } |
| 270 |
| 271 int MemEntryImpl::InternalReadData(int index, int offset, net::IOBuffer* buf, |
| 272 int buf_len) { |
| 155 DCHECK(type() == kParentEntry || index == kSparseData); | 273 DCHECK(type() == kParentEntry || index == kSparseData); |
| 156 | 274 |
| 157 if (index < 0 || index >= NUM_STREAMS) | 275 if (index < 0 || index >= NUM_STREAMS) |
| 158 return net::ERR_INVALID_ARGUMENT; | 276 return net::ERR_INVALID_ARGUMENT; |
| 159 | 277 |
| 160 int entry_size = GetDataSize(index); | 278 int entry_size = GetDataSize(index); |
| 161 if (offset >= entry_size || offset < 0 || !buf_len) | 279 if (offset >= entry_size || offset < 0 || !buf_len) |
| 162 return 0; | 280 return 0; |
| 163 | 281 |
| 164 if (buf_len < 0) | 282 if (buf_len < 0) |
| 165 return net::ERR_INVALID_ARGUMENT; | 283 return net::ERR_INVALID_ARGUMENT; |
| 166 | 284 |
| 167 if (offset + buf_len > entry_size) | 285 if (offset + buf_len > entry_size) |
| 168 buf_len = entry_size - offset; | 286 buf_len = entry_size - offset; |
| 169 | 287 |
| 170 UpdateRank(false); | 288 UpdateRank(false); |
| 171 | 289 |
| 172 memcpy(buf->data() , &(data_[index])[offset], buf_len); | 290 memcpy(buf->data(), &(data_[index])[offset], buf_len); |
| 173 return buf_len; | 291 return buf_len; |
| 174 } | 292 } |
| 175 | 293 |
| 176 int MemEntryImpl::WriteData(int index, int offset, net::IOBuffer* buf, | 294 int MemEntryImpl::InternalWriteData(int index, int offset, net::IOBuffer* buf, |
| 177 int buf_len, net::CompletionCallback* completion_callback, bool truncate) { | 295 int buf_len, bool truncate) { |
| 178 DCHECK(type() == kParentEntry || index == kSparseData); | 296 DCHECK(type() == kParentEntry || index == kSparseData); |
| 179 | 297 |
| 180 if (index < 0 || index >= NUM_STREAMS) | 298 if (index < 0 || index >= NUM_STREAMS) |
| 181 return net::ERR_INVALID_ARGUMENT; | 299 return net::ERR_INVALID_ARGUMENT; |
| 182 | 300 |
| 183 if (offset < 0 || buf_len < 0) | 301 if (offset < 0 || buf_len < 0) |
| 184 return net::ERR_INVALID_ARGUMENT; | 302 return net::ERR_INVALID_ARGUMENT; |
| 185 | 303 |
| 186 int max_file_size = backend_->MaxFileSize(); | 304 int max_file_size = backend_->MaxFileSize(); |
| 187 | 305 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 208 | 326 |
| 209 UpdateRank(true); | 327 UpdateRank(true); |
| 210 | 328 |
| 211 if (!buf_len) | 329 if (!buf_len) |
| 212 return 0; | 330 return 0; |
| 213 | 331 |
| 214 memcpy(&(data_[index])[offset], buf->data(), buf_len); | 332 memcpy(&(data_[index])[offset], buf->data(), buf_len); |
| 215 return buf_len; | 333 return buf_len; |
| 216 } | 334 } |
| 217 | 335 |
| 218 int MemEntryImpl::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 336 int MemEntryImpl::InternalReadSparseData(int64 offset, net::IOBuffer* buf, |
| 219 net::CompletionCallback* completion_callback) { | 337 int buf_len) { |
| 220 DCHECK(type() == kParentEntry); | 338 DCHECK(type() == kParentEntry); |
| 221 | 339 |
| 222 if (!InitSparseInfo()) | 340 if (!InitSparseInfo()) |
| 223 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 341 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 224 | 342 |
| 225 if (offset < 0 || buf_len < 0) | 343 if (offset < 0 || buf_len < 0) |
| 226 return net::ERR_INVALID_ARGUMENT; | 344 return net::ERR_INVALID_ARGUMENT; |
| 227 | 345 |
| 228 // We will keep using this buffer and adjust the offset in this buffer. | 346 // We will keep using this buffer and adjust the offset in this buffer. |
| 229 scoped_refptr<net::DrainableIOBuffer> io_buf( | 347 scoped_refptr<net::DrainableIOBuffer> io_buf( |
| 230 new net::DrainableIOBuffer(buf, buf_len)); | 348 new net::DrainableIOBuffer(buf, buf_len)); |
| 231 | 349 |
| 232 // Iterate until we have read enough. | 350 // Iterate until we have read enough. |
| 233 while (io_buf->BytesRemaining()) { | 351 while (io_buf->BytesRemaining()) { |
| 234 MemEntryImpl* child = OpenChild(offset + io_buf->BytesConsumed(), false); | 352 MemEntryImpl* child = OpenChild(offset + io_buf->BytesConsumed(), false); |
| 235 | 353 |
| 236 // No child present for that offset. | 354 // No child present for that offset. |
| 237 if (!child) | 355 if (!child) |
| 238 break; | 356 break; |
| 239 | 357 |
| 240 // We then need to prepare the child offset and len. | 358 // We then need to prepare the child offset and len. |
| 241 int child_offset = ToChildOffset(offset + io_buf->BytesConsumed()); | 359 int child_offset = ToChildOffset(offset + io_buf->BytesConsumed()); |
| 242 | 360 |
| 243 // If we are trying to read from a position that the child entry has no data | 361 // If we are trying to read from a position that the child entry has no data |
| 244 // we should stop. | 362 // we should stop. |
| 245 if (child_offset < child->child_first_pos_) | 363 if (child_offset < child->child_first_pos_) |
| 246 break; | 364 break; |
| 365 if (net_log_.IsLoggingAllEvents()) { |
| 366 net_log_.BeginEvent( |
| 367 net::NetLog::TYPE_SPARSE_READ_CHILD_DATA, |
| 368 make_scoped_refptr(new SparseReadWriteParameters( |
| 369 child->net_log().source(), |
| 370 io_buf->BytesRemaining()))); |
| 371 } |
| 247 int ret = child->ReadData(kSparseData, child_offset, io_buf, | 372 int ret = child->ReadData(kSparseData, child_offset, io_buf, |
| 248 io_buf->BytesRemaining(), NULL); | 373 io_buf->BytesRemaining(), NULL); |
| 374 if (net_log_.IsLoggingAllEvents()) { |
| 375 net_log_.EndEventWithNetErrorCode( |
| 376 net::NetLog::TYPE_SPARSE_READ_CHILD_DATA, ret); |
| 377 } |
| 249 | 378 |
| 250 // If we encounter an error in one entry, return immediately. | 379 // If we encounter an error in one entry, return immediately. |
| 251 if (ret < 0) | 380 if (ret < 0) |
| 252 return ret; | 381 return ret; |
| 253 else if (ret == 0) | 382 else if (ret == 0) |
| 254 break; | 383 break; |
| 255 | 384 |
| 256 // Increment the counter by number of bytes read in the child entry. | 385 // Increment the counter by number of bytes read in the child entry. |
| 257 io_buf->DidConsume(ret); | 386 io_buf->DidConsume(ret); |
| 258 } | 387 } |
| 259 | 388 |
| 260 UpdateRank(false); | 389 UpdateRank(false); |
| 261 | 390 |
| 262 return io_buf->BytesConsumed(); | 391 return io_buf->BytesConsumed(); |
| 263 } | 392 } |
| 264 | 393 |
| 265 int MemEntryImpl::WriteSparseData(int64 offset, net::IOBuffer* buf, int buf_len, | 394 int MemEntryImpl::InternalWriteSparseData(int64 offset, net::IOBuffer* buf, |
| 266 net::CompletionCallback* completion_callback) { | 395 int buf_len) { |
| 267 DCHECK(type() == kParentEntry); | 396 DCHECK(type() == kParentEntry); |
| 268 | 397 |
| 269 if (!InitSparseInfo()) | 398 if (!InitSparseInfo()) |
| 270 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 399 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 271 | 400 |
| 272 if (offset < 0 || buf_len < 0) | 401 if (offset < 0 || buf_len < 0) |
| 273 return net::ERR_INVALID_ARGUMENT; | 402 return net::ERR_INVALID_ARGUMENT; |
| 274 | 403 |
| 275 scoped_refptr<net::DrainableIOBuffer> io_buf( | 404 scoped_refptr<net::DrainableIOBuffer> io_buf( |
| 276 new net::DrainableIOBuffer(buf, buf_len)); | 405 new net::DrainableIOBuffer(buf, buf_len)); |
| 277 | 406 |
| 278 // This loop walks through child entries continuously starting from |offset| | 407 // This loop walks through child entries continuously starting from |offset| |
| 279 // and writes blocks of data (of maximum size kMaxSparseEntrySize) into each | 408 // and writes blocks of data (of maximum size kMaxSparseEntrySize) into each |
| 280 // child entry until all |buf_len| bytes are written. The write operation can | 409 // child entry until all |buf_len| bytes are written. The write operation can |
| 281 // start in the middle of an entry. | 410 // start in the middle of an entry. |
| 282 while (io_buf->BytesRemaining()) { | 411 while (io_buf->BytesRemaining()) { |
| 283 MemEntryImpl* child = OpenChild(offset + io_buf->BytesConsumed(), true); | 412 MemEntryImpl* child = OpenChild(offset + io_buf->BytesConsumed(), true); |
| 284 int child_offset = ToChildOffset(offset + io_buf->BytesConsumed()); | 413 int child_offset = ToChildOffset(offset + io_buf->BytesConsumed()); |
| 285 | 414 |
| 286 // Find the right amount to write, this evaluates the remaining bytes to | 415 // Find the right amount to write, this evaluates the remaining bytes to |
| 287 // write and remaining capacity of this child entry. | 416 // write and remaining capacity of this child entry. |
| 288 int write_len = std::min(static_cast<int>(io_buf->BytesRemaining()), | 417 int write_len = std::min(static_cast<int>(io_buf->BytesRemaining()), |
| 289 kMaxSparseEntrySize - child_offset); | 418 kMaxSparseEntrySize - child_offset); |
| 290 | 419 |
| 291 // Keep a record of the last byte position (exclusive) in the child. | 420 // Keep a record of the last byte position (exclusive) in the child. |
| 292 int data_size = child->GetDataSize(kSparseData); | 421 int data_size = child->GetDataSize(kSparseData); |
| 293 | 422 |
| 423 if (net_log_.IsLoggingAllEvents()) { |
| 424 net_log_.BeginEvent( |
| 425 net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA, |
| 426 make_scoped_refptr(new SparseReadWriteParameters( |
| 427 child->net_log().source(), |
| 428 write_len))); |
| 429 } |
| 430 |
| 294 // Always writes to the child entry. This operation may overwrite data | 431 // Always writes to the child entry. This operation may overwrite data |
| 295 // previously written. | 432 // previously written. |
| 296 // TODO(hclam): if there is data in the entry and this write is not | 433 // TODO(hclam): if there is data in the entry and this write is not |
| 297 // continuous we may want to discard this write. | 434 // continuous we may want to discard this write. |
| 298 int ret = child->WriteData(kSparseData, child_offset, io_buf, write_len, | 435 int ret = child->WriteData(kSparseData, child_offset, io_buf, write_len, |
| 299 NULL, true); | 436 NULL, true); |
| 437 if (net_log_.IsLoggingAllEvents()) { |
| 438 net_log_.EndEventWithNetErrorCode( |
| 439 net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA, ret); |
| 440 } |
| 300 if (ret < 0) | 441 if (ret < 0) |
| 301 return ret; | 442 return ret; |
| 302 else if (ret == 0) | 443 else if (ret == 0) |
| 303 break; | 444 break; |
| 304 | 445 |
| 305 // Keep a record of the first byte position in the child if the write was | 446 // Keep a record of the first byte position in the child if the write was |
| 306 // not aligned nor continuous. This is to enable witting to the middle | 447 // not aligned nor continuous. This is to enable witting to the middle |
| 307 // of an entry and still keep track of data off the aligned edge. | 448 // of an entry and still keep track of data off the aligned edge. |
| 308 if (data_size != child_offset) | 449 if (data_size != child_offset) |
| 309 child->child_first_pos_ = child_offset; | 450 child->child_first_pos_ = child_offset; |
| 310 | 451 |
| 311 // Adjust the offset in the IO buffer. | 452 // Adjust the offset in the IO buffer. |
| 312 io_buf->DidConsume(ret); | 453 io_buf->DidConsume(ret); |
| 313 } | 454 } |
| 314 | 455 |
| 315 UpdateRank(true); | 456 UpdateRank(true); |
| 316 | 457 |
| 317 return io_buf->BytesConsumed(); | 458 return io_buf->BytesConsumed(); |
| 318 } | 459 } |
| 319 | 460 |
| 320 int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start, | |
| 321 CompletionCallback* callback) { | |
| 322 return GetAvailableRange(offset, len, start); | |
| 323 } | |
| 324 | |
| 325 bool MemEntryImpl::CouldBeSparse() const { | |
| 326 DCHECK_EQ(kParentEntry, type()); | |
| 327 return (children_.get() != NULL); | |
| 328 } | |
| 329 | |
| 330 int MemEntryImpl::ReadyForSparseIO( | |
| 331 net::CompletionCallback* completion_callback) { | |
| 332 return net::OK; | |
| 333 } | |
| 334 | |
| 335 // ------------------------------------------------------------------------ | |
| 336 | |
| 337 MemEntryImpl::~MemEntryImpl() { | |
| 338 for (int i = 0; i < NUM_STREAMS; i++) | |
| 339 backend_->ModifyStorageSize(data_size_[i], 0); | |
| 340 backend_->ModifyStorageSize(static_cast<int32>(key_.size()), 0); | |
| 341 } | |
| 342 | |
| 343 int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { | 461 int MemEntryImpl::GetAvailableRange(int64 offset, int len, int64* start) { |
| 344 DCHECK(type() == kParentEntry); | 462 DCHECK(type() == kParentEntry); |
| 345 DCHECK(start); | 463 DCHECK(start); |
| 346 | 464 |
| 347 if (!InitSparseInfo()) | 465 if (!InitSparseInfo()) |
| 348 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 466 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 349 | 467 |
| 350 if (offset < 0 || len < 0 || !start) | 468 if (offset < 0 || len < 0 || !start) |
| 351 return net::ERR_INVALID_ARGUMENT; | 469 return net::ERR_INVALID_ARGUMENT; |
| 352 | 470 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 return false; | 540 return false; |
| 423 children_.reset(new EntryMap()); | 541 children_.reset(new EntryMap()); |
| 424 | 542 |
| 425 // The parent entry stores data for the first block, so save this object to | 543 // The parent entry stores data for the first block, so save this object to |
| 426 // index 0. | 544 // index 0. |
| 427 (*children_)[0] = this; | 545 (*children_)[0] = this; |
| 428 } | 546 } |
| 429 return true; | 547 return true; |
| 430 } | 548 } |
| 431 | 549 |
| 432 bool MemEntryImpl::InitChildEntry(MemEntryImpl* parent, int child_id) { | 550 bool MemEntryImpl::InitChildEntry(MemEntryImpl* parent, int child_id, |
| 551 net::NetLog* net_log) { |
| 433 DCHECK(!parent_); | 552 DCHECK(!parent_); |
| 434 DCHECK(!child_id_); | 553 DCHECK(!child_id_); |
| 554 |
| 555 net_log_ = net::BoundNetLog::Make(net_log, |
| 556 net::NetLog::SOURCE_MEMORY_CACHE_ENTRY); |
| 557 net_log_.BeginEvent( |
| 558 net::NetLog::TYPE_DISK_CACHE_MEM_ENTRY_IMPL, |
| 559 make_scoped_refptr(new EntryCreationParameters( |
| 560 GenerateChildName(parent->key(), child_id_), |
| 561 true))); |
| 562 |
| 435 parent_ = parent; | 563 parent_ = parent; |
| 436 child_id_ = child_id; | 564 child_id_ = child_id; |
| 437 Time current = Time::Now(); | 565 Time current = Time::Now(); |
| 438 last_modified_ = current; | 566 last_modified_ = current; |
| 439 last_used_ = current; | 567 last_used_ = current; |
| 440 // Insert this to the backend's ranking list. | 568 // Insert this to the backend's ranking list. |
| 441 backend_->InsertIntoRankingList(this); | 569 backend_->InsertIntoRankingList(this); |
| 442 return true; | 570 return true; |
| 443 } | 571 } |
| 444 | 572 |
| 445 MemEntryImpl* MemEntryImpl::OpenChild(int64 offset, bool create) { | 573 MemEntryImpl* MemEntryImpl::OpenChild(int64 offset, bool create) { |
| 446 DCHECK(type() == kParentEntry); | 574 DCHECK(type() == kParentEntry); |
| 447 int index = ToChildIndex(offset); | 575 int index = ToChildIndex(offset); |
| 448 EntryMap::iterator i = children_->find(index); | 576 EntryMap::iterator i = children_->find(index); |
| 449 if (i != children_->end()) { | 577 if (i != children_->end()) { |
| 450 return i->second; | 578 return i->second; |
| 451 } else if (create) { | 579 } else if (create) { |
| 452 MemEntryImpl* child = new MemEntryImpl(backend_); | 580 MemEntryImpl* child = new MemEntryImpl(backend_); |
| 453 child->InitChildEntry(this, index); | 581 child->InitChildEntry(this, index, net_log_.net_log()); |
| 454 (*children_)[index] = child; | 582 (*children_)[index] = child; |
| 455 return child; | 583 return child; |
| 456 } | 584 } |
| 457 return NULL; | 585 return NULL; |
| 458 } | 586 } |
| 459 | 587 |
| 460 int MemEntryImpl::FindNextChild(int64 offset, int len, MemEntryImpl** child) { | 588 int MemEntryImpl::FindNextChild(int64 offset, int len, MemEntryImpl** child) { |
| 461 DCHECK(child); | 589 DCHECK(child); |
| 462 *child = NULL; | 590 *child = NULL; |
| 463 int scanned_len = 0; | 591 int scanned_len = 0; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 487 scanned_len += kMaxSparseEntrySize - current_child_offset; | 615 scanned_len += kMaxSparseEntrySize - current_child_offset; |
| 488 } | 616 } |
| 489 return scanned_len; | 617 return scanned_len; |
| 490 } | 618 } |
| 491 | 619 |
| 492 void MemEntryImpl::DetachChild(int child_id) { | 620 void MemEntryImpl::DetachChild(int child_id) { |
| 493 children_->erase(child_id); | 621 children_->erase(child_id); |
| 494 } | 622 } |
| 495 | 623 |
| 496 } // namespace disk_cache | 624 } // namespace disk_cache |
| OLD | NEW |