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

Side by Side Diff: net/disk_cache/block_files.cc

Issue 2891022: Disk cache: Read the index and data_0 files in a single... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 5 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
OLDNEW
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/block_files.h" 5 #include "net/disk_cache/block_files.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/histogram.h" 8 #include "base/histogram.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 if (zero_buffer_) 165 if (zero_buffer_)
166 delete[] zero_buffer_; 166 delete[] zero_buffer_;
167 CloseFiles(); 167 CloseFiles();
168 } 168 }
169 169
170 bool BlockFiles::Init(bool create_files) { 170 bool BlockFiles::Init(bool create_files) {
171 DCHECK(!init_); 171 DCHECK(!init_);
172 if (init_) 172 if (init_)
173 return false; 173 return false;
174 174
175 block_files_.resize(kFirstAdditionlBlockFile); 175 block_files_.resize(kFirstAdditionalBlockFile);
176 for (int i = 0; i < kFirstAdditionlBlockFile; i++) { 176 for (int i = 0; i < kFirstAdditionalBlockFile; i++) {
177 if (create_files) 177 if (create_files)
178 if (!CreateBlockFile(i, static_cast<FileType>(i + 1), true)) 178 if (!CreateBlockFile(i, static_cast<FileType>(i + 1), true))
179 return false; 179 return false;
180 180
181 if (!OpenBlockFile(i)) 181 if (!OpenBlockFile(i))
182 return false; 182 return false;
183 183
184 // Walk this chain of files removing empty ones. 184 // Walk this chain of files removing empty ones.
185 RemoveEmptyFile(static_cast<FileType>(i + 1)); 185 RemoveEmptyFile(static_cast<FileType>(i + 1));
186 } 186 }
187 187
188 init_ = true; 188 init_ = true;
189 return true; 189 return true;
190 } 190 }
191 191
192 void BlockFiles::CloseFiles() { 192 void BlockFiles::CloseFiles() {
193 init_ = false; 193 init_ = false;
194 for (unsigned int i = 0; i < block_files_.size(); i++) { 194 for (unsigned int i = 0; i < block_files_.size(); i++) {
195 if (block_files_[i]) { 195 if (block_files_[i]) {
196 block_files_[i]->Release(); 196 block_files_[i]->Release();
197 block_files_[i] = NULL; 197 block_files_[i] = NULL;
198 } 198 }
199 } 199 }
200 block_files_.clear(); 200 block_files_.clear();
201 } 201 }
202 202
203 FilePath BlockFiles::Name(int index) { 203 void BlockFiles::ReportStats() {
204 // The file format allows for 256 files. 204 int used_blocks[kFirstAdditionalBlockFile];
205 DCHECK(index < 256 || index >= 0); 205 int load[kFirstAdditionalBlockFile];
206 std::string tmp = StringPrintf("%s%d", kBlockName, index); 206 for (int i = 0; i < kFirstAdditionalBlockFile; i++) {
207 return path_.AppendASCII(tmp); 207 GetFileStats(i, &used_blocks[i], &load[i]);
208 }
209 UMA_HISTOGRAM_COUNTS("Blocks_0", used_blocks[0]);
210 UMA_HISTOGRAM_COUNTS("Blocks_1", used_blocks[1]);
211 UMA_HISTOGRAM_COUNTS("Blocks_2", used_blocks[2]);
212 UMA_HISTOGRAM_COUNTS("Blocks_3", used_blocks[3]);
213
214 UMA_HISTOGRAM_ENUMERATION("BlockLoad_0", load[0], 101);
215 UMA_HISTOGRAM_ENUMERATION("BlockLoad_1", load[1], 101);
216 UMA_HISTOGRAM_ENUMERATION("BlockLoad_2", load[2], 101);
217 UMA_HISTOGRAM_ENUMERATION("BlockLoad_3", load[3], 101);
208 } 218 }
209 219
210 bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) { 220 bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) {
211 FilePath name = Name(index); 221 FilePath name = Name(index);
212 int flags = 222 int flags =
213 force ? base::PLATFORM_FILE_CREATE_ALWAYS : base::PLATFORM_FILE_CREATE; 223 force ? base::PLATFORM_FILE_CREATE_ALWAYS : base::PLATFORM_FILE_CREATE;
214 flags |= base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE; 224 flags |= base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE;
215 225
216 scoped_refptr<File> file(new File( 226 scoped_refptr<File> file(new File(
217 base::CreatePlatformFile(name, flags, NULL))); 227 base::CreatePlatformFile(name, flags, NULL)));
(...skipping 16 matching lines...) Expand all
234 } 244 }
235 245
236 FilePath name = Name(index); 246 FilePath name = Name(index);
237 scoped_refptr<MappedFile> file(new MappedFile()); 247 scoped_refptr<MappedFile> file(new MappedFile());
238 248
239 if (!file->Init(name, kBlockHeaderSize)) { 249 if (!file->Init(name, kBlockHeaderSize)) {
240 LOG(ERROR) << "Failed to open " << name.value(); 250 LOG(ERROR) << "Failed to open " << name.value();
241 return false; 251 return false;
242 } 252 }
243 253
244 if (file->GetLength() < static_cast<size_t>(kBlockHeaderSize)) { 254 size_t file_len = file->GetLength();
gavinp 2010/07/15 15:03:48 nit: const
rvargas (doing something else) 2010/07/15 18:31:50 What do you mean? if you mean const size_t file_l
255 if (file_len < static_cast<size_t>(kBlockHeaderSize)) {
245 LOG(ERROR) << "File too small " << name.value(); 256 LOG(ERROR) << "File too small " << name.value();
246 return false; 257 return false;
247 } 258 }
248 259
249 BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 260 BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer());
250 if (kBlockMagic != header->magic || kCurrentVersion != header->version) { 261 if (kBlockMagic != header->magic || kCurrentVersion != header->version) {
251 LOG(ERROR) << "Invalid file version or magic"; 262 LOG(ERROR) << "Invalid file version or magic";
252 return false; 263 return false;
253 } 264 }
254 265
255 if (header->updating) { 266 if (header->updating) {
256 // Last instance was not properly shutdown. 267 // Last instance was not properly shutdown.
257 if (!FixBlockFileHeader(file)) 268 if (!FixBlockFileHeader(file))
258 return false; 269 return false;
259 } 270 }
260 271
272 if (index == 0) {
273 // Load the links file into memory with a single read.
274 scoped_array<char> buf(new char[file_len]);
275 if (!file->Read(buf.get(), file_len, 0))
276 return false;
277 }
278
261 DCHECK(!block_files_[index]); 279 DCHECK(!block_files_[index]);
262 file.swap(&block_files_[index]); 280 file.swap(&block_files_[index]);
263 return true; 281 return true;
264 } 282 }
265 283
266 MappedFile* BlockFiles::GetFile(Addr address) { 284 MappedFile* BlockFiles::GetFile(Addr address) {
267 DCHECK(block_files_.size() >= 4); 285 DCHECK(block_files_.size() >= 4);
268 DCHECK(address.is_block_file() || !address.is_initialized()); 286 DCHECK(address.is_block_file() || !address.is_initialized());
269 if (!address.is_initialized()) 287 if (!address.is_initialized())
270 return NULL; 288 return NULL;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 FileLock lock(header); 367 FileLock lock(header);
350 header->next_file = new_file; 368 header->next_file = new_file;
351 } 369 }
352 370
353 // Only the block_file argument is relevant for what we want. 371 // Only the block_file argument is relevant for what we want.
354 Addr address(BLOCK_256, 1, new_file, 0); 372 Addr address(BLOCK_256, 1, new_file, 0);
355 return GetFile(address); 373 return GetFile(address);
356 } 374 }
357 375
358 int BlockFiles::CreateNextBlockFile(FileType block_type) { 376 int BlockFiles::CreateNextBlockFile(FileType block_type) {
359 for (int i = kFirstAdditionlBlockFile; i <= kMaxBlockFile; i++) { 377 for (int i = kFirstAdditionalBlockFile; i <= kMaxBlockFile; i++) {
360 if (CreateBlockFile(i, block_type, false)) 378 if (CreateBlockFile(i, block_type, false))
361 return i; 379 return i;
362 } 380 }
363 return 0; 381 return 0;
364 } 382 }
365 383
366 // We walk the list of files for this particular block type, deleting the ones 384 // We walk the list of files for this particular block type, deleting the ones
367 // that are empty. 385 // that are empty.
368 void BlockFiles::RemoveEmptyFile(FileType block_type) { 386 void BlockFiles::RemoveEmptyFile(FileType block_type) {
369 MappedFile* file = block_files_[block_type - 1]; 387 MappedFile* file = block_files_[block_type - 1];
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 // We were in the middle of growing the file. 496 // We were in the middle of growing the file.
479 int num_entries = (file_size - sizeof(*header)) / header->entry_size; 497 int num_entries = (file_size - sizeof(*header)) / header->entry_size;
480 header->max_entries = num_entries; 498 header->max_entries = num_entries;
481 } 499 }
482 500
483 FixAllocationCounters(header); 501 FixAllocationCounters(header);
484 header->updating = 0; 502 header->updating = 0;
485 return true; 503 return true;
486 } 504 }
487 505
506 // We are interested in the total number of block used by this file type, and
507 // the max number of blocks that we can store (reported as the percentage of
508 // used blocks). In order to find out the number of used blocks, we have to
509 // substract the empty blocks from the total blocks for each file in the chain.
510 void BlockFiles::GetFileStats(int index, int* used_count, int* load) {
511 int max_blocks = 0;
512 *used_count = 0;
513 *load = 0;
514 for (;;) {
515 if (!block_files_[index] && !OpenBlockFile(index))
516 return;
517
518 BlockFileHeader* header =
519 reinterpret_cast<BlockFileHeader*>(block_files_[index]->buffer());
520
521 max_blocks += header->max_entries;
522 int used = header->max_entries;
523 for (int i = 0; i < 4; i++) {
524 used -= header->empty[i] * (i + 1);
nsylvain 2010/07/15 05:47:04 What does header->empty[i] contain? This looks a l
rvargas (doing something else) 2010/07/15 18:31:50 empty is an array of 4 slots that keeps the number
525 DCHECK_GE(used, 0);
526 }
527 *used_count += used;
528
529 if (!header->next_file)
530 break;
531 index = header->next_file;
532 }
533 if (max_blocks)
534 *load = *used_count * 100 / max_blocks;
535 }
536
537 FilePath BlockFiles::Name(int index) {
538 // The file format allows for 256 files.
539 DCHECK(index < 256 || index >= 0);
540 std::string tmp = StringPrintf("%s%d", kBlockName, index);
541 return path_.AppendASCII(tmp);
542 }
543
488 } // namespace disk_cache 544 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698