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 650 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1345 | 1346 |
1346 if (!table_len) | 1347 if (!table_len) |
1347 return; | 1348 return; |
1348 | 1349 |
1349 // If we already have a table, adjust the size to it. | 1350 // If we already have a table, adjust the size to it. |
1350 int current_max_size = MaxStorageSizeForTable(table_len); | 1351 int current_max_size = MaxStorageSizeForTable(table_len); |
1351 if (max_size_ > current_max_size) | 1352 if (max_size_ > current_max_size) |
1352 max_size_= current_max_size; | 1353 max_size_= current_max_size; |
1353 } | 1354 } |
1354 | 1355 |
| 1356 bool BackendImpl::InitStats() { |
| 1357 Addr address(data_->header.stats); |
| 1358 int size = stats_.StorageSize(); |
| 1359 |
| 1360 if (!address.is_initialized()) { |
| 1361 FileType file_type = Addr::RequiredFileType(size); |
| 1362 DCHECK_NE(file_type, EXTERNAL); |
| 1363 int num_blocks = Addr::RequiredBlocks(size, file_type); |
| 1364 |
| 1365 if (!CreateBlock(file_type, num_blocks, &address)) |
| 1366 return false; |
| 1367 return stats_.Init(NULL, 0, address); |
| 1368 } |
| 1369 |
| 1370 if (!address.is_block_file()) { |
| 1371 NOTREACHED(); |
| 1372 return false; |
| 1373 } |
| 1374 |
| 1375 // Load the required data. |
| 1376 size = address.num_blocks() * address.BlockSize(); |
| 1377 MappedFile* file = File(address); |
| 1378 if (!file) |
| 1379 return false; |
| 1380 |
| 1381 scoped_ptr<char[]> data(new char[size]); |
| 1382 size_t offset = address.start_block() * address.BlockSize() + |
| 1383 kBlockHeaderSize; |
| 1384 if (!file->Read(data.get(), size, offset)) |
| 1385 return false; |
| 1386 |
| 1387 if (!stats_.Init(data.get(), size, address)) |
| 1388 return false; |
| 1389 if (cache_type_ == net::DISK_CACHE && ShouldReportAgain()) |
| 1390 stats_.InitSizeHistogram(); |
| 1391 return true; |
| 1392 } |
| 1393 |
| 1394 void BackendImpl::StoreStats() { |
| 1395 int size = stats_.StorageSize(); |
| 1396 scoped_ptr<char[]> data(new char[size]); |
| 1397 Addr address; |
| 1398 size = stats_.SerializeStats(data.get(), size, &address); |
| 1399 DCHECK(size); |
| 1400 if (!address.is_initialized()) |
| 1401 return; |
| 1402 |
| 1403 MappedFile* file = File(address); |
| 1404 if (!file) |
| 1405 return; |
| 1406 |
| 1407 size_t offset = address.start_block() * address.BlockSize() + |
| 1408 kBlockHeaderSize; |
| 1409 file->Write(data.get(), size, offset); // ignore result. |
| 1410 } |
| 1411 |
1355 void BackendImpl::RestartCache(bool failure) { | 1412 void BackendImpl::RestartCache(bool failure) { |
1356 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); | 1413 int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); |
1357 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); | 1414 int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); |
1358 int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); | 1415 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); | 1416 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); |
1361 | 1417 |
1362 PrepareForRestart(); | 1418 PrepareForRestart(); |
1363 if (failure) { | 1419 if (failure) { |
1364 DCHECK(!num_refs_); | 1420 DCHECK(!num_refs_); |
1365 DCHECK(!open_entries_.size()); | 1421 DCHECK(!open_entries_.size()); |
1366 DelayedCacheCleanup(path_); | 1422 DelayedCacheCleanup(path_); |
1367 } else { | 1423 } else { |
1368 DeleteCache(path_, false); | 1424 DeleteCache(path_, false); |
1369 } | 1425 } |
1370 | 1426 |
1371 // Don't call Init() if directed by the unit test: we are simulating a failure | 1427 // Don't call Init() if directed by the unit test: we are simulating a failure |
1372 // trying to re-enable the cache. | 1428 // trying to re-enable the cache. |
1373 if (unit_test_) | 1429 if (unit_test_) |
1374 init_ = true; // Let the destructor do proper cleanup. | 1430 init_ = true; // Let the destructor do proper cleanup. |
1375 else if (SyncInit() == net::OK) { | 1431 else if (SyncInit() == net::OK) { |
1376 stats_.SetCounter(Stats::FATAL_ERROR, errors); | 1432 stats_.SetCounter(Stats::FATAL_ERROR, errors); |
1377 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); | 1433 stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); |
1378 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); | 1434 stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); |
1379 stats_.SetCounter(Stats::GAJS_EVICTED, ga_evictions); | |
1380 stats_.SetCounter(Stats::LAST_REPORT, last_report); | 1435 stats_.SetCounter(Stats::LAST_REPORT, last_report); |
1381 } | 1436 } |
1382 } | 1437 } |
1383 | 1438 |
1384 void BackendImpl::PrepareForRestart() { | 1439 void BackendImpl::PrepareForRestart() { |
1385 // Reset the mask_ if it was not given by the user. | 1440 // Reset the mask_ if it was not given by the user. |
1386 if (!(user_flags_ & kMask)) | 1441 if (!(user_flags_ & kMask)) |
1387 mask_ = 0; | 1442 mask_ = 0; |
1388 | 1443 |
1389 if (!(user_flags_ & kNewEviction)) | 1444 if (!(user_flags_ & kNewEviction)) |
(...skipping 15 matching lines...) Expand all Loading... |
1405 if (it != open_entries_.end()) { | 1460 if (it != open_entries_.end()) { |
1406 // Easy job. This entry is already in memory. | 1461 // Easy job. This entry is already in memory. |
1407 EntryImpl* this_entry = it->second; | 1462 EntryImpl* this_entry = it->second; |
1408 this_entry->AddRef(); | 1463 this_entry->AddRef(); |
1409 *entry = this_entry; | 1464 *entry = this_entry; |
1410 return 0; | 1465 return 0; |
1411 } | 1466 } |
1412 | 1467 |
1413 STRESS_DCHECK(block_files_.IsValid(address)); | 1468 STRESS_DCHECK(block_files_.IsValid(address)); |
1414 | 1469 |
1415 if (!address.SanityCheckForEntry()) { | 1470 if (!address.SanityCheckForEntryV2()) { |
1416 LOG(WARNING) << "Wrong entry address."; | 1471 LOG(WARNING) << "Wrong entry address."; |
1417 STRESS_NOTREACHED(); | 1472 STRESS_NOTREACHED(); |
1418 return ERR_INVALID_ADDRESS; | 1473 return ERR_INVALID_ADDRESS; |
1419 } | 1474 } |
1420 | 1475 |
1421 scoped_refptr<EntryImpl> cache_entry( | 1476 scoped_refptr<EntryImpl> cache_entry( |
1422 new EntryImpl(this, address, read_only_)); | 1477 new EntryImpl(this, address, read_only_)); |
1423 IncreaseNumRefs(); | 1478 IncreaseNumRefs(); |
1424 *entry = NULL; | 1479 *entry = NULL; |
1425 | 1480 |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 num_refs_++; | 1827 num_refs_++; |
1773 if (max_refs_ < num_refs_) | 1828 if (max_refs_ < num_refs_) |
1774 max_refs_ = num_refs_; | 1829 max_refs_ = num_refs_; |
1775 } | 1830 } |
1776 | 1831 |
1777 void BackendImpl::DecreaseNumRefs() { | 1832 void BackendImpl::DecreaseNumRefs() { |
1778 DCHECK(num_refs_); | 1833 DCHECK(num_refs_); |
1779 num_refs_--; | 1834 num_refs_--; |
1780 | 1835 |
1781 if (!num_refs_ && disabled_) | 1836 if (!num_refs_ && disabled_) |
1782 MessageLoop::current()->PostTask(FROM_HERE, | 1837 base::MessageLoop::current()->PostTask( |
1783 base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); | 1838 FROM_HERE, base::Bind(&BackendImpl::RestartCache, GetWeakPtr(), true)); |
1784 } | 1839 } |
1785 | 1840 |
1786 void BackendImpl::IncreaseNumEntries() { | 1841 void BackendImpl::IncreaseNumEntries() { |
1787 data_->header.num_entries++; | 1842 data_->header.num_entries++; |
1788 DCHECK_GT(data_->header.num_entries, 0); | 1843 DCHECK_GT(data_->header.num_entries, 0); |
1789 } | 1844 } |
1790 | 1845 |
1791 void BackendImpl::DecreaseNumEntries() { | 1846 void BackendImpl::DecreaseNumEntries() { |
1792 data_->header.num_entries--; | 1847 data_->header.num_entries--; |
1793 if (data_->header.num_entries < 0) { | 1848 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, | 1882 CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0, |
1828 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); | 1883 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); |
1829 stats_.SetCounter(Stats::MAX_ENTRIES, 0); | 1884 stats_.SetCounter(Stats::MAX_ENTRIES, 0); |
1830 | 1885 |
1831 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, | 1886 CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, |
1832 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); | 1887 static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); |
1833 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, | 1888 CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, |
1834 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); | 1889 static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); |
1835 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, | 1890 CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, |
1836 static_cast<int>(stats_.GetCounter(Stats::DOOM_RECENT))); | 1891 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); | 1892 stats_.SetCounter(Stats::FATAL_ERROR, 0); |
1840 stats_.SetCounter(Stats::DOOM_CACHE, 0); | 1893 stats_.SetCounter(Stats::DOOM_CACHE, 0); |
1841 stats_.SetCounter(Stats::DOOM_RECENT, 0); | 1894 stats_.SetCounter(Stats::DOOM_RECENT, 0); |
1842 stats_.SetCounter(Stats::GAJS_EVICTED, 0); | |
1843 | 1895 |
1844 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; | 1896 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; |
1845 if (!data_->header.create_time || !data_->header.lru.filled) { | 1897 if (!data_->header.create_time || !data_->header.lru.filled) { |
1846 int cause = data_->header.create_time ? 0 : 1; | 1898 int cause = data_->header.create_time ? 0 : 1; |
1847 if (!data_->header.lru.filled) | 1899 if (!data_->header.lru.filled) |
1848 cause |= 2; | 1900 cause |= 2; |
1849 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); | 1901 CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); |
1850 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); | 1902 CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); |
1851 return; | 1903 return; |
1852 } | 1904 } |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2054 if (total_memory > kMaxBuffersSize || total_memory <= 0) | 2106 if (total_memory > kMaxBuffersSize || total_memory <= 0) |
2055 total_memory = kMaxBuffersSize; | 2107 total_memory = kMaxBuffersSize; |
2056 | 2108 |
2057 done = true; | 2109 done = true; |
2058 } | 2110 } |
2059 | 2111 |
2060 return static_cast<int>(total_memory); | 2112 return static_cast<int>(total_memory); |
2061 } | 2113 } |
2062 | 2114 |
2063 } // namespace disk_cache | 2115 } // namespace disk_cache |
OLD | NEW |