Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1613)

Side by Side Diff: net/disk_cache/v3/sparse_control_v3.cc

Issue 15203004: Disk cache: Reference CL for the implementation of file format version 3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: IndexTable review Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/v3/sparse_control_v3.h ('k') | net/net.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/disk_cache/v3/sparse_control_v3.h"
6
7 #include "base/bind.h"
8 #include "base/format_macros.h"
9 #include "base/logging.h"
10 #include "base/message_loop.h"
11 #include "base/stringprintf.h"
12 #include "base/time.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/disk_cache/net_log_parameters.h"
16 #include "net/disk_cache/v3/backend_impl_v3.h"
17 #include "net/disk_cache/v3/entry_impl_v3.h"
18
19 using base::Time;
20 using base::Bind;
21
22 namespace {
23
24 // Stream of the sparse data index.
25 const int kSparseIndex = 2;
26
27 // Stream of the sparse data.
28 const int kSparseData = 1;
29
30 // We can have up to 64k children.
31 const int kMaxMapSize = 8 * 1024;
32
33 // The maximum number of bytes that a child can store.
34 const int kMaxEntrySize = 0x100000;
35
36 // The size of each data block (tracked by the child allocation bitmap).
37 const int kBlockSize = 1024;
38
39 // Returns the name of a child entry given the base_name and signature of the
40 // parent and the child_id.
41 // If the entry is called entry_name, child entries will be named something
42 // like Range_entry_name:XXX:YYY where XXX is the entry signature and YYY is the
43 // number of the particular child.
44 std::string GenerateChildName(const std::string& base_name, int64 signature,
45 int64 child_id) {
46 return base::StringPrintf("Range_%s:%" PRIx64 ":%" PRIx64, base_name.c_str(),
47 signature, child_id);
48 }
49
50 // This class deletes the children of a sparse entry.
51 class ChildrenDeleter : public base::RefCountedThreadSafe<ChildrenDeleter> {
52 public:
53 ChildrenDeleter(disk_cache::BackendImplV3* backend, const std::string& name)
54 : backend_(backend->GetWeakPtr()), name_(name), signature_(0) {}
55
56 // Two ways of deleting the children: if we have the children map, use Start()
57 // directly, otherwise pass the data address to ReadData().
58 void Start(net::IOBuffer* buffer, int len);
59 void ReadData(disk_cache::Addr address, int len);
60
61 private:
62 friend class base::RefCountedThreadSafe<ChildrenDeleter>;
63 virtual ~ChildrenDeleter() {}
64
65 void DeleteChildren();
66 void OnReadComplete(int result);
67 void OnDoomComplete(int result);
68
69 base::WeakPtr<disk_cache::BackendImplV3> backend_;
70 std::string name_;
71 disk_cache::Bitmap children_map_;
72 int64 signature_;
73 scoped_refptr<net::IOBuffer> buffer_;
74 DISALLOW_COPY_AND_ASSIGN(ChildrenDeleter);
75 };
76
77 void ChildrenDeleter::Start(net::IOBuffer* buffer, int len) {
78 if (len < static_cast<int>(sizeof(disk_cache::SparseData)))
79 return Release();
80
81 // Just copy the information from |buffer|, delete |buffer| and start deleting
82 // the child entries.
83 disk_cache::SparseData* data =
84 reinterpret_cast<disk_cache::SparseData*>(buffer->data());
85 signature_ = data->header.signature;
86
87 int num_bits = (len - sizeof(disk_cache::SparseHeader)) * 8;
88 children_map_.Resize(num_bits, false);
89 children_map_.SetMap(data->bitmap, num_bits / 32);
90
91 MessageLoop::current()->PostTask(FROM_HERE,
92 Bind(&ChildrenDeleter::DeleteChildren,
93 this));
94 }
95
96 void ChildrenDeleter::ReadData(disk_cache::Addr address, int len) {
97 DCHECK(address.is_block_file());
98 if (!backend_)
99 return Release();
100
101 buffer_ = new net::IOBuffer(len);
102 backend_->ReadData(NULL, address, 0, buffer_, len,
103 Bind(&ChildrenDeleter::OnReadComplete, this));
104 }
105
106 void ChildrenDeleter::DeleteChildren() {
107 int child_id = 0;
108 for (int rv = net::OK; rv != net::ERR_IO_PENDING;) {
109 if (!children_map_.FindNextSetBit(&child_id) || !backend_) {
110 // We are done. Just delete this object.
111 return Release();
112 }
113 std::string child_name = GenerateChildName(name_, signature_, child_id);
114 rv = backend_->DoomEntry(child_name,
115 Bind(&ChildrenDeleter::OnDoomComplete, this));
116 children_map_.Set(child_id, false);
117 }
118 }
119
120 void ChildrenDeleter::OnReadComplete(int result) {
121 Start(buffer_, result);
122 }
123
124 void ChildrenDeleter::OnDoomComplete(int result) {
125 DeleteChildren();
126 }
127
128 // -----------------------------------------------------------------------
129
130 // Returns the NetLog event type corresponding to a SparseOperation.
131 net::NetLog::EventType GetSparseEventType(
132 disk_cache::SparseControlV3::SparseOperation operation) {
133 switch (operation) {
134 case disk_cache::SparseControlV3::kReadOperation:
135 return net::NetLog::TYPE_SPARSE_READ;
136 case disk_cache::SparseControlV3::kWriteOperation:
137 return net::NetLog::TYPE_SPARSE_WRITE;
138 case disk_cache::SparseControlV3::kGetRangeOperation:
139 return net::NetLog::TYPE_SPARSE_GET_RANGE;
140 default:
141 NOTREACHED();
142 return net::NetLog::TYPE_CANCELLED;
143 }
144 }
145
146 } // namespace.
147
148 namespace disk_cache {
149
150 SparseControlV3::SparseControlV3(EntryImplV3* entry)
151 : entry_(entry),
152 child_(NULL),
153 operation_(kNoOperation),
154 next_state_(STATE_NONE),
155 init_(false),
156 range_found_(false),
157 abort_(false),
158 valid_(false),
159 closing_(false),
160 child_map_(child_data_.bitmap, kNumSparseBits, kNumSparseBits / 32),
161 callback_(base::Bind(&SparseControlV3::OnIOComplete,
162 base::Unretained(this))),
163 offset_(0),
164 buf_len_(0),
165 child_offset_(0),
166 child_len_(0),
167 result_(0),
168 range_start_(NULL) {
169 memset(&sparse_header_, 0, sizeof(sparse_header_));
170 memset(&child_data_, 0, sizeof(child_data_));
171 }
172
173 SparseControlV3::~SparseControlV3() {
174 }
175
176 void SparseControlV3::Close() {
177 if (closing_)
178 return;
179 if (operation_ != kNoOperation || valid_) {
180 closing_ = true;
181 entry_->AddRef();
182 if (operation_ != kNoOperation)
183 return;
184
185 DCHECK_EQ(next_state_, STATE_NONE);
186 DCHECK(user_callback_.is_null());
187 next_state_ = STATE_CLOSE;
188 int rv = DoLoop(net::OK);
189 return;
190 }
191 }
192
193 bool SparseControlV3::CouldBeSparse() const {
194 if (init_)
195 return valid_;
196
197 if (entry_->GetDataSize(kSparseData))
198 return false;
199
200 // We don't verify the data, just see if it could be there.
201 return (entry_->GetDataSize(kSparseIndex) != 0);
202 }
203
204 int SparseControlV3::StartIO(SparseOperation op, int64 offset,
205 net::IOBuffer* buf, int buf_len,
206 const CompletionCallback& callback) {
207 // We don't support simultaneous IO for sparse data.
208 if (operation_ != kNoOperation)
209 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
210
211 if (offset < 0 || buf_len < 0)
212 return net::ERR_INVALID_ARGUMENT;
213
214 // We only support up to 64 GB.
215 if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0)
216 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
217
218 DCHECK(!user_buf_);
219 DCHECK(user_callback_.is_null());
220
221 if (init_ && !valid_)
222 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
223
224 if (!buf && (op == kReadOperation || op == kWriteOperation))
225 return 0;
226
227 // Copy the operation parameters.
228 operation_ = op;
229 offset_ = offset;
230 user_buf_ = buf ? new net::DrainableIOBuffer(buf, buf_len) : NULL;
231 buf_len_ = buf_len;
232
233 result_ = 0;
234 abort_ = false;
235
236 if (entry_->net_log().IsLoggingAllEvents()) {
237 entry_->net_log().BeginEvent(
238 GetSparseEventType(operation_),
239 CreateNetLogSparseOperationCallback(offset_, buf_len_));
240 }
241
242 DCHECK_EQ(next_state_, STATE_NONE);
243 next_state_ = init_ ? STATE_GET_CHILD_KEY : STATE_INIT;
244
245 int rv = DoLoop(net::OK);
246 if (rv == net::ERR_IO_PENDING) {
247 user_callback_ = callback;
248 entry_->AddRef(); // Self preservation while we're working.
249 } else {
250 operation_ = kNoOperation;
251 user_buf_ = NULL;
252 }
253
254 return rv;
255 }
256
257 int SparseControlV3::GetAvailableRange(int64 offset, int len, int64* start,
258 const CompletionCallback& callback) {
259 // We don't support simultaneous IO for sparse data.
260 if (operation_ != kNoOperation)
261 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
262
263 DCHECK(start);
264
265 // If there is a failure, we want to return a valid start.
266 *start = offset;
267 range_found_ = false;
268 range_start_ = start;
269 int result = StartIO(kGetRangeOperation, offset, NULL, len, callback);
270 if (range_found_) {
271 *start = offset_;
272 return result;
273 }
274
275 return result;
276 }
277
278 void SparseControlV3::CancelIO() {
279 if (operation_ == kNoOperation)
280 return;
281 abort_ = true;
282 }
283
284 int SparseControlV3::ReadyToUse(const CompletionCallback& callback) {
285 if (!abort_)
286 return net::OK;
287
288 // We'll grab another reference to keep this object alive because we just have
289 // one extra reference due to the pending IO operation itself, but we'll
290 // release that one before invoking user_callback_.
291 entry_->AddRef(); // Balanced in HanldeAbortCallbacks.
292 abort_callbacks_.push_back(callback);
293 return net::ERR_IO_PENDING;
294 }
295
296 // Static
297 void SparseControlV3::DeleteChildren(EntryImplV3* entry) {
298 DCHECK(entry->GetEntryFlags() & PARENT_ENTRY);
299 int data_len = entry->GetDataSize(kSparseIndex);
300 if (data_len < static_cast<int>(sizeof(SparseData)) ||
301 entry->GetDataSize(kSparseData))
302 return;
303
304 int map_len = data_len - sizeof(SparseHeader);
305 if (map_len > kMaxMapSize || map_len % 4)
306 return;
307
308 scoped_refptr<net::IOBuffer> buffer;
309 Addr address;
310 entry->GetData(kSparseIndex, &buffer, &address);
311 if (!buffer && !address.is_initialized())
312 return;
313
314 entry->net_log().AddEvent(net::NetLog::TYPE_SPARSE_DELETE_CHILDREN);
315
316 DCHECK(entry->backend_);
317 ChildrenDeleter* deleter = new ChildrenDeleter(entry->backend_,
318 entry->GetKey());
319 // The object will self destruct when finished.
320 deleter->AddRef();
321
322 if (buffer)
323 deleter->Start(buffer, data_len);
324 else
325 deleter->ReadData(address, data_len);
326 }
327
328 // -----------------------------------------------------------------------
329
330 int SparseControlV3::DoLoop(int result) {
331 DCHECK(next_state_ != STATE_NONE);
332
333 int rv = result;
334 do {
335 State state = next_state_;
336 next_state_ = STATE_NONE;
337 switch (state) {
338 case STATE_INIT:
339 DCHECK_EQ(net::OK, rv);
340 rv = DoInit();
341 break;
342 case STATE_CREATE_SPARSE_ENTRY:
343 DCHECK_EQ(net::OK, rv);
344 rv = DoCreateSparseEntry();
345 break;
346 case STATE_CREATE_SPARSE_ENTRY_COMPLETE:
347 rv = DoCreateSparseEntryComplete(rv);
348 break;
349 case STATE_OPEN_SPARSE_ENTRY:
350 rv = DoOpenSparseEntry(rv);
351 break;
352 case STATE_OPEN_SPARSE_ENTRY_COMPLETE:
353 rv = DoOpenSparseEntryComplete(rv);
354 break;
355 case STATE_READ_BITMAP_COMPLETE:
356 rv = DoReadBitmapComplete(rv);
357 break;
358 case STATE_GET_CHILD_KEY:
359 DCHECK_EQ(net::OK, rv);
360 rv = DoGetChildKey();
361 break;
362 case STATE_OPEN_CHILD:
363 DCHECK_EQ(net::OK, rv);
364 rv = DoOpenChild();
365 break;
366 case STATE_OPEN_CHILD_COMPLETE:
367 rv = DoOpenChildComplete(rv);
368 break;
369 case STATE_CREATE_CHILD:
370 DCHECK_EQ(net::OK, rv);
371 rv = DoCreateChild();
372 break;
373 case STATE_CREATE_CHILD_COMPLETE:
374 rv = DoCreateChildComplete(rv);
375 break;
376 case STATE_READ_SIGNATURE_COMPLETE:
377 rv = DoReadSignatureComplete(rv);
378 break;
379 case STATE_CLOSE_CHILD:
380 DCHECK_EQ(net::OK, rv);
381 rv = DoCloseChild();
382 break;
383 case STATE_CLOSE_CHILD_COMPLETE:
384 rv = DoCloseChildComplete(rv);
385 break;
386 case STATE_DO_CHILD_IO:
387 DCHECK_EQ(net::OK, rv);
388 rv = DoChildIO();
389 break;
390 case STATE_DO_CHILD_IO_COMPLETE:
391 rv = DoChildIOComplete(rv);
392 break;
393 case STATE_CLOSE:
394 DCHECK_EQ(net::OK, rv);
395 rv = DoClose();
396 break;
397 case STATE_WRITE_BITMAP:
398 DCHECK_EQ(net::OK, rv);
399 rv = DoWriteBitmap();
400 break;
401 case STATE_WRITE_BITMAP_COMPLETE:
402 rv = DoWriteBitmapComplete(rv);
403 break;
404 default:
405 NOTREACHED();
406 }
407 } while (rv != net::ERR_IO_PENDING && next_state_ != STATE_NONE);
408
409 if (rv != net::ERR_IO_PENDING)
410 HandleResult(rv);
411
412 return rv;
413 }
414
415 int SparseControlV3::DoInit() {
416 DCHECK(!init_);
417
418 // We should not have sparse data for the exposed entry.
419 if (entry_->GetDataSize(kSparseData))
420 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
421
422 // Now see if there is something where we store our data.
423 int rv = net::OK;
424 int data_len = entry_->GetDataSize(kSparseIndex);
425 if (data_len) {
426 next_state_ = STATE_OPEN_SPARSE_ENTRY;
427 return data_len;
428 }
429 next_state_ = STATE_CREATE_SPARSE_ENTRY;
430 return net::OK;
431 }
432
433 // We are going to start using this entry to store sparse data, so we have to
434 // initialize our control info.
435 int SparseControlV3::DoCreateSparseEntry() {
436 if (CHILD_ENTRY & entry_->GetEntryFlags())
437 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
438
439 memset(&sparse_header_, 0, sizeof(sparse_header_));
440 sparse_header_.signature = Time::Now().ToInternalValue();
441 sparse_header_.magic = kIndexMagicV3;
442 sparse_header_.parent_key_len = entry_->GetKey().size();
443 children_map_.Resize(kNumSparseBits, true);
444
445 // Save the header. The bitmap is saved in the destructor.
446 scoped_refptr<net::IOBuffer> buf(
447 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
448
449 next_state_ = STATE_CREATE_SPARSE_ENTRY_COMPLETE;
450 return entry_->WriteData(kSparseIndex, 0, buf, sizeof(sparse_header_),
451 callback_, false);
452 }
453
454 int SparseControlV3::DoCreateSparseEntryComplete(int result) {
455 if (result != sizeof(sparse_header_)) {
456 DLOG(ERROR) << "Unable to save sparse_header_";
457 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
458 }
459
460 entry_->SetEntryFlags(PARENT_ENTRY);
461 init_ = true;
462 valid_ = true;
463 next_state_ = STATE_GET_CHILD_KEY;
464 return net::OK;
465 }
466
467 // We are opening an entry from disk. Make sure that our control data is there.
468 int SparseControlV3::DoOpenSparseEntry(int data_len) {
469 if (data_len < static_cast<int>(sizeof(SparseData)))
470 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
471
472 if (entry_->GetDataSize(kSparseData))
473 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
474
475 if (!(PARENT_ENTRY & entry_->GetEntryFlags()))
476 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
477
478 // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB.
479 int map_len = data_len - sizeof(sparse_header_);
480 if (map_len > kMaxMapSize || map_len % 4)
481 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
482
483 scoped_refptr<net::IOBuffer> buf(
484 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_)));
485
486 // Read header.
487 next_state_ = STATE_OPEN_SPARSE_ENTRY_COMPLETE;
488 return entry_->ReadData(kSparseIndex, 0, buf, sizeof(sparse_header_),
489 callback_);
490 }
491
492 int SparseControlV3::DoOpenSparseEntryComplete(int result) {
493 if (result != static_cast<int>(sizeof(sparse_header_)))
494 return net::ERR_CACHE_READ_FAILURE;
495
496 // The real validation should be performed by the caller. This is just to
497 // double check.
498 if (sparse_header_.magic != kIndexMagicV3 ||
499 sparse_header_.parent_key_len !=
500 static_cast<int>(entry_->GetKey().size()))
501 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
502
503 // Read the actual bitmap.
504 int map_len = entry_->GetDataSize(kSparseIndex) - sizeof(sparse_header_);
505 buf_ = new net::IOBuffer(map_len);
506 next_state_ = STATE_READ_BITMAP_COMPLETE;
507 return entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf_, map_len,
508 callback_);
509 }
510
511 int SparseControlV3::DoReadBitmapComplete(int result) {
512 int map_len = entry_->GetDataSize(kSparseIndex) - sizeof(sparse_header_);
513 if (result != map_len)
514 return net::ERR_CACHE_READ_FAILURE;
515
516 // Grow the bitmap to the current size and copy the bits.
517 children_map_.Resize(map_len * 8, false);
518 children_map_.SetMap(reinterpret_cast<uint32*>(buf_->data()), map_len);
519 init_ = true;
520 valid_ = true;
521 next_state_ = STATE_GET_CHILD_KEY;
522 return net::OK;
523 }
524
525 int SparseControlV3::DoGetChildKey() {
526 key_ = GenerateChildKey();
527 if (child_) {
528 // Keep using the same child or open another one?.
529 if (key_ == child_->GetKey()) {
530 next_state_ = STATE_DO_CHILD_IO;
531 return net::OK;
532 }
533 next_state_ = STATE_CLOSE_CHILD;
534 return net::OK;
535 }
536 next_state_ = STATE_OPEN_CHILD;
537 return net::OK;
538 }
539
540 int SparseControlV3::DoOpenChild() {
541 // See if we are tracking this child.
542 if (!ChildPresent()) {
543 next_state_ = STATE_CREATE_CHILD;
544 return net::OK;
545 }
546
547 if (!entry_->backend_)
548 return net::ERR_FAILED;
549
550 next_state_ = STATE_OPEN_CHILD_COMPLETE;
551 return entry_->backend_->OpenEntry(key_, &child_, callback_);
552 }
553
554 int SparseControlV3::DoOpenChildComplete(int result) {
555 if (!child_) {
556 next_state_ = STATE_CREATE_CHILD;
557 return net::OK;
558 }
559
560 EntryImplV3* child = static_cast<EntryImplV3*>(child_);
561 if (!(CHILD_ENTRY & child->GetEntryFlags()) ||
562 child->GetDataSize(kSparseIndex) <
563 static_cast<int>(sizeof(child_data_))) {
564 return KillChildAndContinue();
565 }
566
567 scoped_refptr<net::WrappedIOBuffer> buf(
568 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
569
570 // Read signature.
571 next_state_ = STATE_READ_SIGNATURE_COMPLETE;
572 return child_->ReadData(kSparseIndex, 0, buf, sizeof(child_data_),
573 callback_);
574 }
575
576 int SparseControlV3::DoReadSignatureComplete(int result) {
577 if (result != sizeof(child_data_))
578 return KillChildAndContinue();
579
580 if (child_data_.header.signature != sparse_header_.signature ||
581 child_data_.header.magic != kIndexMagicV3)
582 return KillChildAndContinue();
583
584 if (child_data_.header.last_block_len < 0 ||
585 child_data_.header.last_block_len > kBlockSize) {
586 // Make sure these values are always within range.
587 child_data_.header.last_block_len = 0;
588 child_data_.header.last_block = -1;
589 }
590
591 next_state_ = STATE_DO_CHILD_IO;
592 return net::OK;
593 }
594
595 int SparseControlV3::DoCloseChild() {
596 next_state_ = STATE_CLOSE_CHILD_COMPLETE;
597 scoped_refptr<net::WrappedIOBuffer> buf(
598 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
599
600 // Save the allocation bitmap before closing the child entry.
601 return child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
602 callback_, false);
603 }
604
605 int SparseControlV3::DoCloseChildComplete(int result) {
606 if (result != sizeof(child_data_))
607 DLOG(ERROR) << "Failed to save child data";
608 child_->Close();
609 child_ = NULL;
610
611 DCHECK(valid_);
612 if (closing_ && user_callback_.is_null())
613 next_state_= STATE_WRITE_BITMAP;
614 else
615 next_state_ = STATE_OPEN_CHILD;
616
617 return net::OK;
618 }
619
620 // We were not able to open this child; see what we can do.
621 int SparseControlV3::DoCreateChild() {
622 if (kReadOperation == operation_)
623 return 0;
624 if (kGetRangeOperation == operation_) {
625 next_state_ = STATE_DO_CHILD_IO;
626 return net::OK;
627 }
628
629 if (!entry_->backend_)
630 return net::ERR_FAILED;
631
632 next_state_ = STATE_CREATE_CHILD_COMPLETE;
633 return entry_->backend_->CreateEntry(key_, &child_, callback_);
634 }
635
636 int SparseControlV3::DoCreateChildComplete(int result) {
637 if (result != net::OK)
638 return net::ERR_CACHE_READ_FAILURE;
639
640 // Write signature.
641 InitChildData();
642 next_state_ = STATE_DO_CHILD_IO;
643 return net::OK;
644 }
645
646 int SparseControlV3::DoWriteBitmap() {
647 next_state_ = STATE_WRITE_BITMAP_COMPLETE;
648 scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer(
649 reinterpret_cast<const char*>(children_map_.GetMap())));
650
651 int len = children_map_.ArraySize() * 4;
652 return entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len,
653 callback_, false);
654 }
655
656 int SparseControlV3::DoWriteBitmapComplete(int result) {
657 if (result != children_map_.ArraySize() * 4) {
658 DLOG(ERROR) << "Unable to save sparse map";
659 }
660 return net::OK;
661 }
662
663 int SparseControlV3::DoChildIO() {
664 if (!VerifyRange())
665 return 0;
666
667 int rv = 0;
668 switch (operation_) {
669 case kReadOperation:
670 LogChildOperationStart();
671 rv = child_->ReadData(kSparseData, child_offset_, user_buf_,
672 child_len_, callback_);
673 break;
674 case kWriteOperation:
675 LogChildOperationStart();
676 rv = child_->WriteData(kSparseData, child_offset_, user_buf_,
677 child_len_, callback_, false);
678 break;
679 case kGetRangeOperation:
680 rv = GetAvailableRangeImpl();
681 break;
682 default:
683 NOTREACHED();
684 }
685
686 next_state_ = STATE_DO_CHILD_IO_COMPLETE;
687 return rv;
688 }
689
690 int SparseControlV3::DoChildIOComplete(int result) {
691 LogChildOperationEnd(result);
692
693 if (result < 0)
694 return LogCompletion(result);
695
696 UpdateRange(result);
697
698 if (operation_ != kGetRangeOperation)
699 result_ += result;
700 offset_ += result;
701 buf_len_ -= result;
702
703 if (!buf_len_)
704 return LogCompletion(result_);
705
706 // We'll be reusing the user provided buffer for the next chunk.
707 if (buf_len_ && user_buf_)
708 user_buf_->DidConsume(result);
709
710 next_state_ = STATE_GET_CHILD_KEY;
711 return net::OK;
712 }
713
714 int SparseControlV3::DoClose() {
715 DCHECK(valid_);
716 DCHECK(user_callback_.is_null());
717 if (child_)
718 next_state_= STATE_CLOSE_CHILD;
719 else if (valid_)
720 next_state_= STATE_WRITE_BITMAP;
721
722 return net::OK;
723 }
724
725 std::string SparseControlV3::GenerateChildKey() {
726 return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
727 offset_ >> 20);
728 }
729
730 // We are deleting the child because something went wrong.
731 int SparseControlV3::KillChildAndContinue() {
732 SetChildBit(false);
733 child_->Doom();
734 child_->Close();
735 child_ = NULL;
736 next_state_ = STATE_CREATE_CHILD;
737 return net::OK;
738 }
739
740 bool SparseControlV3::ChildPresent() {
741 int child_bit = static_cast<int>(offset_ >> 20);
742 if (children_map_.Size() <= child_bit)
743 return false;
744
745 return children_map_.Get(child_bit);
746 }
747
748 void SparseControlV3::SetChildBit(bool value) {
749 int child_bit = static_cast<int>(offset_ >> 20);
750
751 // We may have to increase the bitmap of child entries.
752 if (children_map_.Size() <= child_bit)
753 children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true);
754
755 children_map_.Set(child_bit, value);
756 }
757
758 bool SparseControlV3::VerifyRange() {
759 child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1);
760 child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_);
761
762 // We can write to (or get info from) anywhere in this child.
763 if (operation_ != kReadOperation)
764 return true;
765
766 // Check that there are no holes in this range.
767 int last_bit = (child_offset_ + child_len_ + 1023) >> 10;
768 int start = child_offset_ >> 10;
769 if (child_map_.FindNextBit(&start, last_bit, false)) {
770 // Something is not here.
771 DCHECK_GE(child_data_.header.last_block_len, 0);
772 DCHECK_LT(child_data_.header.last_block_len, kMaxEntrySize);
773 int partial_block_len = PartialBlockLength(start);
774 if (start == child_offset_ >> 10) {
775 // It looks like we don't have anything.
776 if (partial_block_len <= (child_offset_ & (kBlockSize - 1)))
777 return false;
778 }
779
780 // We have the first part.
781 child_len_ = (start << 10) - child_offset_;
782 if (partial_block_len) {
783 // We may have a few extra bytes.
784 child_len_ = std::min(child_len_ + partial_block_len, buf_len_);
785 }
786 // There is no need to read more after this one.
787 buf_len_ = child_len_;
788 }
789 return true;
790 }
791
792 void SparseControlV3::UpdateRange(int result) {
793 if (result <= 0 || operation_ != kWriteOperation)
794 return;
795
796 DCHECK_GE(child_data_.header.last_block_len, 0);
797 DCHECK_LT(child_data_.header.last_block_len, kMaxEntrySize);
798
799 // Write the bitmap.
800 int first_bit = child_offset_ >> 10;
801 int block_offset = child_offset_ & (kBlockSize - 1);
802 if (block_offset && (child_data_.header.last_block != first_bit ||
803 child_data_.header.last_block_len < block_offset)) {
804 // The first block is not completely filled; ignore it.
805 first_bit++;
806 }
807
808 int last_bit = (child_offset_ + result) >> 10;
809 block_offset = (child_offset_ + result) & (kBlockSize - 1);
810
811 // This condition will hit with the following criteria:
812 // 1. The first byte doesn't follow the last write.
813 // 2. The first byte is in the middle of a block.
814 // 3. The first byte and the last byte are in the same block.
815 if (first_bit > last_bit)
816 return;
817
818 if (block_offset && !child_map_.Get(last_bit)) {
819 // The last block is not completely filled; save it for later.
820 child_data_.header.last_block = last_bit;
821 child_data_.header.last_block_len = block_offset;
822 } else {
823 child_data_.header.last_block = -1;
824 }
825
826 child_map_.SetRange(first_bit, last_bit, true);
827 }
828
829 int SparseControlV3::PartialBlockLength(int block_index) const {
830 if (block_index == child_data_.header.last_block)
831 return child_data_.header.last_block_len;
832
833 // This may be the last stored index.
834 int entry_len = child_->GetDataSize(kSparseData);
835 if (block_index == entry_len >> 10)
836 return entry_len & (kBlockSize - 1);
837
838 // This is really empty.
839 return 0;
840 }
841
842 void SparseControlV3::InitChildData() {
843 // We know the real type of child_.
844 EntryImplV3* child = static_cast<EntryImplV3*>(child_);
845 child->SetEntryFlags(CHILD_ENTRY);
846
847 memset(&child_data_, 0, sizeof(child_data_));
848 child_data_.header = sparse_header_;
849
850 scoped_refptr<net::WrappedIOBuffer> buf(
851 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_)));
852
853 int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
854 CompletionCallback(), false);
855 if (rv != sizeof(child_data_))
856 DLOG(ERROR) << "Failed to save child data";
857 SetChildBit(true);
858 }
859
860 int SparseControlV3::GetAvailableRangeImpl() {
861 if (!child_)
862 return child_len_; // Move on to the next child.
863
864 // Check that there are no holes in this range.
865 int last_bit = (child_offset_ + child_len_ + 1023) >> 10;
866 int start = child_offset_ >> 10;
867 int partial_start_bytes = PartialBlockLength(start);
868 int found = start;
869 int bits_found = child_map_.FindBits(&found, last_bit, true);
870
871 // We don't care if there is a partial block in the middle of the range.
872 int block_offset = child_offset_ & (kBlockSize - 1);
873 if (!bits_found && partial_start_bytes <= block_offset)
874 return child_len_;
875
876 // We are done. Just break the loop and reset result_ to our real result.
877 range_found_ = true;
878
879 // found now points to the first 1. Lets see if we have zeros before it.
880 int empty_start = std::max((found << 10) - child_offset_, 0);
881
882 int bytes_found = bits_found << 10;
883 bytes_found += PartialBlockLength(found + bits_found);
884
885 if (start == found)
886 bytes_found -= block_offset;
887
888 // If the user is searching past the end of this child, bits_found is the
889 // right result; otherwise, we have some empty space at the start of this
890 // query that we have to subtract from the range that we searched.
891 result_ = std::min(bytes_found, child_len_ - empty_start);
892
893 if (!bits_found) {
894 result_ = std::min(partial_start_bytes - block_offset, child_len_);
895 empty_start = 0;
896 }
897
898 // Only update offset_ when this query found zeros at the start.
899 if (empty_start)
900 offset_ += empty_start;
901
902 // This will actually break the loop.
903 buf_len_ = 0;
904 return 0;
905 }
906
907 void SparseControlV3::LogChildOperationStart() {
908 net::NetLog::EventType type = (operation_ == kReadOperation) ?
909 net::NetLog::TYPE_SPARSE_READ_CHILD_DATA :
910 net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA;
911
912 if (entry_->net_log().IsLoggingAllEvents()) {
913 disk_cache::EntryImplV3* entry =
914 reinterpret_cast<disk_cache::EntryImplV3*>(child_);
915 entry_->net_log().BeginEvent(
916 type,
917 CreateNetLogSparseReadWriteCallback(entry->net_log().source(),
918 child_len_));
919 }
920 }
921
922 void SparseControlV3::LogChildOperationEnd(int result) {
923 if (entry_->net_log().IsLoggingAllEvents()) {
924 net::NetLog::EventType event_type;
925 switch (operation_) {
926 case disk_cache::SparseControlV3::kReadOperation:
927 event_type = net::NetLog::TYPE_SPARSE_READ_CHILD_DATA;
928 break;
929 case disk_cache::SparseControlV3::kWriteOperation:
930 event_type = net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA;
931 break;
932 case disk_cache::SparseControlV3::kGetRangeOperation:
933 return;
934 default:
935 NOTREACHED();
936 return;
937 }
938 entry_->net_log().EndEventWithNetErrorCode(event_type, result);
939 }
940 }
941
942 int SparseControlV3::LogCompletion(int result) {
943 if (!entry_->net_log().IsLoggingAllEvents())
944 return result;
945
946 if (kGetRangeOperation == operation_) {
947 entry_->net_log().EndEvent(
948 net::NetLog::TYPE_SPARSE_GET_RANGE,
949 CreateNetLogGetAvailableRangeResultCallback(offset_, result));
950 } else {
951 entry_->net_log().EndEvent(GetSparseEventType(operation_));
952 }
953 return result;
954 }
955
956 void SparseControlV3::HandleResult(int result) {
957 if (!result && result_)
958 result = result_;
959
960 if (result > 0 && operation_ == kGetRangeOperation)
961 *range_start_ = offset_;
962
963 user_buf_ = NULL;
964 operation_ = kNoOperation;
965 next_state_ = STATE_NONE;
966
967 if (user_callback_.is_null()) {
968 if (closing_) {
969 closing_ = false;
970 entry_->Release(); // Don't touch object after this line.
971 }
972 return;
973 }
974
975 CompletionCallback cb = user_callback_;
976 user_callback_.Reset();
977 bool closing = closing_;
978 DCHECK(!closing_ || !entry_->HasOneRef());
979
980 entry_->Release(); // Don't touch object after this line.
981 cb.Run(result);
982
983 if (closing) {
984 // This object is not gone yet, but there's more work to do before the
985 // destructor runs.
986 next_state_ = STATE_CLOSE;
987 int rv = DoLoop(net::OK);
988 }
989 }
990
991 void SparseControlV3::HanldeAbortCallbacks() {
992 for (size_t i = 0; i < abort_callbacks_.size(); i++) {
993 // Releasing all references to entry_ may result in the destruction of this
994 // object so we should not be touching it after the last Release().
995 CompletionCallback cb = abort_callbacks_[i];
996 if (i == abort_callbacks_.size() - 1)
997 abort_callbacks_.clear();
998
999 entry_->Release(); // Don't touch object after this line.
1000 cb.Run(net::OK);
1001 }
1002 }
1003
1004 void SparseControlV3::OnIOComplete(int result) {
1005 DCHECK_NE(net::ERR_IO_PENDING, result);
1006
1007 if (abort_) {
1008 // We'll return the current result of the operation, which may be less than
1009 // the bytes to read or write, but the user cancelled the operation.
1010 abort_ = false;
1011 if (entry_->net_log().IsLoggingAllEvents()) {
1012 entry_->net_log().AddEvent(net::NetLog::TYPE_CANCELLED);
1013 entry_->net_log().EndEvent(GetSparseEventType(operation_));
1014 }
1015 // We have an indirect reference to this object for every callback so if
1016 // there is only one callback, we may delete this object before reaching
1017 // HanldeAbortCallbacks.
1018 bool has_abort_callbacks = !abort_callbacks_.empty();
1019 HandleResult(result);
1020 if (has_abort_callbacks)
1021 HanldeAbortCallbacks();
1022 return;
1023 }
1024
1025 DoLoop(result);
1026 }
1027
1028 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/v3/sparse_control_v3.h ('k') | net/net.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698