| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/backend_impl.h" | 5 #include "net/disk_cache/backend_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| 11 #include "base/hash.h" | 11 #include "base/hash.h" |
| 12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 13 #include "base/metrics/field_trial.h" | 13 #include "base/metrics/field_trial.h" |
| 14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
| 15 #include "base/metrics/stats_counters.h" | 15 #include "base/metrics/stats_counters.h" |
| 16 #include "base/rand_util.h" | 16 #include "base/rand_util.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
| 19 #include "base/sys_info.h" | 19 #include "base/sys_info.h" |
| 20 #include "base/threading/thread_restrictions.h" | 20 #include "base/threading/thread_restrictions.h" |
| 21 #include "base/time.h" | 21 #include "base/time.h" |
| 22 #include "base/timer.h" | 22 #include "base/timer.h" |
| 23 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
| 24 #include "net/disk_cache/cache_util.h" | 24 #include "net/disk_cache/cache_util.h" |
| 25 #include "net/disk_cache/disk_format.h" |
| 25 #include "net/disk_cache/entry_impl.h" | 26 #include "net/disk_cache/entry_impl.h" |
| 26 #include "net/disk_cache/errors.h" | 27 #include "net/disk_cache/errors.h" |
| 27 #include "net/disk_cache/experiments.h" | 28 #include "net/disk_cache/experiments.h" |
| 28 #include "net/disk_cache/file.h" | 29 #include "net/disk_cache/file.h" |
| 29 | 30 |
| 30 // This has to be defined before including histogram_macros.h from this file. | 31 // This has to be defined before including histogram_macros.h from this file. |
| 31 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ | 32 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ |
| 32 #include "net/disk_cache/histogram_macros.h" | 33 #include "net/disk_cache/histogram_macros.h" |
| 33 | 34 |
| 34 using base::Time; | 35 using base::Time; |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 // the id cannot be zero, because that value is used as "not dirty". | 278 // the id cannot be zero, because that value is used as "not dirty". |
| 278 // Increasing the value once per second gives us many years before we start | 279 // Increasing the value once per second gives us many years before we start |
| 279 // having collisions. | 280 // having collisions. |
| 280 data_->header.this_id++; | 281 data_->header.this_id++; |
| 281 if (!data_->header.this_id) | 282 if (!data_->header.this_id) |
| 282 data_->header.this_id++; | 283 data_->header.this_id++; |
| 283 | 284 |
| 284 bool previous_crash = (data_->header.crash != 0); | 285 bool previous_crash = (data_->header.crash != 0); |
| 285 data_->header.crash = 1; | 286 data_->header.crash = 1; |
| 286 | 287 |
| 287 if (!block_files_.Init(create_files)) | 288 if (!block_files_.Init(create_files, kFirstAdditionalBlockFile)) |
| 288 return net::ERR_FAILED; | 289 return net::ERR_FAILED; |
| 289 | 290 |
| 290 // We want to minimize the changes to cache for an AppCache. | 291 // We want to minimize the changes to cache for an AppCache. |
| 291 if (cache_type() == net::APP_CACHE) { | 292 if (cache_type() == net::APP_CACHE) { |
| 292 DCHECK(!new_eviction_); | 293 DCHECK(!new_eviction_); |
| 293 read_only_ = true; | 294 read_only_ = true; |
| 294 } else if (cache_type() == net::SHADER_CACHE) { | 295 } else if (cache_type() == net::SHADER_CACHE) { |
| 295 DCHECK(!new_eviction_); | 296 DCHECK(!new_eviction_); |
| 296 } | 297 } |
| 297 | 298 |
| 298 eviction_.Init(this); | 299 eviction_.Init(this); |
| 299 | 300 |
| 300 // stats_ and rankings_ may end up calling back to us so we better be enabled. | 301 // stats_ and rankings_ may end up calling back to us so we better be enabled. |
| 301 disabled_ = false; | 302 disabled_ = false; |
| 302 if (!stats_.Init(this, &data_->header.stats)) | 303 if (!InitStats()) |
| 303 return net::ERR_FAILED; | 304 return net::ERR_FAILED; |
| 304 | 305 |
| 305 disabled_ = !rankings_.Init(this, new_eviction_); | 306 disabled_ = !rankings_.Init(this, new_eviction_); |
| 306 | 307 |
| 307 #if defined(STRESS_CACHE_EXTENDED_VALIDATION) | 308 #if defined(STRESS_CACHE_EXTENDED_VALIDATION) |
| 308 trace_object_->EnableTracing(false); | 309 trace_object_->EnableTracing(false); |
| 309 int sc = SelfCheck(); | 310 int sc = SelfCheck(); |
| 310 if (sc < 0 && sc != ERR_NUM_ENTRIES_MISMATCH) | 311 if (sc < 0 && sc != ERR_NUM_ENTRIES_MISMATCH) |
| 311 NOTREACHED(); | 312 NOTREACHED(); |
| 312 trace_object_->EnableTracing(true); | 313 trace_object_->EnableTracing(true); |
| 313 #endif | 314 #endif |
| 314 | 315 |
| 315 if (previous_crash) { | 316 if (previous_crash) { |
| 316 ReportError(ERR_PREVIOUS_CRASH); | 317 ReportError(ERR_PREVIOUS_CRASH); |
| 317 } else if (!restarted_) { | 318 } else if (!restarted_) { |
| 318 ReportError(ERR_NO_ERROR); | 319 ReportError(ERR_NO_ERROR); |
| 319 } | 320 } |
| 320 | 321 |
| 321 FlushIndex(); | 322 FlushIndex(); |
| 322 | 323 |
| 323 return disabled_ ? net::ERR_FAILED : net::OK; | 324 return disabled_ ? net::ERR_FAILED : net::OK; |
| 324 } | 325 } |
| 325 | 326 |
| 326 void BackendImpl::CleanupCache() { | 327 void BackendImpl::CleanupCache() { |
| 327 Trace("Backend Cleanup"); | 328 Trace("Backend Cleanup"); |
| 328 eviction_.Stop(); | 329 eviction_.Stop(); |
| 329 timer_.reset(); | 330 timer_.reset(); |
| 330 | 331 |
| 331 if (init_) { | 332 if (init_) { |
| 332 stats_.Store(); | 333 StoreStats(); |
| 333 if (data_) | 334 if (data_) |
| 334 data_->header.crash = 0; | 335 data_->header.crash = 0; |
| 335 | 336 |
| 336 if (user_flags_ & kNoRandom) { | 337 if (user_flags_ & kNoRandom) { |
| 337 // This is a net_unittest, verify that we are not 'leaking' entries. | 338 // This is a net_unittest, verify that we are not 'leaking' entries. |
| 338 File::WaitForPendingIO(&num_pending_io_); | 339 File::WaitForPendingIO(&num_pending_io_); |
| 339 DCHECK(!num_refs_); | 340 DCHECK(!num_refs_); |
| 340 } else { | 341 } else { |
| 341 File::DropPendingIO(); | 342 File::DropPendingIO(); |
| 342 } | 343 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 block_files_.DeleteBlock(entry_address, false); | 601 block_files_.DeleteBlock(entry_address, false); |
| 601 block_files_.DeleteBlock(node_address, false); | 602 block_files_.DeleteBlock(node_address, false); |
| 602 LOG(ERROR) << "Create entry failed " << key.c_str(); | 603 LOG(ERROR) << "Create entry failed " << key.c_str(); |
| 603 stats_.OnEvent(Stats::CREATE_ERROR); | 604 stats_.OnEvent(Stats::CREATE_ERROR); |
| 604 return NULL; | 605 return NULL; |
| 605 } | 606 } |
| 606 | 607 |
| 607 cache_entry->BeginLogging(net_log_, true); | 608 cache_entry->BeginLogging(net_log_, true); |
| 608 | 609 |
| 609 // We are not failing the operation; let's add this to the map. | 610 // We are not failing the operation; let's add this to the map. |
| 610 open_entries_[entry_address.value()] = cache_entry; | 611 open_entries_[entry_address.value()] = cache_entry.get(); |
| 611 | 612 |
| 612 // Save the entry. | 613 // Save the entry. |
| 613 cache_entry->entry()->Store(); | 614 cache_entry->entry()->Store(); |
| 614 cache_entry->rankings()->Store(); | 615 cache_entry->rankings()->Store(); |
| 615 IncreaseNumEntries(); | 616 IncreaseNumEntries(); |
| 616 entry_count_++; | 617 entry_count_++; |
| 617 | 618 |
| 618 // Link this entry through the index. | 619 // Link this entry through the index. |
| 619 if (parent.get()) { | 620 if (parent.get()) { |
| 620 parent->SetNextAddress(entry_address); | 621 parent->SetNextAddress(entry_address); |
| 621 } else { | 622 } else { |
| 622 data_->table[hash & mask_] = entry_address.value(); | 623 data_->table[hash & mask_] = entry_address.value(); |
| 623 } | 624 } |
| 624 | 625 |
| 625 // Link this entry through the lists. | 626 // Link this entry through the lists. |
| 626 eviction_.OnCreateEntry(cache_entry); | 627 eviction_.OnCreateEntry(cache_entry.get()); |
| 627 | 628 |
| 628 CACHE_UMA(AGE_MS, "CreateTime", 0, start); | 629 CACHE_UMA(AGE_MS, "CreateTime", 0, start); |
| 629 stats_.OnEvent(Stats::CREATE_HIT); | 630 stats_.OnEvent(Stats::CREATE_HIT); |
| 630 SIMPLE_STATS_COUNTER("disk_cache.miss"); | 631 SIMPLE_STATS_COUNTER("disk_cache.miss"); |
| 631 Trace("create entry hit "); | 632 Trace("create entry hit "); |
| 632 FlushIndex(); | 633 FlushIndex(); |
| 633 cache_entry->AddRef(); | 634 cache_entry->AddRef(); |
| 634 return cache_entry.get(); | 635 return cache_entry.get(); |
| 635 } | 636 } |
| 636 | 637 |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 stats_.OnEvent(Stats::FATAL_ERROR); | 994 stats_.OnEvent(Stats::FATAL_ERROR); |
| 994 LogStats(); | 995 LogStats(); |
| 995 ReportError(error); | 996 ReportError(error); |
| 996 | 997 |
| 997 // Setting the index table length to an invalid value will force re-creation | 998 // Setting the index table length to an invalid value will force re-creation |
| 998 // of the cache files. | 999 // of the cache files. |
| 999 data_->header.table_len = 1; | 1000 data_->header.table_len = 1; |
| 1000 disabled_ = true; | 1001 disabled_ = true; |
| 1001 | 1002 |
| 1002 if (!num_refs_) | 1003 if (!num_refs_) |
| 1003 MessageLoop::current()->PostTask(FROM_HERE, | 1004 base::MessageLoop::current()->PostTask( |
| 1004 base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); | 1005 FROM_HERE, base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); |
| 1005 } | 1006 } |
| 1006 | 1007 |
| 1007 void BackendImpl::ReportError(int error) { | 1008 void BackendImpl::ReportError(int error) { |
| 1008 STRESS_DCHECK(!error || error == ERR_PREVIOUS_CRASH || | 1009 STRESS_DCHECK(!error || error == ERR_PREVIOUS_CRASH || |
| 1009 error == ERR_CACHE_CREATED); | 1010 error == ERR_CACHE_CREATED); |
| 1010 | 1011 |
| 1011 // We transmit positive numbers, instead of direct error codes. | 1012 // We transmit positive numbers, instead of direct error codes. |
| 1012 DCHECK_LE(error, 0); | 1013 DCHECK_LE(error, 0); |
| 1013 CACHE_UMA(CACHE_ERROR, "Error", 0, error * -1); | 1014 CACHE_UMA(CACHE_ERROR, "Error", 0, error * -1); |
| 1014 } | 1015 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 if (!data_) | 1060 if (!data_) |
| 1060 first_timer_ = false; | 1061 first_timer_ = false; |
| 1061 if (first_timer_) { | 1062 if (first_timer_) { |
| 1062 first_timer_ = false; | 1063 first_timer_ = false; |
| 1063 if (ShouldReportAgain()) | 1064 if (ShouldReportAgain()) |
| 1064 ReportStats(); | 1065 ReportStats(); |
| 1065 } | 1066 } |
| 1066 | 1067 |
| 1067 // Save stats to disk at 5 min intervals. | 1068 // Save stats to disk at 5 min intervals. |
| 1068 if (time % 10 == 0) | 1069 if (time % 10 == 0) |
| 1069 stats_.Store(); | 1070 StoreStats(); |
| 1070 } | 1071 } |
| 1071 | 1072 |
| 1072 void BackendImpl::IncrementIoCount() { | 1073 void BackendImpl::IncrementIoCount() { |
| 1073 num_pending_io_++; | 1074 num_pending_io_++; |
| 1074 } | 1075 } |
| 1075 | 1076 |
| 1076 void BackendImpl::DecrementIoCount() { | 1077 void BackendImpl::DecrementIoCount() { |
| 1077 num_pending_io_--; | 1078 num_pending_io_--; |
| 1078 } | 1079 } |
| 1079 | 1080 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1240 stats->push_back(item); | 1241 stats->push_back(item); |
| 1241 | 1242 |
| 1242 item.first = "Max size"; | 1243 item.first = "Max size"; |
| 1243 item.second = base::StringPrintf("%d", max_size_); | 1244 item.second = base::StringPrintf("%d", max_size_); |
| 1244 stats->push_back(item); | 1245 stats->push_back(item); |
| 1245 | 1246 |
| 1246 item.first = "Current size"; | 1247 item.first = "Current size"; |
| 1247 item.second = base::StringPrintf("%d", data_->header.num_bytes); | 1248 item.second = base::StringPrintf("%d", data_->header.num_bytes); |
| 1248 stats->push_back(item); | 1249 stats->push_back(item); |
| 1249 | 1250 |
| 1251 item.first = "Cache type"; |
| 1252 item.second = "Blockfile Cache"; |
| 1253 stats->push_back(item); |
| 1254 |
| 1250 stats_.GetItems(stats); | 1255 stats_.GetItems(stats); |
| 1251 } | 1256 } |
| 1252 | 1257 |
| 1253 void BackendImpl::OnExternalCacheHit(const std::string& key) { | 1258 void BackendImpl::OnExternalCacheHit(const std::string& key) { |
| 1254 background_queue_.OnExternalCacheHit(key); | 1259 background_queue_.OnExternalCacheHit(key); |
| 1255 } | 1260 } |
| 1256 | 1261 |
| 1257 // ------------------------------------------------------------------------ | 1262 // ------------------------------------------------------------------------ |
| 1258 | 1263 |
| 1259 // We just created a new file so we're going to write the header and set the | 1264 // We just created a new file so we're going to write the header and set the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1287 base::PLATFORM_FILE_OPEN_ALWAYS | | 1292 base::PLATFORM_FILE_OPEN_ALWAYS | |
| 1288 base::PLATFORM_FILE_EXCLUSIVE_WRITE; | 1293 base::PLATFORM_FILE_EXCLUSIVE_WRITE; |
| 1289 scoped_refptr<disk_cache::File> file(new disk_cache::File( | 1294 scoped_refptr<disk_cache::File> file(new disk_cache::File( |
| 1290 base::CreatePlatformFile(index_name, flags, file_created, NULL))); | 1295 base::CreatePlatformFile(index_name, flags, file_created, NULL))); |
| 1291 | 1296 |
| 1292 if (!file->IsValid()) | 1297 if (!file->IsValid()) |
| 1293 return false; | 1298 return false; |
| 1294 | 1299 |
| 1295 bool ret = true; | 1300 bool ret = true; |
| 1296 if (*file_created) | 1301 if (*file_created) |
| 1297 ret = CreateBackingStore(file); | 1302 ret = CreateBackingStore(file.get()); |
| 1298 | 1303 |
| 1299 file = NULL; | 1304 file = NULL; |
| 1300 if (!ret) | 1305 if (!ret) |
| 1301 return false; | 1306 return false; |
| 1302 | 1307 |
| 1303 index_ = new MappedFile(); | 1308 index_ = new MappedFile(); |
| 1304 data_ = reinterpret_cast<Index*>(index_->Init(index_name, 0)); | 1309 data_ = reinterpret_cast<Index*>(index_->Init(index_name, 0)); |
| 1305 if (!data_) { | 1310 if (!data_) { |
| 1306 LOG(ERROR) << "Unable to map Index file"; | 1311 LOG(ERROR) << "Unable to map Index file"; |
| 1307 return false; | 1312 return false; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 | 1350 |
| 1346 if (!table_len) | 1351 if (!table_len) |
| 1347 return; | 1352 return; |
| 1348 | 1353 |
| 1349 // If we already have a table, adjust the size to it. | 1354 // If we already have a table, adjust the size to it. |
| 1350 int current_max_size = MaxStorageSizeForTable(table_len); | 1355 int current_max_size = MaxStorageSizeForTable(table_len); |
| 1351 if (max_size_ > current_max_size) | 1356 if (max_size_ > current_max_size) |
| 1352 max_size_= current_max_size; | 1357 max_size_= current_max_size; |
| 1353 } | 1358 } |
| 1354 | 1359 |
| 1360 bool BackendImpl::InitStats() { |
| 1361 Addr address(data_->header.stats); |
| 1362 int size = stats_.StorageSize(); |
| 1363 |
| 1364 if (!address.is_initialized()) { |
| 1365 FileType file_type = Addr::RequiredFileType(size); |
| 1366 DCHECK_NE(file_type, EXTERNAL); |
| 1367 int num_blocks = Addr::RequiredBlocks(size, file_type); |
| 1368 |
| 1369 if (!CreateBlock(file_type, num_blocks, &address)) |
| 1370 return false; |
| 1371 |
| 1372 data_->header.stats = address.value(); |
| 1373 return stats_.Init(NULL, 0, address); |
| 1374 } |
| 1375 |
| 1376 if (!address.is_block_file()) { |
| 1377 NOTREACHED(); |
| 1378 return false; |
| 1379 } |
| 1380 |
| 1381 // Load the required data. |
| 1382 size = address.num_blocks() * address.BlockSize(); |
| 1383 MappedFile* file = File(address); |
| 1384 if (!file) |
| 1385 return false; |
| 1386 |
| 1387 scoped_ptr<char[]> data(new char[size]); |
| 1388 size_t offset = address.start_block() * address.BlockSize() + |
| 1389 kBlockHeaderSize; |
| 1390 if (!file->Read(data.get(), size, offset)) |
| 1391 return false; |
| 1392 |
| 1393 if (!stats_.Init(data.get(), size, address)) |
| 1394 return false; |
| 1395 if (cache_type_ == net::DISK_CACHE && ShouldReportAgain()) |
| 1396 stats_.InitSizeHistogram(); |
| 1397 return true; |
| 1398 } |
| 1399 |
| 1400 void BackendImpl::StoreStats() { |
| 1401 int size = stats_.StorageSize(); |
| 1402 scoped_ptr<char[]> data(new char[size]); |
| 1403 Addr address; |
| 1404 size = stats_.SerializeStats(data.get(), size, &address); |
| 1405 DCHECK(size); |
| 1406 if (!address.is_initialized()) |
| 1407 return; |
| 1408 |
| 1409 MappedFile* file = File(address); |
| 1410 if (!file) |
| 1411 return; |
| 1412 |
| 1413 size_t offset = address.start_block() * address.BlockSize() + |
| 1414 kBlockHeaderSize; |
| 1415 file->Write(data.get(), size, offset); // ignore result. |
| 1416 } |
| 1417 |
| 1355 void BackendImpl::RestartCache(bool failure) { | 1418 void BackendImpl::RestartCache(bool failure) { |
| 1356 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); | 1419 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); |
| 1357 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); | 1420 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); |
| 1358 int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); | 1421 int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); |
| 1359 int64 ga_evictions = stats_.GetCounter(Stats::GAJS_EVICTED); | |
| 1360 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); | 1422 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); |
| 1361 | 1423 |
| 1362 PrepareForRestart(); | 1424 PrepareForRestart(); |
| 1363 if (failure) { | 1425 if (failure) { |
| 1364 DCHECK(!num_refs_); | 1426 DCHECK(!num_refs_); |
| 1365 DCHECK(!open_entries_.size()); | 1427 DCHECK(!open_entries_.size()); |
| 1366 DelayedCacheCleanup(path_); | 1428 DelayedCacheCleanup(path_); |
| 1367 } else { | 1429 } else { |
| 1368 DeleteCache(path_, false); | 1430 DeleteCache(path_, false); |
| 1369 } | 1431 } |
| 1370 | 1432 |
| 1371 // Don't call Init() if directed by the unit test: we are simulating a failure | 1433 // Don't call Init() if directed by the unit test: we are simulating a failure |
| 1372 // trying to re-enable the cache. | 1434 // trying to re-enable the cache. |
| 1373 if (unit_test_) | 1435 if (unit_test_) |
| 1374 init_ = true; // Let the destructor do proper cleanup. | 1436 init_ = true; // Let the destructor do proper cleanup. |
| 1375 else if (SyncInit() == net::OK) { | 1437 else if (SyncInit() == net::OK) { |
| 1376 stats_.SetCounter(Stats::FATAL_ERROR, errors); | 1438 stats_.SetCounter(Stats::FATAL_ERROR, errors); |
| 1377 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); | 1439 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); |
| 1378 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); | 1440 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); |
| 1379 stats_.SetCounter(Stats::GAJS_EVICTED, ga_evictions); | |
| 1380 stats_.SetCounter(Stats::LAST_REPORT, last_report); | 1441 stats_.SetCounter(Stats::LAST_REPORT, last_report); |
| 1381 } | 1442 } |
| 1382 } | 1443 } |
| 1383 | 1444 |
| 1384 void BackendImpl::PrepareForRestart() { | 1445 void BackendImpl::PrepareForRestart() { |
| 1385 // Reset the mask_ if it was not given by the user. | 1446 // Reset the mask_ if it was not given by the user. |
| 1386 if (!(user_flags_ & kMask)) | 1447 if (!(user_flags_ & kMask)) |
| 1387 mask_ = 0; | 1448 mask_ = 0; |
| 1388 | 1449 |
| 1389 if (!(user_flags_ & kNewEviction)) | 1450 if (!(user_flags_ & kNewEviction)) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1405 if (it != open_entries_.end()) { | 1466 if (it != open_entries_.end()) { |
| 1406 // Easy job. This entry is already in memory. | 1467 // Easy job. This entry is already in memory. |
| 1407 EntryImpl* this_entry = it->second; | 1468 EntryImpl* this_entry = it->second; |
| 1408 this_entry->AddRef(); | 1469 this_entry->AddRef(); |
| 1409 *entry = this_entry; | 1470 *entry = this_entry; |
| 1410 return 0; | 1471 return 0; |
| 1411 } | 1472 } |
| 1412 | 1473 |
| 1413 STRESS_DCHECK(block_files_.IsValid(address)); | 1474 STRESS_DCHECK(block_files_.IsValid(address)); |
| 1414 | 1475 |
| 1415 if (!address.SanityCheckForEntry()) { | 1476 if (!address.SanityCheckForEntryV2()) { |
| 1416 LOG(WARNING) << "Wrong entry address."; | 1477 LOG(WARNING) << "Wrong entry address."; |
| 1417 STRESS_NOTREACHED(); | 1478 STRESS_NOTREACHED(); |
| 1418 return ERR_INVALID_ADDRESS; | 1479 return ERR_INVALID_ADDRESS; |
| 1419 } | 1480 } |
| 1420 | 1481 |
| 1421 scoped_refptr<EntryImpl> cache_entry( | 1482 scoped_refptr<EntryImpl> cache_entry( |
| 1422 new EntryImpl(this, address, read_only_)); | 1483 new EntryImpl(this, address, read_only_)); |
| 1423 IncreaseNumRefs(); | 1484 IncreaseNumRefs(); |
| 1424 *entry = NULL; | 1485 *entry = NULL; |
| 1425 | 1486 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 } | 1524 } |
| 1464 | 1525 |
| 1465 // Prevent overwriting the dirty flag on the destructor. | 1526 // Prevent overwriting the dirty flag on the destructor. |
| 1466 cache_entry->SetDirtyFlag(GetCurrentEntryId()); | 1527 cache_entry->SetDirtyFlag(GetCurrentEntryId()); |
| 1467 | 1528 |
| 1468 if (cache_entry->dirty()) { | 1529 if (cache_entry->dirty()) { |
| 1469 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), | 1530 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), |
| 1470 address.value()); | 1531 address.value()); |
| 1471 } | 1532 } |
| 1472 | 1533 |
| 1473 open_entries_[address.value()] = cache_entry; | 1534 open_entries_[address.value()] = cache_entry.get(); |
| 1474 | 1535 |
| 1475 cache_entry->BeginLogging(net_log_, false); | 1536 cache_entry->BeginLogging(net_log_, false); |
| 1476 cache_entry.swap(entry); | 1537 cache_entry.swap(entry); |
| 1477 return 0; | 1538 return 0; |
| 1478 } | 1539 } |
| 1479 | 1540 |
| 1480 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, | 1541 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, |
| 1481 bool find_parent, Addr entry_addr, | 1542 bool find_parent, Addr entry_addr, |
| 1482 bool* match_error) { | 1543 bool* match_error) { |
| 1483 Addr address(data_->table[hash & mask_]); | 1544 Addr address(data_->table[hash & mask_]); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 } else { | 1583 } else { |
| 1523 data_->table[hash & mask_] = child.value(); | 1584 data_->table[hash & mask_] = child.value(); |
| 1524 } | 1585 } |
| 1525 | 1586 |
| 1526 Trace("MatchEntry dirty %d 0x%x 0x%x", find_parent, entry_addr.value(), | 1587 Trace("MatchEntry dirty %d 0x%x 0x%x", find_parent, entry_addr.value(), |
| 1527 address.value()); | 1588 address.value()); |
| 1528 | 1589 |
| 1529 if (!error) { | 1590 if (!error) { |
| 1530 // It is important to call DestroyInvalidEntry after removing this | 1591 // It is important to call DestroyInvalidEntry after removing this |
| 1531 // entry from the table. | 1592 // entry from the table. |
| 1532 DestroyInvalidEntry(cache_entry); | 1593 DestroyInvalidEntry(cache_entry.get()); |
| 1533 cache_entry = NULL; | 1594 cache_entry = NULL; |
| 1534 } else { | 1595 } else { |
| 1535 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); | 1596 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); |
| 1536 } | 1597 } |
| 1537 | 1598 |
| 1538 // Restart the search. | 1599 // Restart the search. |
| 1539 address.set_value(data_->table[hash & mask_]); | 1600 address.set_value(data_->table[hash & mask_]); |
| 1540 visited.clear(); | 1601 visited.clear(); |
| 1541 continue; | 1602 continue; |
| 1542 } | 1603 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1772 num_refs_++; | 1833 num_refs_++; |
| 1773 if (max_refs_ < num_refs_) | 1834 if (max_refs_ < num_refs_) |
| 1774 max_refs_ = num_refs_; | 1835 max_refs_ = num_refs_; |
| 1775 } | 1836 } |
| 1776 | 1837 |
| 1777 void BackendImpl::DecreaseNumRefs() { | 1838 void BackendImpl::DecreaseNumRefs() { |
| 1778 DCHECK(num_refs_); | 1839 DCHECK(num_refs_); |
| 1779 num_refs_--; | 1840 num_refs_--; |
| 1780 | 1841 |
| 1781 if (!num_refs_ && disabled_) | 1842 if (!num_refs_ && disabled_) |
| 1782 MessageLoop::current()->PostTask(FROM_HERE, | 1843 base::MessageLoop::current()->PostTask( |
| 1783 base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); | 1844 FROM_HERE, base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); |
| 1784 } | 1845 } |
| 1785 | 1846 |
| 1786 void BackendImpl::IncreaseNumEntries() { | 1847 void BackendImpl::IncreaseNumEntries() { |
| 1787 data_->header.num_entries++; | 1848 data_->header.num_entries++; |
| 1788 DCHECK_GT(data_->header.num_entries, 0); | 1849 DCHECK_GT(data_->header.num_entries, 0); |
| 1789 } | 1850 } |
| 1790 | 1851 |
| 1791 void BackendImpl::DecreaseNumEntries() { | 1852 void BackendImpl::DecreaseNumEntries() { |
| 1792 data_->header.num_entries--; | 1853 data_->header.num_entries--; |
| 1793 if (data_->header.num_entries < 0) { | 1854 if (data_->header.num_entries < 0) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0, | 1888 CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0, |
| 1828 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); | 1889 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); |
| 1829 stats_.SetCounter(Stats::MAX_ENTRIES, 0); | 1890 stats_.SetCounter(Stats::MAX_ENTRIES, 0); |
| 1830 | 1891 |
| 1831 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, | 1892 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, |
| 1832 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); | 1893 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); |
| 1833 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, | 1894 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, |
| 1834 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); | 1895 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); |
| 1835 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, | 1896 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, |
| 1836 static_cast<int>(stats_.GetCounter(Stats::DOOM_RECENT))); | 1897 static_cast<int>(stats_.GetCounter(Stats::DOOM_RECENT))); |
| 1837 CACHE_UMA(COUNTS_10000, "TotalEvictionsGaJs", 0, | |
| 1838 static_cast<int>(stats_.GetCounter(Stats::GAJS_EVICTED))); | |
| 1839 stats_.SetCounter(Stats::FATAL_ERROR, 0); | 1898 stats_.SetCounter(Stats::FATAL_ERROR, 0); |
| 1840 stats_.SetCounter(Stats::DOOM_CACHE, 0); | 1899 stats_.SetCounter(Stats::DOOM_CACHE, 0); |
| 1841 stats_.SetCounter(Stats::DOOM_RECENT, 0); | 1900 stats_.SetCounter(Stats::DOOM_RECENT, 0); |
| 1842 stats_.SetCounter(Stats::GAJS_EVICTED, 0); | |
| 1843 | 1901 |
| 1844 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; | 1902 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; |
| 1845 if (!data_->header.create_time || !data_->header.lru.filled) { | 1903 if (!data_->header.create_time || !data_->header.lru.filled) { |
| 1846 int cause = data_->header.create_time ? 0 : 1; | 1904 int cause = data_->header.create_time ? 0 : 1; |
| 1847 if (!data_->header.lru.filled) | 1905 if (!data_->header.lru.filled) |
| 1848 cause |= 2; | 1906 cause |= 2; |
| 1849 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); | 1907 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); |
| 1850 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); | 1908 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); |
| 1851 return; | 1909 return; |
| 1852 } | 1910 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2054 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2112 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
| 2055 total_memory = kMaxBuffersSize; | 2113 total_memory = kMaxBuffersSize; |
| 2056 | 2114 |
| 2057 done = true; | 2115 done = true; |
| 2058 } | 2116 } |
| 2059 | 2117 |
| 2060 return static_cast<int>(total_memory); | 2118 return static_cast<int>(total_memory); |
| 2061 } | 2119 } |
| 2062 | 2120 |
| 2063 } // namespace disk_cache | 2121 } // namespace disk_cache |
| OLD | NEW |