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

Side by Side Diff: net/disk_cache/v3/backend_worker.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: Created 7 years, 6 months 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/backend_worker.h ('k') | net/disk_cache/v3/block_bitmaps.h » ('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/backend_worker.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/message_loop.h"
10 #include "base/stringprintf.h"
11 #include "net/base/net_errors.h"
12 #include "net/disk_cache/cache_util.h"
13 #include "net/disk_cache/errors.h"
14 #include "net/disk_cache/experiments.h"
15 #include "net/disk_cache/mapped_file.h"
16 #include "net/disk_cache/v3/backend_work_item.h"
17 #include "net/disk_cache/v3/disk_format_v3.h"
18
19 using base::Time;
20 using base::TimeDelta;
21 using base::TimeTicks;
22
23 namespace {
24
25 const char kIndexName[] = "index";
26 const char kIndexBackupName[] = "index_bak";
27 const char kTable1Name[] = "index_tb1";
28 const char kTable2Name[] = "index_tb2";
29 const char kTable2TempName[] = "index_tb2_tmp";
30 const int kMaxOldFolders = 100;
31
32 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people.
33 // Note that the actual target is to keep the index table load factor under 55%
34 // for most users.
35 const int k64kEntriesStore = 240 * 1000 * 1000;
36 const int kBaseTableLen = 64 * 1024;
37 const int kDefaultCacheSize = 80 * 1024 * 1024;
38
39 // Avoid trimming the cache for the first 5 minutes (10 timer ticks).
40 const int kTrimDelay = 10;
41
42 int DesiredIndexTableLen(int32 storage_size) {
43 if (storage_size <= k64kEntriesStore)
44 return kBaseTableLen;
45 if (storage_size <= k64kEntriesStore * 2)
46 return kBaseTableLen * 2;
47 if (storage_size <= k64kEntriesStore * 4)
48 return kBaseTableLen * 4;
49 if (storage_size <= k64kEntriesStore * 8)
50 return kBaseTableLen * 8;
51
52 // The biggest storage_size for int32 requires a 4 MB table.
53 return kBaseTableLen * 16;
54 }
55
56 int MaxStorageSizeForTable(int table_len) {
57 return table_len * (k64kEntriesStore / kBaseTableLen);
58 }
59
60 size_t GetIndexSize(int table_len) {
61 //
62 //size_t table_size = sizeof(disk_cache::CacheAddr) * table_len;
63 //return sizeof(disk_cache::IndexHeaderV3) + table_size;
64 return 0;
65 }
66
67 size_t GetIndexBitmapSize(int table_len) {
68 DCHECK_LT(table_len, 1 << 22);
69 size_t base_bits = disk_cache::kBaseBitmapBytes * 8;
70 if (table_len < static_cast<int>(base_bits))
71 return sizeof(disk_cache::IndexBitmap);
72
73 size_t extra_pages = (table_len / 8) - disk_cache::kBaseBitmapBytes;
74 extra_pages = (extra_pages + 4095) / 4096;
75 return sizeof(disk_cache::IndexBitmap) + extra_pages * 4096;
76 }
77
78 // ------------------------------------------------------------------------
79
80 // Sets group for the current experiment. Returns false if the files should be
81 // discarded.
82 bool InitExperiment(disk_cache::IndexHeaderV3* header) {
83 header->experiment = disk_cache::NO_EXPERIMENT;
84 return true;
85 }
86
87 } // namespace
88
89 // ------------------------------------------------------------------------
90
91 namespace disk_cache {
92
93 BackendImplV3::Worker::Worker(const base::FilePath& path,
94 base::MessageLoopProxy* main_thread)
95 : path_(path),
96 main_thread_(main_thread),
97 cleanup_work_item_(NULL),
98 init_(false),
99 doubling_index_(false),
100 user_flags_(0) {
101 }
102
103 int BackendImplV3::Worker::Init(uint32 flags, scoped_ptr<InitResult>* result) {
104 DCHECK(!init_);
105 if (init_)
106 return ERR_INIT_FAILED;
107
108 user_flags_ = flags;
109 result->reset(new InitResult);
110
111 bool create_files = false;
112 if (!InitBackingStore(&create_files))
113 return ERR_STORAGE_ERROR;
114
115 init_ = true;
116 if (!LoadIndex(result->get()))
117 return ERR_INIT_FAILED;
118
119 int rv = ERR_NO_ERROR;
120 IndexHeaderV3* index =
121 reinterpret_cast<IndexHeaderV3*>(index_header_->buffer());
122 if (create_files || !index->num_entries)
123 rv = ERR_CACHE_CREATED;
124
125 if (create_files && (flags & EVICTION_V2)) {
126 index->flags |= CACHE_EVICTION_2;
127 }
128
129 if (!(flags & BASIC_UNIT_TEST) && !InitExperiment(index))
130 return ERR_INIT_FAILED;
131
132 if (index->crash != 0)
133 rv = ERR_PREVIOUS_CRASH;
134 index->crash = 1;
135
136 block_files_.reset(new BlockFiles(path_));
137 if (flags & BASIC_UNIT_TEST)
138 block_files_->UseSmallSizeIncrementsForTest();
139
140 if (!block_files_->Init(create_files, kFirstAdditionalBlockFileV3))
141 return ERR_INIT_FAILED;
142
143 block_files_->GetBitmaps(index->max_block_file,
144 &result->get()->block_bitmaps);
145 index->max_block_file = static_cast<int>(result->get()->block_bitmaps.size());
146
147 if (!InitStats(index, result->get()))
148 return ERR_INIT_FAILED;
149
150 #if defined(STRESS_CACHE_EXTENDED_VALIDATION)
151 trace_object_->EnableTracing(false);
152 int sc = SelfCheck();
153 if (sc < 0 && sc != ERR_NUM_ENTRIES_MISMATCH)
154 NOTREACHED();
155 trace_object_->EnableTracing(true);
156 #endif
157
158 return rv;
159 }
160
161 int BackendImplV3::Worker::Restart(uint32 flags,
162 scoped_ptr<InitResult>* result) {
163 Trace("Worker::Restart");
164 if (init_) {
165 init_ = false;
166 }
167
168 CloseFiles();
169 DeleteCache(path_, false);
170
171 return Init(flags, result);
172 }
173
174 int BackendImplV3::Worker::GrowIndex(uint32 flags,
175 scoped_ptr<InitResult>* result) {
176 Trace("Worker::GrowIndex, flags 0x%x", flags);
177 if (!init_)
178 return ERR_OPERATION_FAILED;
179
180 if (flags & WorkItem::WORK_COMPLETE) {
181 index_header_ = big_index_header_;
182 big_index_header_ = NULL;
183 if (big_main_table_) {
184 main_table_ = big_main_table_;
185 big_main_table_ = NULL;
186 }
187 if (!big_extra_temp_table_)
188 extra_table_ = big_extra_table_;
189 big_extra_table_ = NULL;
190
191 // If the index takes time to move the cells, it creates a new work item to
192 // notify completion, which executes this code.
193 if (big_extra_temp_table_)
194 return GrowDone();
195
196 return ERR_NO_ERROR;
197 }
198
199 IndexHeaderV3* header =
200 reinterpret_cast<IndexHeaderV3*>(index_header_->buffer());
201
202 int current_main_len = header->table_len / kIndexTablesize * kIndexTablesize;
203 int step_size = std::min(8192, current_main_len / 8);
204 if (user_flags_ & BASIC_UNIT_TEST)
205 step_size = 8;
206 if ((user_flags_ & UNIT_TEST_MODE) && !doubling_index_)
207 step_size = (header->table_len * 3 / 2) & 0x7ffffff0;
208 int new_len = header->table_len + step_size;
209
210 bool double_index = false;
211 if (!doubling_index_) {
212 DCHECK(!big_extra_table_);
213 DCHECK(!big_main_table_);
214 double_index = (new_len / kIndexTablesize !=
215 header->table_len / kIndexTablesize);
216 }
217
218 int extra_len = new_len - kIndexTablesize;
219 if (double_index) {
220 // We double the table when the extra table is about to reach the size of
221 // the main table. That means that right after this, the new extra table
222 // should be between 19% and 23% of the main table so we start with 25%.
223 extra_len = std::min(8192, current_main_len / 4);
224 extra_len = (user_flags_ & BASIC_UNIT_TEST) ? 128 : extra_len;
225 int main_len = (header->table_len / kIndexTablesize + 1) * kIndexTablesize;
226 new_len = main_len + extra_len;
227
228 if (!CreateExtraTable(extra_len * kBytesPerCell))
229 return ERR_OPERATION_FAILED;
230
231 if (!main_table_->SetLength(main_len * kBytesPerCell))
232 return ERR_OPERATION_FAILED;
233 } else if (doubling_index_) {
234 if (!big_extra_temp_table_->SetLength(extra_len * kBytesPerCell))
235 return ERR_OPERATION_FAILED;
236 } else {
237 if (!extra_table_->SetLength(extra_len * kBytesPerCell))
238 return ERR_OPERATION_FAILED;
239 }
240
241 if (!index_header_->SetLength(GetIndexBitmapSize(new_len)))
242 return ERR_OPERATION_FAILED;
243
244 scoped_refptr<MappedFile> big_index_header = new MappedFile();
245 if (!big_index_header->Init(path_.AppendASCII(kIndexName), 0)) {
246 LOG(ERROR) << "Unable to remap index";
247 return ERR_OPERATION_FAILED;
248 }
249
250 scoped_refptr<MappedFile> big_extra_table = new MappedFile();
251 const char* extra_name = (double_index || doubling_index_) ? kTable2TempName :
252 kTable2Name;
253 if (!big_extra_table->Init(path_.AppendASCII(extra_name), 0)) {
254 LOG(ERROR) << "Unable to remap index_tb2";
255 return ERR_OPERATION_FAILED;
256 }
257
258 if (double_index) {
259 scoped_refptr<MappedFile> big_main_table = new MappedFile();
260 if (!big_main_table->Init(path_.AppendASCII(kTable1Name), 0)) {
261 LOG(ERROR) << "Unable to remap index_tb1";
262 return ERR_OPERATION_FAILED;
263 }
264 big_main_table_.swap(big_main_table);
265
266 // Grab an extra reference to the new extra table that can be used for an
267 // extended period, while the index is being rebuilt. The normal reference
268 // (big_extra_table_) will be released when the work item is completed, but
269 // that doesn't mean the index is done with it.
270 // Note that we are able to process slow grow requests even when the index
271 // is being doubled.
272 big_extra_temp_table_ = big_extra_table;
273 }
274 big_index_header_.swap(big_index_header);
275 big_extra_table_.swap(big_extra_table);
276
277 header = reinterpret_cast<IndexHeaderV3*>(big_index_header_->buffer());
278 header->table_len = new_len;
279
280 result->reset(new InitResult);
281 result->get()->main_table = NULL;
282
283 result->get()->index_bitmap =
284 reinterpret_cast<IndexBitmap*>(big_index_header_->buffer());
285 result->get()->extra_table =
286 reinterpret_cast<IndexBucket*>(big_extra_table_->buffer());
287
288 if (double_index) {
289 result->get()->main_table =
290 reinterpret_cast<IndexBucket*>(big_main_table_->buffer());
291 doubling_index_ = true;
292 }
293
294 return ERR_NO_ERROR;
295 }
296
297 int BackendImplV3::Worker::GrowFiles(uint32 flags,
298 scoped_ptr<InitResult>* result) {
299 Trace("Worker::GrowFiles, flags 0x%x", flags);
300 if (!init_)
301 return ERR_OPERATION_FAILED;
302
303 if (flags & WorkItem::WORK_COMPLETE) {
304 block_files_.reset();
305 block_files_.swap(big_block_files_);
306 return ERR_NO_ERROR;
307 }
308
309 big_block_files_.reset(new BlockFiles(path_));
310 if (user_flags_ & BASIC_UNIT_TEST)
311 big_block_files_->UseSmallSizeIncrementsForTest();
312
313 if (!big_block_files_->Init(false, kFirstAdditionalBlockFileV3))
314 return ERR_INIT_FAILED;
315
316 IndexHeaderV3* index =
317 reinterpret_cast<IndexHeaderV3*>(index_header_->buffer());
318
319 result->reset(new InitResult);
320 big_block_files_->GetBitmaps(index->max_block_file,
321 &result->get()->block_bitmaps);
322 index->max_block_file = static_cast<int>(result->get()->block_bitmaps.size());
323 return ERR_NO_ERROR;
324 }
325
326 int BackendImplV3::Worker::Delete(Addr address) {
327 if (address.is_block_file())
328 return ERR_OPERATION_FAILED;
329
330 if (DeleteCacheFile(GetFileName(address)))
331 return ERR_NO_ERROR;
332
333 return ERR_OPERATION_FAILED;
334 }
335
336 int BackendImplV3::Worker::Close(Addr address) {
337 if (address.is_block_file())
338 return ERR_OPERATION_FAILED;
339
340 FilesMap::iterator it = files_.find(address.value());
341 if (it != files_.end())
342 files_.erase(it);
343
344 return ERR_NO_ERROR;
345 }
346
347 void BackendImplV3::Worker::OnDoWork(WorkItem* work_item) {
348 if (work_item->type() == WorkItem::WORK_CLEANUP)
349 return Cleanup(work_item);
350
351 work_item->Start(this);
352 }
353
354 void BackendImplV3::Worker::DoneWithItem(WorkItem* work_item) {
355 bool rv = main_thread_->PostTask(FROM_HERE,
356 base::Bind(&WorkItem::OnDone, work_item));
357 DCHECK(rv);
358 }
359
360 File* BackendImplV3::Worker::GetBackingFile(Addr address, bool for_write) {
361 disk_cache::File* file;
362 if (address.is_separate_file())
363 file = GetExternalFile(address, for_write);
364 else
365 file = block_files_->GetFile(address);
366 return file;
367 }
368
369 bool BackendImplV3::Worker::IsValid() {
370 return init_;
371 }
372
373 // ------------------------------------------------------------------------
374
375 BackendImplV3::Worker::~Worker() {
376 if (cleanup_work_item_)
377 main_thread_->PostTask(FROM_HERE,
378 base::Bind(&WorkItem::OnDone, cleanup_work_item_));
379 }
380
381 void BackendImplV3::Worker::Cleanup(WorkItem* work_item) {
382 Trace("Worker::Cleanup");
383 if (!work_item->user_callback().is_null())
384 cleanup_work_item_ = work_item;
385
386 if (init_) {
387 IndexHeaderV3* index =
388 reinterpret_cast<IndexHeaderV3*>(index_header_->buffer());
389 index->crash = 0;
390 }
391
392 CloseFiles();
393 init_ = false;
394
395 if (work_item->user_callback().is_null()) {
396 // This is the only message we don't return to the main thread, we are done
397 // with the work item for good.
398 work_item->Release();
399 }
400 }
401
402 void BackendImplV3::Worker::CloseFiles() {
403 index_header_ = NULL;
404 main_table_ = NULL;
405 extra_table_ = NULL;
406 index_backup_ = NULL;
407 block_files_->CloseFiles();
408 files_.clear();
409
410 big_index_header_ = NULL;
411 big_main_table_ = NULL;
412 big_extra_table_ = NULL;
413 big_extra_temp_table_ = NULL;
414 if (big_block_files_.get())
415 big_block_files_->CloseFiles();
416 }
417
418 File* BackendImplV3::Worker::GetExternalFile(Addr address, bool for_write) {
419 FilesMap::iterator it = files_.find(address.value());
420 if (it != files_.end())
421 return it->second;
422
423 scoped_refptr<disk_cache::File> file(new disk_cache::File(false));
424 if (for_write)
425 file->set_force_creation();
426 if (file->Init(GetFileName(address)))
427 files_[address.value()] = file.get();
428 else
429 file = NULL;
430
431 return file;
432 }
433
434 base::FilePath BackendImplV3::Worker::GetFileName(Addr address) const {
435 if (!address.is_separate_file() || !address.is_initialized()) {
436 NOTREACHED();
437 return base::FilePath();
438 }
439
440 std::string tmp = base::StringPrintf("f_%06x", address.FileNumber());
441 return path_.AppendASCII(tmp);
442 }
443
444 // We just created a new file so we're going to write the header and set the
445 // file length to include the hash table (zero filled).
446 bool BackendImplV3::Worker::CreateBackingStore(disk_cache::File* file) {
447 IndexHeaderV3 header;
448
449 // Start with 12.5% of the size of the main table.
450 int extra_len = (user_flags_ & BASIC_UNIT_TEST) ? 8 : kIndexTablesize / 8;
451 header.table_len = kIndexTablesize + extra_len;
452 header.max_bucket = kIndexTablesize / 4 - 1;
453
454 header.create_time = Time::Now().ToInternalValue();
455 header.base_time = (Time::Now() - TimeDelta::FromDays(20)).ToInternalValue();
456
457 if (!file->Write(&header, sizeof(header), 0))
458 return false;
459
460 if (!file->SetLength(GetIndexBitmapSize(header.table_len)))
461 return false;
462
463 int flags = base::PLATFORM_FILE_READ |
464 base::PLATFORM_FILE_WRITE |
465 base::PLATFORM_FILE_CREATE |
466 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
467
468 base::FilePath name = path_.AppendASCII(kIndexBackupName);
469 scoped_refptr<disk_cache::File> file2(new disk_cache::File(
470 base::CreatePlatformFile(name, flags, NULL, NULL)));
471
472 if (!file2->IsValid())
473 return false;
474
475 if (!file2->Write(&header, sizeof(header), 0))
476 return false;
477
478 if (!file2->SetLength(GetIndexBitmapSize(header.table_len)))
479 return false;
480
481 name = path_.AppendASCII(kTable1Name);
482 file2 = new disk_cache::File(base::CreatePlatformFile(name, flags, NULL,
483 NULL));
484 if (!file2->IsValid())
485 return false;
486
487 if (!file2->SetLength(kIndexTablesize * kBytesPerCell))
488 return false;
489
490 name = path_.AppendASCII(kTable2Name);
491 file2 = new disk_cache::File(base::CreatePlatformFile(name, flags, NULL,
492 NULL));
493 if (!file2->IsValid())
494 return false;
495
496 if (!file2->SetLength(extra_len * kBytesPerCell))
497 return false;
498
499 return true;
500 }
501
502 bool BackendImplV3::Worker::CreateExtraTable(int extra_len) {
503 int flags = base::PLATFORM_FILE_READ |
504 base::PLATFORM_FILE_WRITE |
505 base::PLATFORM_FILE_CREATE |
506 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
507
508 base::FilePath name = path_.AppendASCII(kTable2TempName);
509 scoped_refptr<disk_cache::File> file(new disk_cache::File(
510 base::CreatePlatformFile(name, flags, NULL, NULL)));
511 if (!file->IsValid())
512 return false;
513
514 if (!file->SetLength(extra_len * kBytesPerCell))
515 return false;
516
517 return true;
518 }
519
520 bool BackendImplV3::Worker::InitBackingStore(bool* file_created) {
521 if (!file_util::CreateDirectory(path_))
522 return false;
523
524 base::FilePath index_name = path_.AppendASCII(kIndexName);
525
526 int flags = base::PLATFORM_FILE_READ |
527 base::PLATFORM_FILE_WRITE |
528 base::PLATFORM_FILE_OPEN_ALWAYS |
529 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
530 scoped_refptr<disk_cache::File> file(new disk_cache::File(
531 base::CreatePlatformFile(index_name, flags, file_created, NULL)));
532
533 if (!file->IsValid())
534 return false;
535
536 bool ret = true;
537 if (*file_created)
538 ret = CreateBackingStore(file);
539
540 file = NULL;
541 if (!ret)
542 return false;
543
544 index_header_ = new MappedFile();
545 if (!index_header_->Init(index_name, 0)) {
546 LOG(ERROR) << "Unable to map index";
547 return false;
548 }
549
550 if (index_header_->GetLength() < sizeof(IndexBitmap)) {
551 // We verify this again on CheckIndex() but it's easier to make sure now
552 // that the header is there.
553 LOG(ERROR) << "Corrupt index file";
554 return false;
555 }
556
557 main_table_ = new MappedFile();
558 if (!main_table_->Init(path_.AppendASCII(kTable1Name), 0)) {
559 LOG(ERROR) << "Unable to map index_tb1";
560 return false;
561 }
562
563 extra_table_ = new MappedFile();
564 if (!extra_table_->Init(path_.AppendASCII(kTable2Name), 0)) {
565 LOG(ERROR) << "Unable to map index_tb2";
566 return false;
567 }
568
569 index_backup_ = new MappedFile();
570 if (!index_backup_->Init(path_.AppendASCII(kIndexBackupName), 0)) {
571 LOG(ERROR) << "Unable to map index_bak";
572 return false;
573 }
574
575 return true;
576 }
577
578 bool BackendImplV3::Worker::LoadIndex(InitResult* init_result) {
579 init_result->index_bitmap =
580 reinterpret_cast<IndexBitmap*>(index_header_->buffer());
581 init_result->main_table =
582 reinterpret_cast<IndexBucket*>(main_table_->buffer());
583 init_result->extra_table =
584 reinterpret_cast<IndexBucket*>(extra_table_->buffer());
585
586 if (!CheckIndexFile(index_header_))
587 return false;
588
589 if (!CheckIndexFile(index_backup_))
590 return false;
591
592 IndexHeaderV3& header = init_result->index_bitmap->header;
593
594 size_t extra_table_len = header.table_len % kIndexTablesize;
595 size_t main_table_len = (kIndexTablesize - extra_table_len) * kBytesPerCell;
596 extra_table_len *= kBytesPerCell;
597
598 if (main_table_->GetLength() < main_table_len ||
599 extra_table_->GetLength() < extra_table_len) {
600 LOG(ERROR) << "Truncated table";
601 return false;
602 }
603
604 IndexBitmap* index = reinterpret_cast<IndexBitmap*>(index_backup_->buffer());
605
606 init_result->backup_header.reset(new IndexHeaderV3);
607 memcpy(init_result->backup_header.get(), &index->header,
608 sizeof(index->header));
609
610 size_t bitmap_len = GetIndexBitmapSize(index->header.table_len) -
611 sizeof(index->header);
612 init_result->backup_bitmap.reset(new uint32[bitmap_len / 4]);
613 memcpy(init_result->backup_bitmap.get(), &index->bitmap, bitmap_len);
614
615 // Close the backup.
616 index_backup_ = NULL;
617 return true;
618 }
619
620 bool BackendImplV3::Worker::CheckIndexFile(MappedFile* file) {
621 size_t current_size = file->GetLength();
622 if (current_size < sizeof(IndexBitmap)) {
623 LOG(ERROR) << "Corrupt Index file";
624 return false;
625 }
626
627 IndexHeaderV3* header = reinterpret_cast<IndexHeaderV3*>(file->buffer());
628
629 if (kIndexMagic != header->magic ||
630 kCurrentVersion != header->version) {
631 LOG(ERROR) << "Invalid file version or magic";
632 return false;
633 }
634
635 if (header->table_len <= 0 || header->table_len > 1 << 22) {
636 LOG(ERROR) << "Invalid table size";
637 return false;
638 }
639
640 int min_mask = (user_flags_ & BASIC_UNIT_TEST) ? 0x3 : 0xff;
641 if (current_size < GetIndexBitmapSize(header->table_len) ||
642 header->table_len & (min_mask)) {
643 LOG(ERROR) << "Corrupt Index file";
644 return false;
645 }
646
647 //AdjustMaxCacheSize(header->table_len);
648
649 #if !defined(NET_BUILD_STRESS_CACHE)
650 if (header->num_bytes < 0 || header->max_bytes < 0 ||
651 header->num_bytes > header->max_bytes + kDefaultCacheSize) {
652 LOG(ERROR) << "Invalid cache size";
653 return false;
654 }
655 #endif
656
657 if (header->num_entries < 0) {
658 LOG(ERROR) << "Invalid number of entries";
659 return false;
660 }
661
662 // Load the table into memory with a single read.
663 //scoped_array<char> buf(new char[current_size]);
664 //return index_->Read(buf.get(), current_size, 0);
665
666 return true;
667 }
668
669 bool BackendImplV3::Worker::InitStats(IndexHeaderV3* index,
670 InitResult* result) {
671 Addr address(index->stats);
672 if (!address.is_initialized())
673 return true;
674
675 if (!address.is_block_file()) {
676 NOTREACHED();
677 return false;
678 }
679
680 int size = address.num_blocks() * address.BlockSize();
681
682 // Load the required data.
683 MappedFile* file = GetMappedFile(address);
684 if (!file)
685 return false;
686
687 scoped_ptr<char[]> data(new char[size]);
688 size_t offset = address.start_block() * address.BlockSize() +
689 kBlockHeaderSize;
690 if (!file->Read(data.get(), size, offset))
691 return false;
692
693 result->stats_data = data.Pass();
694 return true;
695 }
696
697 int BackendImplV3::Worker::GrowDone() {
698 Trace("Worker::GrowDone");
699 if (!init_)
700 return ERR_OPERATION_FAILED;
701
702 DCHECK(doubling_index_);
703 doubling_index_ = false;
704
705 extra_table_ = big_extra_temp_table_;
706 big_extra_temp_table_ = NULL;
707
708 return ERR_NO_ERROR;
709 }
710
711 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/v3/backend_worker.h ('k') | net/disk_cache/v3/block_bitmaps.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698