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 return stats_.Init(NULL, 0, address); |
| 1372 } |
| 1373 |
| 1374 if (!address.is_block_file()) { |
| 1375 NOTREACHED(); |
| 1376 return false; |
| 1377 } |
| 1378 |
| 1379 // Load the required data. |
| 1380 size = address.num_blocks() * address.BlockSize(); |
| 1381 MappedFile* file = File(address); |
| 1382 if (!file) |
| 1383 return false; |
| 1384 |
| 1385 scoped_ptr<char[]> data(new char[size]); |
| 1386 size_t offset = address.start_block() * address.BlockSize() + |
| 1387 kBlockHeaderSize; |
| 1388 if (!file->Read(data.get(), size, offset)) |
| 1389 return false; |
| 1390 |
| 1391 if (!stats_.Init(data.get(), size, address)) |
| 1392 return false; |
| 1393 if (cache_type_ == net::DISK_CACHE && ShouldReportAgain()) |
| 1394 stats_.InitSizeHistogram(); |
| 1395 return true; |
| 1396 } |
| 1397 |
| 1398 void BackendImpl::StoreStats() { |
| 1399 int size = stats_.StorageSize(); |
| 1400 scoped_ptr<char[]> data(new char[size]); |
| 1401 Addr address; |
| 1402 size = stats_.SerializeStats(data.get(), size, &address); |
| 1403 DCHECK(size); |
| 1404 if (!address.is_initialized()) |
| 1405 return; |
| 1406 |
| 1407 MappedFile* file = File(address); |
| 1408 if (!file) |
| 1409 return; |
| 1410 |
| 1411 size_t offset = address.start_block() * address.BlockSize() + |
| 1412 kBlockHeaderSize; |
| 1413 file->Write(data.get(), size, offset); // ignore result. |
| 1414 } |
| 1415 |
1355 void BackendImpl::RestartCache(bool failure) { | 1416 void BackendImpl::RestartCache(bool failure) { |
1356 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); | 1417 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); |
1357 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); | 1418 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); |
1358 int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); | 1419 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); | 1420 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); |
1361 | 1421 |
1362 PrepareForRestart(); | 1422 PrepareForRestart(); |
1363 if (failure) { | 1423 if (failure) { |
1364 DCHECK(!num_refs_); | 1424 DCHECK(!num_refs_); |
1365 DCHECK(!open_entries_.size()); | 1425 DCHECK(!open_entries_.size()); |
1366 DelayedCacheCleanup(path_); | 1426 DelayedCacheCleanup(path_); |
1367 } else { | 1427 } else { |
1368 DeleteCache(path_, false); | 1428 DeleteCache(path_, false); |
1369 } | 1429 } |
1370 | 1430 |
1371 // Don't call Init() if directed by the unit test: we are simulating a failure | 1431 // Don't call Init() if directed by the unit test: we are simulating a failure |
1372 // trying to re-enable the cache. | 1432 // trying to re-enable the cache. |
1373 if (unit_test_) | 1433 if (unit_test_) |
1374 init_ = true; // Let the destructor do proper cleanup. | 1434 init_ = true; // Let the destructor do proper cleanup. |
1375 else if (SyncInit() == net::OK) { | 1435 else if (SyncInit() == net::OK) { |
1376 stats_.SetCounter(Stats::FATAL_ERROR, errors); | 1436 stats_.SetCounter(Stats::FATAL_ERROR, errors); |
1377 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); | 1437 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); |
1378 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); | 1438 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); |
1379 stats_.SetCounter(Stats::GAJS_EVICTED, ga_evictions); | |
1380 stats_.SetCounter(Stats::LAST_REPORT, last_report); | 1439 stats_.SetCounter(Stats::LAST_REPORT, last_report); |
1381 } | 1440 } |
1382 } | 1441 } |
1383 | 1442 |
1384 void BackendImpl::PrepareForRestart() { | 1443 void BackendImpl::PrepareForRestart() { |
1385 // Reset the mask_ if it was not given by the user. | 1444 // Reset the mask_ if it was not given by the user. |
1386 if (!(user_flags_ & kMask)) | 1445 if (!(user_flags_ & kMask)) |
1387 mask_ = 0; | 1446 mask_ = 0; |
1388 | 1447 |
1389 if (!(user_flags_ & kNewEviction)) | 1448 if (!(user_flags_ & kNewEviction)) |
(...skipping 15 matching lines...) Expand all Loading... |
1405 if (it != open_entries_.end()) { | 1464 if (it != open_entries_.end()) { |
1406 // Easy job. This entry is already in memory. | 1465 // Easy job. This entry is already in memory. |
1407 EntryImpl* this_entry = it->second; | 1466 EntryImpl* this_entry = it->second; |
1408 this_entry->AddRef(); | 1467 this_entry->AddRef(); |
1409 *entry = this_entry; | 1468 *entry = this_entry; |
1410 return 0; | 1469 return 0; |
1411 } | 1470 } |
1412 | 1471 |
1413 STRESS_DCHECK(block_files_.IsValid(address)); | 1472 STRESS_DCHECK(block_files_.IsValid(address)); |
1414 | 1473 |
1415 if (!address.SanityCheckForEntry()) { | 1474 if (!address.SanityCheckForEntryV2()) { |
1416 LOG(WARNING) << "Wrong entry address."; | 1475 LOG(WARNING) << "Wrong entry address."; |
1417 STRESS_NOTREACHED(); | 1476 STRESS_NOTREACHED(); |
1418 return ERR_INVALID_ADDRESS; | 1477 return ERR_INVALID_ADDRESS; |
1419 } | 1478 } |
1420 | 1479 |
1421 scoped_refptr<EntryImpl> cache_entry( | 1480 scoped_refptr<EntryImpl> cache_entry( |
1422 new EntryImpl(this, address, read_only_)); | 1481 new EntryImpl(this, address, read_only_)); |
1423 IncreaseNumRefs(); | 1482 IncreaseNumRefs(); |
1424 *entry = NULL; | 1483 *entry = NULL; |
1425 | 1484 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 } | 1522 } |
1464 | 1523 |
1465 // Prevent overwriting the dirty flag on the destructor. | 1524 // Prevent overwriting the dirty flag on the destructor. |
1466 cache_entry->SetDirtyFlag(GetCurrentEntryId()); | 1525 cache_entry->SetDirtyFlag(GetCurrentEntryId()); |
1467 | 1526 |
1468 if (cache_entry->dirty()) { | 1527 if (cache_entry->dirty()) { |
1469 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), | 1528 Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), |
1470 address.value()); | 1529 address.value()); |
1471 } | 1530 } |
1472 | 1531 |
1473 open_entries_[address.value()] = cache_entry; | 1532 open_entries_[address.value()] = cache_entry.get(); |
1474 | 1533 |
1475 cache_entry->BeginLogging(net_log_, false); | 1534 cache_entry->BeginLogging(net_log_, false); |
1476 cache_entry.swap(entry); | 1535 cache_entry.swap(entry); |
1477 return 0; | 1536 return 0; |
1478 } | 1537 } |
1479 | 1538 |
1480 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, | 1539 EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, |
1481 bool find_parent, Addr entry_addr, | 1540 bool find_parent, Addr entry_addr, |
1482 bool* match_error) { | 1541 bool* match_error) { |
1483 Addr address(data_->table[hash & mask_]); | 1542 Addr address(data_->table[hash & mask_]); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 } else { | 1581 } else { |
1523 data_->table[hash & mask_] = child.value(); | 1582 data_->table[hash & mask_] = child.value(); |
1524 } | 1583 } |
1525 | 1584 |
1526 Trace("MatchEntry dirty %d 0x%x 0x%x", find_parent, entry_addr.value(), | 1585 Trace("MatchEntry dirty %d 0x%x 0x%x", find_parent, entry_addr.value(), |
1527 address.value()); | 1586 address.value()); |
1528 | 1587 |
1529 if (!error) { | 1588 if (!error) { |
1530 // It is important to call DestroyInvalidEntry after removing this | 1589 // It is important to call DestroyInvalidEntry after removing this |
1531 // entry from the table. | 1590 // entry from the table. |
1532 DestroyInvalidEntry(cache_entry); | 1591 DestroyInvalidEntry(cache_entry.get()); |
1533 cache_entry = NULL; | 1592 cache_entry = NULL; |
1534 } else { | 1593 } else { |
1535 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); | 1594 Trace("NewEntry failed on MatchEntry 0x%x", address.value()); |
1536 } | 1595 } |
1537 | 1596 |
1538 // Restart the search. | 1597 // Restart the search. |
1539 address.set_value(data_->table[hash & mask_]); | 1598 address.set_value(data_->table[hash & mask_]); |
1540 visited.clear(); | 1599 visited.clear(); |
1541 continue; | 1600 continue; |
1542 } | 1601 } |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 num_refs_++; | 1831 num_refs_++; |
1773 if (max_refs_ < num_refs_) | 1832 if (max_refs_ < num_refs_) |
1774 max_refs_ = num_refs_; | 1833 max_refs_ = num_refs_; |
1775 } | 1834 } |
1776 | 1835 |
1777 void BackendImpl::DecreaseNumRefs() { | 1836 void BackendImpl::DecreaseNumRefs() { |
1778 DCHECK(num_refs_); | 1837 DCHECK(num_refs_); |
1779 num_refs_--; | 1838 num_refs_--; |
1780 | 1839 |
1781 if (!num_refs_ && disabled_) | 1840 if (!num_refs_ && disabled_) |
1782 MessageLoop::current()->PostTask(FROM_HERE, | 1841 base::MessageLoop::current()->PostTask( |
1783 base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); | 1842 FROM_HERE, base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); |
1784 } | 1843 } |
1785 | 1844 |
1786 void BackendImpl::IncreaseNumEntries() { | 1845 void BackendImpl::IncreaseNumEntries() { |
1787 data_->header.num_entries++; | 1846 data_->header.num_entries++; |
1788 DCHECK_GT(data_->header.num_entries, 0); | 1847 DCHECK_GT(data_->header.num_entries, 0); |
1789 } | 1848 } |
1790 | 1849 |
1791 void BackendImpl::DecreaseNumEntries() { | 1850 void BackendImpl::DecreaseNumEntries() { |
1792 data_->header.num_entries--; | 1851 data_->header.num_entries--; |
1793 if (data_->header.num_entries < 0) { | 1852 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, | 1886 CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0, |
1828 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); | 1887 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); |
1829 stats_.SetCounter(Stats::MAX_ENTRIES, 0); | 1888 stats_.SetCounter(Stats::MAX_ENTRIES, 0); |
1830 | 1889 |
1831 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, | 1890 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, |
1832 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); | 1891 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); |
1833 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, | 1892 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, |
1834 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); | 1893 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); |
1835 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, | 1894 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, |
1836 static_cast<int>(stats_.GetCounter(Stats::DOOM_RECENT))); | 1895 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); | 1896 stats_.SetCounter(Stats::FATAL_ERROR, 0); |
1840 stats_.SetCounter(Stats::DOOM_CACHE, 0); | 1897 stats_.SetCounter(Stats::DOOM_CACHE, 0); |
1841 stats_.SetCounter(Stats::DOOM_RECENT, 0); | 1898 stats_.SetCounter(Stats::DOOM_RECENT, 0); |
1842 stats_.SetCounter(Stats::GAJS_EVICTED, 0); | |
1843 | 1899 |
1844 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; | 1900 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; |
1845 if (!data_->header.create_time || !data_->header.lru.filled) { | 1901 if (!data_->header.create_time || !data_->header.lru.filled) { |
1846 int cause = data_->header.create_time ? 0 : 1; | 1902 int cause = data_->header.create_time ? 0 : 1; |
1847 if (!data_->header.lru.filled) | 1903 if (!data_->header.lru.filled) |
1848 cause |= 2; | 1904 cause |= 2; |
1849 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); | 1905 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); |
1850 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); | 1906 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); |
1851 return; | 1907 return; |
1852 } | 1908 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2054 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2110 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
2055 total_memory = kMaxBuffersSize; | 2111 total_memory = kMaxBuffersSize; |
2056 | 2112 |
2057 done = true; | 2113 done = true; |
2058 } | 2114 } |
2059 | 2115 |
2060 return static_cast<int>(total_memory); | 2116 return static_cast<int>(total_memory); |
2061 } | 2117 } |
2062 | 2118 |
2063 } // namespace disk_cache | 2119 } // namespace disk_cache |
OLD | NEW |