backend_impl.cc revision 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801
1731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/backend_impl.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/field_trial.h" 11731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/rand_util.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/sys_info.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/worker_pool.h" 173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/time.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/timer.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/net_errors.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/cache_util.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/entry_impl.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/errors.h" 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/disk_cache/experiments.h" 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/file.h" 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/disk_cache/hash.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/disk_cache/mem_backend_impl.h" 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This has to be defined before including histogram_macros.h from this file. 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_DISK_CACHE_BACKEND_IMPL_CC_ 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/histogram_macros.h" 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Time; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeDelta; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeTicks; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char* kIndexName = "index"; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kMaxOldFolders = 100; 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Seems like ~240 MB correspond to less than 50k entries for 99% of the people. 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Note that the actual target is to keep the index table load factor under 55% 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// for most users. 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int k64kEntriesStore = 240 * 1000 * 1000; 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kBaseTableLen = 64 * 1024; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kDefaultCacheSize = 80 * 1024 * 1024; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint DesiredIndexTableLen(int32 storage_size) { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (storage_size <= k64kEntriesStore) 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kBaseTableLen; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (storage_size <= k64kEntriesStore * 2) 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kBaseTableLen * 2; 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (storage_size <= k64kEntriesStore * 4) 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kBaseTableLen * 4; 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (storage_size <= k64kEntriesStore * 8) 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kBaseTableLen * 8; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The biggest storage_size for int32 requires a 4 MB table. 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kBaseTableLen * 16; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint MaxStorageSizeForTable(int table_len) { 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return table_len * (k64kEntriesStore / kBaseTableLen); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottsize_t GetIndexSize(int table_len) { 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t table_size = sizeof(disk_cache::CacheAddr) * table_len; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return sizeof(disk_cache::IndexHeader) + table_size; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ------------------------------------------------------------------------ 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns a fully qualified name from path and name, using a given name prefix 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and index number. For instance, if the arguments are "/foo", "bar" and 5, it 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// will return "/foo/old_bar_005". 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFilePath GetPrefixedName(const FilePath& path, const std::string& name, 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int index) { 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string tmp = base::StringPrintf("%s%s_%03d", "old_", 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name.c_str(), index); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return path.AppendASCII(tmp); 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is a simple Task to cleanup old caches. 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass CleanupTask : public Task { 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CleanupTask(const FilePath& path, const std::string& name) 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : path_(path), name_(name) {} 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Run(); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path_; 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string name_; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(CleanupTask); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CleanupTask::Run() { 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxOldFolders; i++) { 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath to_delete = GetPrefixedName(path_, name_, i); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::DeleteCache(to_delete, true); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns a full path to rename the current cache, in order to delete it. path 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is the current folder location, and name is the current folder name. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFilePath GetTempCacheName(const FilePath& path, const std::string& name) { 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We'll attempt to have up to kMaxOldFolders folders for deletion. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxOldFolders; i++) { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath to_delete = GetPrefixedName(path, name, i); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file_util::PathExists(to_delete)) 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return to_delete; 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FilePath(); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Moves the cache files to a new folder and creates a task to delete them. 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool DelayedCacheCleanup(const FilePath& full_path) { 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // GetTempCacheName() and MoveCache() use synchronous file 120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // operations. 121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::ScopedAllowIO allow_io; 122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath current_path = full_path.StripTrailingSeparators(); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = current_path.DirName(); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath name = current_path.BaseName(); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_POSIX) 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string name_str = name.value(); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#elif defined(OS_WIN) 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We created this file so it should only contain ASCII. 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string name_str = WideToASCII(name.value()); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath to_delete = GetTempCacheName(path, name_str); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (to_delete.empty()) { 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Unable to get another cache folder"; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!disk_cache::MoveCache(full_path, to_delete)) { 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Unable to move cache folder"; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::WorkerPool::PostTask(FROM_HERE, new CleanupTask(path, name_str), true); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Sets group for the current experiment. Returns false if the files should be 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// discarded. 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool InitExperiment(disk_cache::IndexHeader* header) { 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (header->experiment == disk_cache::EXPERIMENT_OLD_FILE1 || 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick header->experiment == disk_cache::EXPERIMENT_OLD_FILE2) { 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Discard current cache. 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // See if we already defined the group for this profile. 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (header->experiment >= disk_cache::EXPERIMENT_DELETED_LIST_OUT) 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The experiment is closed. 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick header->experiment = disk_cache::EXPERIMENT_DELETED_LIST_OUT; 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Initializes the field trial structures to allow performance measurements 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// for the current cache configuration. Returns true if we are active part of 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the CacheThrottle field trial. 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool SetFieldTrialInfo(int size_group) { 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool first = true; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!first) 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Field trials involve static objects so we have to do this only once. 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first = false; 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string group1 = base::StringPrintf("CacheSizeGroup_%d", size_group); 17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int totalProbability = 10; 17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_refptr<base::FieldTrial> trial1( 18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new base::FieldTrial("CacheSize", totalProbability, group1, 2011, 6, 30)); 18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen trial1->AppendGroup(group1, totalProbability); 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // After June 30, 2011 builds, it will always be in default group. 18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_refptr<base::FieldTrial> trial2( 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new base::FieldTrial( 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen "CacheThrottle", 100, "CacheThrottle_Default", 2011, 6, 30)); 18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int group2a = trial2->AppendGroup("CacheThrottle_On", 10); // 10 % in. 18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen trial2->AppendGroup("CacheThrottle_Off", 10); // 10 % control. 18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return trial2->group() == group2a; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------ 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class takes care of building an instance of the backend. 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass CacheCreator { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CacheCreator(const FilePath& path, bool force, int max_bytes, 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CacheType type, uint32 flags, 2003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::MessageLoopProxy* thread, net::NetLog* net_log, 2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen disk_cache::Backend** backend, 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallback* callback) 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : path_(path), force_(force), retry_(false), max_bytes_(max_bytes), 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type_(type), flags_(flags), thread_(thread), backend_(backend), 2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen callback_(callback), cache_(NULL), net_log_(net_log), 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch my_callback_(this, &CacheCreator::OnIOComplete)) { 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~CacheCreator() {} 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Creates the backend. 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int Run(); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Callback implementation. 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void OnIOComplete(int result); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoCallback(int result); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const FilePath& path_; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool force_; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool retry_; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int max_bytes_; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CacheType type_; 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uint32 flags_; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<base::MessageLoopProxy> thread_; 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disk_cache::Backend** backend_; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallback* callback_; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disk_cache::BackendImpl* cache_; 2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::NetLog* net_log_; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallbackImpl<CacheCreator> my_callback_; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(CacheCreator); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CacheCreator::Run() { 2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen cache_ = new disk_cache::BackendImpl(path_, thread_, net_log_); 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_->SetMaxSize(max_bytes_); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_->SetType(type_); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_->SetFlags(flags_); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = cache_->Init(&my_callback_); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(net::ERR_IO_PENDING, rv); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rv; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CacheCreator::OnIOComplete(int result) { 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == net::OK || !force_ || retry_) 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return DoCallback(result); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a failure and we are supposed to try again, so delete the object, 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // delete all the files, and try again. 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch retry_ = true; 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete cache_; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_ = NULL; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!DelayedCacheCleanup(path_)) 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return DoCallback(result); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The worker thread will start deleting files soon, but the original folder 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is not there anymore... let's create a new set of files. 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = Run(); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(net::ERR_IO_PENDING, rv); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CacheCreator::DoCallback(int result) { 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_NE(net::ERR_IO_PENDING, result); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result == net::OK) { 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *backend_ = cache_; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Unable to create cache"; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *backend_ = NULL; 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete cache_; 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch callback_->Run(result); 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete this; 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ------------------------------------------------------------------------ 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A task to perform final cleanup on the background thread. 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FinalCleanup : public Task { 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit FinalCleanup(disk_cache::BackendImpl* backend) : backend_(backend) {} 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~FinalCleanup() {} 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Run(); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disk_cache::BackendImpl* backend_; 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_EVIL_CONSTRUCTORS(FinalCleanup); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid FinalCleanup::Run() { 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick backend_->CleanupCache(); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ------------------------------------------------------------------------ 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint CreateCacheBackend(net::CacheType type, const FilePath& path, int max_bytes, 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool force, base::MessageLoopProxy* thread, 3033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::NetLog* net_log, Backend** backend, 3043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(callback); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == net::MEMORY_CACHE) { 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *backend = MemBackendImpl::CreateBackend(max_bytes); 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *backend ? net::OK : net::ERR_FAILED; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(thread); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return BackendImpl::CreateBackend(path, force, max_bytes, type, kNone, thread, 3133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net_log, backend, callback); 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the preferred maximum number of bytes for the cache given the 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// number of available bytes. 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint PreferedCacheSize(int64 available) { 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return 80% of the available space if there is not enough space to use 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // kDefaultCacheSize. 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (available < kDefaultCacheSize * 10 / 8) 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<int32>(available * 8 / 10); 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return kDefaultCacheSize if it uses 80% to 10% of the available space. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (available < kDefaultCacheSize * 10) 326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kDefaultCacheSize; 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return 10% of the available space if the target size 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (2.5 * kDefaultCacheSize) is more than 10%. 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (available < static_cast<int64>(kDefaultCacheSize) * 25) 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<int32>(available / 10); 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return the target size (2.5 * kDefaultCacheSize) if it uses 10% to 1% 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of the available space. 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (available < static_cast<int64>(kDefaultCacheSize) * 250) 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return kDefaultCacheSize * 5 / 2; 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Return 1% of the available space if it does not exceed kint32max. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (available < static_cast<int64>(kint32max) * 100) 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<int32>(available / 100); 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return kint32max; 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ------------------------------------------------------------------------ 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBackendImpl::BackendImpl(const FilePath& path, 3483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::MessageLoopProxy* cache_thread, 3493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::NetLog* net_log) 3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : ALLOW_THIS_IN_INITIALIZER_LIST(background_queue_(this, cache_thread)), 3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick path_(path), 3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick block_files_(path), 3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick mask_(0), 3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick max_size_(0), 3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_delay_(0), 3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cache_type_(net::DISK_CACHE), 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick uma_report_(0), 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick user_flags_(0), 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick init_(false), 3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick restarted_(false), 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick unit_test_(false), 3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick read_only_(false), 3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_eviction_(false), 3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick first_timer_(true), 3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick throttle_requests_(false), 3663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net_log_(net_log), 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick done_(true, false), 3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)), 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBackendImpl::BackendImpl(const FilePath& path, 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick uint32 mask, 3743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::MessageLoopProxy* cache_thread, 3753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net::NetLog* net_log) 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : ALLOW_THIS_IN_INITIALIZER_LIST(background_queue_(this, cache_thread)), 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick path_(path), 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick block_files_(path), 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick mask_(mask), 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick max_size_(0), 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_delay_(0), 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cache_type_(net::DISK_CACHE), 3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick uma_report_(0), 3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick user_flags_(kMask), 3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick init_(false), 3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick restarted_(false), 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick unit_test_(false), 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick read_only_(false), 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new_eviction_(false), 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick first_timer_(true), 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick throttle_requests_(false), 3923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen net_log_(net_log), 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick done_(true, false), 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)), 3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { 3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBackendImpl::~BackendImpl() { 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_queue_.WaitForPendingIO(); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (background_queue_.BackgroundIsCurrentThread()) { 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Unit tests may use the same thread for everything. 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CleanupCache(); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_queue_.background_thread()->PostTask(FROM_HERE, 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new FinalCleanup(this)); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch done_.Wait(); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// If the initialization of the cache fails, and force is true, we will discard 41272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// the whole cache and create a new one. In order to process a potentially large 41372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// number of files, we'll rename the cache folder to old_ + original_name + 41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// number, (located on the same parent folder), and spawn a worker thread to 41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// delete all the files on all the stale cache folders. The whole process can 41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// still fail if we are not able to rename the cache folder (for instance due to 41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// a sharing violation), and in that case a cache for this profile (on the 41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// desired path) cannot be created. 41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 42072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Static. 42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint BackendImpl::CreateBackend(const FilePath& full_path, bool force, 42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int max_bytes, net::CacheType type, 42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen uint32 flags, base::MessageLoopProxy* thread, 42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen net::NetLog* net_log, Backend** backend, 42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CompletionCallback* callback) { 42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(callback); 42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CacheCreator* creator = new CacheCreator(full_path, force, max_bytes, type, 42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen flags, thread, net_log, backend, 42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen callback); 43072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This object will self-destroy when finished. 43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return creator->Run(); 43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint BackendImpl::Init(CompletionCallback* callback) { 43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen background_queue_.Init(callback); 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return net::ERR_IO_PENDING; 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncInit() { 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!init_); 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (init_) 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool create_files = false; 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!InitBackingStore(&create_files)) { 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportError(ERR_STORAGE_ERROR); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_refs_ = num_pending_io_ = max_refs_ = 0; 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry_count_ = byte_count_ = 0; 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!restarted_) { 4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick buffer_bytes_ = 0; 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott trace_object_ = TraceObject::GetTraceObject(); 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Create a recurrent timer of 30 secs. 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int timer_delay = unit_test_ ? 1000 : 30000; 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott timer_.Start(TimeDelta::FromMilliseconds(timer_delay), this, 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &BackendImpl::OnStatsTimer); 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_ = true; 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (data_->header.experiment != NO_EXPERIMENT && 4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cache_type_ != net::DISK_CACHE) { 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No experiment for other caches. 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(user_flags_ & disk_cache::kNoRandom)) { 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The unit test controls directly what to test. 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_eviction_ = (cache_type_ == net::DISK_CACHE); 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CheckIndex()) { 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportError(ERR_INIT_FAILED); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!(user_flags_ & disk_cache::kNoRandom) && 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cache_type_ == net::DISK_CACHE && 482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !InitExperiment(&data_->header)) 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return net::ERR_FAILED; 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We don't care if the value overflows. The only thing we care about is that 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the id cannot be zero, because that value is used as "not dirty". 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Increasing the value once per second gives us many years before we start 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // having collisions. 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.this_id++; 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!data_->header.this_id) 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.this_id++; 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_->header.crash) { 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportError(ERR_PREVIOUS_CRASH); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportError(0); 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.crash = 1; 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!block_files_.Init(create_files)) 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We want to minimize the changes to cache for an AppCache. 5043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cache_type() == net::APP_CACHE) { 5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!new_eviction_); 5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick read_only_ = true; 5073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 5083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // stats_ and rankings_ may end up calling back to us so we better be enabled. 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disabled_ = false; 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!stats_.Init(this, &data_->header.stats)) 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disabled_ = !rankings_.Init(this, new_eviction_); 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.Init(this); 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Setup load-time data only for the main cache. 5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!throttle_requests_ && cache_type() == net::DISK_CACHE) 5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick throttle_requests_ = SetFieldTrialInfo(GetSizeGroup()); 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return disabled_ ? net::ERR_FAILED : net::OK; 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackendImpl::CleanupCache() { 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Trace("Backend Cleanup"); 5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick eviction_.Stop(); 5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick timer_.Stop(); 5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (init_) { 5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stats_.Store(); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data_) 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_->header.crash = 0; 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch File::WaitForPendingIO(&num_pending_io_); 5353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (user_flags_ & kNoRandom) { 5363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is a net_unittest, verify that we are not 'leaking' entries. 5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!num_refs_); 5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick block_files_.CloseFiles(); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch factory_.RevokeAll(); 5423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ptr_factory_.InvalidateWeakPtrs(); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch done_.Signal(); 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ------------------------------------------------------------------------ 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry, 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CompletionCallback* callback) { 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(callback); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_queue_.OpenPrevEntry(iter, prev_entry, callback); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_IO_PENDING; 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncOpenEntry(const std::string& key, Entry** entry) { 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(entry); 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *entry = OpenEntryImpl(key); 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (*entry) ? net::OK : net::ERR_FAILED; 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncCreateEntry(const std::string& key, Entry** entry) { 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(entry); 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *entry = CreateEntryImpl(key); 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (*entry) ? net::OK : net::ERR_FAILED; 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncDoomEntry(const std::string& key) { 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (disabled_) 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EntryImpl* entry = OpenEntryImpl(key); 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!entry) 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->DoomImpl(); 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->Release(); 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncDoomAllEntries() { 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This is not really an error, but it is an interesting condition. 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ReportError(ERR_CACHE_DOOMED); 5833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.OnEvent(Stats::DOOM_CACHE); 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!num_refs_) { 5853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen RestartCache(false); 5863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return disabled_ ? net::ERR_FAILED : net::OK; 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (disabled_) 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch eviction_.TrimCache(true); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time, 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const base::Time end_time) { 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_NE(net::APP_CACHE, cache_type_); 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (end_time.is_null()) 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return SyncDoomEntriesSince(initial_time); 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(end_time >= initial_time); 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (disabled_) 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EntryImpl* node; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EntryImpl* next = OpenNextEntryImpl(&iter); 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!next) 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (next) { 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node = next; 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next = OpenNextEntryImpl(&iter); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->GetLastUsed() >= initial_time && 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node->GetLastUsed() < end_time) { 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node->DoomImpl(); 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (node->GetLastUsed() < initial_time) { 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next) 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next->Release(); 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next = NULL; 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncEndEnumeration(iter); 625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch node->Release(); 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We use OpenNextEntryImpl to retrieve elements from the cache, until we get 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// entries that are too old. 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_NE(net::APP_CACHE, cache_type_); 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_FAILED; 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.OnEvent(Stats::DOOM_RECENT); 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (;;) { 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* iter = NULL; 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EntryImpl* entry = OpenNextEntryImpl(&iter); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!entry) 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (initial_time > entry->GetLastUsed()) { 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->Release(); 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncEndEnumeration(iter); 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::OK; 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->DoomImpl(); 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->Release(); 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncEndEnumeration(iter); // Dooming the entry invalidates the iterator. 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncOpenNextEntry(void** iter, Entry** next_entry) { 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *next_entry = OpenNextEntryImpl(iter); 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (*next_entry) ? net::OK : net::ERR_FAILED; 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::SyncOpenPrevEntry(void** iter, Entry** prev_entry) { 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *prev_entry = OpenPrevEntryImpl(iter); 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (*prev_entry) ? net::OK : net::ERR_FAILED; 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackendImpl::SyncEndEnumeration(void* iter) { 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<Rankings::Iterator> iterator( 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<Rankings::Iterator*>(iter)); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::OpenEntryImpl(const std::string& key) { 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (disabled_) 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TimeTicks start = TimeTicks::Now(); 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 hash = Hash(key); 6803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Trace("Open hash 0x%x", hash); 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool error; 68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EntryImpl* cache_entry = MatchEntry(key, hash, false, Addr(), &error); 684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry) { 685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::OPEN_MISS); 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ENTRY_NORMAL != cache_entry->entry()->Data()->state) { 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The entry was already evicted. 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry->Release(); 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::OPEN_MISS); 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnOpenEntry(cache_entry); 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry_count_++; 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(AGE_MS, "OpenTime", GetSizeGroup(), start); 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::OPEN_HIT); 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return cache_entry; 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::CreateEntryImpl(const std::string& key) { 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_ || key.empty()) 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TimeTicks start = TimeTicks::Now(); 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 hash = Hash(key); 7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Trace("Create hash 0x%x", hash); 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<EntryImpl> parent; 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr entry_address(data_->table[hash & mask_]); 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (entry_address.is_initialized()) { 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have an entry already. It could be the one we are looking for, or just 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // a hash conflict. 71772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool error; 71872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EntryImpl* old_entry = MatchEntry(key, hash, false, Addr(), &error); 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (old_entry) 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResurrectEntry(old_entry); 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EntryImpl* parent_entry = MatchEntry(key, hash, true, Addr(), &error); 72372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(!error); 7243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (parent_entry) { 7253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parent.swap(&parent_entry); 7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (data_->table[hash & mask_]) { 7273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We should have corrected the problem. 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_blocks; 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t key1_len = sizeof(EntryStore) - offsetof(EntryStore, key); 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key.size() < key1_len || 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key.size() > static_cast<size_t>(kMaxInternalKeyLength)) 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_blocks = 1; 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_blocks = static_cast<int>((key.size() - key1_len) / 256 + 2); 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!block_files_.CreateBlock(BLOCK_256, num_blocks, &entry_address)) { 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Create entry failed " << key.c_str(); 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::CREATE_ERROR); 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr node_address(0); 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!block_files_.CreateBlock(RANKINGS, 1, &node_address)) { 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.DeleteBlock(entry_address, false); 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Create entry failed " << key.c_str(); 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::CREATE_ERROR); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<EntryImpl> cache_entry( 7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new EntryImpl(this, entry_address, false)); 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IncreaseNumRefs(); 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->CreateEntry(node_address, key, hash)) { 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.DeleteBlock(entry_address, false); 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.DeleteBlock(node_address, false); 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Create entry failed " << key.c_str(); 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::CREATE_ERROR); 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen cache_entry->BeginLogging(net_log_, true); 7683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We are not failing the operation; let's add this to the map. 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott open_entries_[entry_address.value()] = cache_entry; 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (parent.get()) 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent->SetNextAddress(entry_address); 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.GetFile(entry_address)->Store(cache_entry->entry()); 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.GetFile(node_address)->Store(cache_entry->rankings()); 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IncreaseNumEntries(); 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnCreateEntry(cache_entry); 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry_count_++; 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!parent.get()) 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->table[hash & mask_] = entry_address.value(); 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(AGE_MS, "CreateTime", GetSizeGroup(), start); 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::CREATE_HIT); 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("create entry hit "); 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return cache_entry.release(); 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::OpenNextEntryImpl(void** iter) { 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OpenFollowingEntry(true, iter); 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::OpenPrevEntryImpl(void** iter) { 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OpenFollowingEntry(false, iter); 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::SetMaxSize(int max_bytes) { 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott COMPILE_ASSERT(sizeof(max_bytes) == sizeof(max_size_), unsupported_int_model); 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_bytes < 0) 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Zero size means use the default. 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!max_bytes) 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Avoid a DCHECK later on. 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_bytes >= kint32max - kint32max / 10) 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_bytes = kint32max - kint32max / 10 - 1; 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_flags_ |= kMaxSize; 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_size_ = max_bytes; 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SetType(net::CacheType type) { 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(type != net::MEMORY_CACHE); 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_type_ = type; 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFilePath BackendImpl::GetFileName(Addr address) const { 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!address.is_separate_file() || !address.is_initialized()) { 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return FilePath(); 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string tmp = base::StringPrintf("f_%06x", address.FileNumber()); 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return path_.AppendASCII(tmp); 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottMappedFile* BackendImpl::File(Addr address) { 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return block_files_.GetFile(address); 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::CreateExternalFile(Addr* address) { 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int file_number = data_->header.last_file + 1; 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr file_address(0); 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool success = false; 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 0x0fffffff; i++, file_number++) { 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file_address.SetFileNumber(file_number)) { 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_number = 1; 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath name = GetFileName(file_address); 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int flags = base::PLATFORM_FILE_READ | 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_WRITE | 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_CREATE | 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_EXCLUSIVE_WRITE; 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<disk_cache::File> file(new disk_cache::File( 8523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::CreatePlatformFile(name, flags, NULL, NULL))); 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file->IsValid()) 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott success = true; 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(success); 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!success) 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.last_file = file_number; 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott address->set_value(file_address.value()); 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::CreateBlock(FileType block_type, int block_count, 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr* block_address) { 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return block_files_.CreateBlock(block_type, block_count, block_address); 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DeleteBlock(Addr block_address, bool deep) { 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.DeleteBlock(block_address, deep); 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottLruData* BackendImpl::GetLruData() { 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return &data_->header.lru; 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::UpdateRank(EntryImpl* entry, bool modified) { 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!read_only_) { 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.UpdateRank(entry, modified); 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(rankings->Data()->contents); 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* cache_entry = NULL; 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool dirty; 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (NewEntry(address, &cache_entry, &dirty)) 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 hash = cache_entry->GetHash(); 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry->Release(); 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Anything on the table means that this entry is there. 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_->table[hash & mask_]) 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->table[hash & mask_] = address.value(); 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::InternalDoomEntry(EntryImpl* entry) { 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 hash = entry->GetHash(); 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string key = entry->GetKey(); 90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Addr entry_addr = entry->entry()->address(); 90972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool error; 91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EntryImpl* parent_entry = MatchEntry(key, hash, true, entry_addr, &error); 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheAddr child(entry->GetNextAddress()); 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("Doom entry 0x%p", entry); 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnDoomEntry(entry); 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->InternalDoom(); 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (parent_entry) { 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry->SetNextAddress(Addr(child)); 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry->Release(); 92172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else if (!error) { 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->table[hash & mask_] = child; 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!new_eviction_) { 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DecreaseNumEntries(); 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::DOOM_ENTRY); 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An entry may be linked on the DELETED list for a while after being doomed. 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This function is called when we want to remove it. 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::RemoveEntry(EntryImpl* entry) { 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!new_eviction_) 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(ENTRY_NORMAL != entry->entry()->Data()->state); 939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("Remove entry 0x%p", entry); 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnDestroyEntry(entry); 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DecreaseNumEntries(); 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BackendImpl::OnEntryDestroyBegin(Addr address) { 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntriesMap::iterator it = open_entries_.find(address.value()); 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it != open_entries_.end()) 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott open_entries_.erase(it); 9493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BackendImpl::OnEntryDestroyEnd() { 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DecreaseNumRefs(); 9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (data_->header.num_bytes > max_size_ && !read_only_) 9543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick eviction_.TrimCache(false); 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEntryImpl* BackendImpl::GetOpenEntry(CacheRankingsBlock* rankings) const { 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(rankings->HasData()); 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntriesMap::const_iterator it = 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott open_entries_.find(rankings->Data()->contents); 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it != open_entries_.end()) { 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have this entry in memory. 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return it->second; 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32 BackendImpl::GetCurrentEntryId() const { 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return data_->header.this_id; 971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BackendImpl::MaxFileSize() const { 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return max_size_ / 8; 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::ModifyStorageSize(int32 old_size, int32 new_size) { 978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_ || old_size == new_size) 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (old_size > new_size) 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SubstractStorageSize(old_size - new_size); 982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddStorageSize(new_size - old_size); 984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Update the usage statistics. 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.ModifyStorageStats(old_size, new_size); 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::TooMuchStorageRequested(int32 size) { 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.ModifyStorageStats(0, size); 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BackendImpl::IsAllocAllowed(int current_size, int new_size) { 9943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_GT(new_size, current_size); 9953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (user_flags_ & kNoBuffering) 9963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 9973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int to_add = new_size - current_size; 9993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (buffer_bytes_ + to_add > MaxBuffersSize()) 10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 10013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick buffer_bytes_ += to_add; 10033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(COUNTS_50000, "BufferBytes", 0, buffer_bytes_ / 1024); 10043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 10053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 10063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BackendImpl::BufferDeleted(int size) { 10083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick buffer_bytes_ -= size; 10093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_GE(size, 0); 10103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 10113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::IsLoaded() const { 1013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "PendingIO", GetSizeGroup(), num_pending_io_); 1014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (user_flags_ & kNoLoadProtection) 1015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return num_pending_io_ > 5; 1018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string BackendImpl::HistogramName(const char* name, int experiment) const { 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!experiment) 10223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return base::StringPrintf("DiskCache.%d.%s", cache_type_, name); 10233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return base::StringPrintf("DiskCache.%d.%s_%d", cache_type_, 10243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name, experiment); 10253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 10263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 10273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbase::WeakPtr<BackendImpl> BackendImpl::GetWeakPtr() { 10283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ptr_factory_.GetWeakPtr(); 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BackendImpl::GetSizeGroup() const { 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We want to report times grouped by the current cache size (50 MB groups). 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int group = data_->header.num_bytes / (50 * 1024 * 1024); 1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (group > 6) 1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott group = 6; // Limit the number of groups, just in case. 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return group; 1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We want to remove biases from some histograms so we only send data once per 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// week. 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::ShouldReportAgain() { 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (uma_report_) 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return uma_report_ == 2; 1047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uma_report_++; 1049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); 1050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Time last_time = Time::FromInternalValue(last_report); 1051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!last_report || (Time::Now() - last_time).InDays() >= 7) { 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue()); 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uma_report_++; 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::FirstEviction() { 1060c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(data_->header.create_time); 1061c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1062c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Time create_time = Time::FromInternalValue(data_->header.create_time); 1063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(AGE, "FillupAge", 0, create_time); 1064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int64 use_time = stats_.GetCounter(Stats::TIMER); 1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(HOURS, "FillupTime", 0, static_cast<int>(use_time / 120)); 1067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstHitRatio", 0, stats_.GetHitRatio()); 1068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!use_time) 1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch use_time = 1; 1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS_10000, "FirstEntryAccessRate", 0, 1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(data_->header.num_entries / use_time)); 1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS, "FirstByteIORate", 0, 1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>((data_->header.num_bytes / 1024) / use_time)); 1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1076c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int avg_size = data_->header.num_bytes / GetEntryCount(); 1077c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "FirstEntrySize", 0, avg_size); 1078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int large_entries_bytes = stats_.GetLargeEntriesSize(); 1080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; 1081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstLargeEntriesRatio", 0, large_ratio); 1082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (new_eviction_) { 1084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstResurrectRatio", 0, stats_.GetResurrectRatio()); 1085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstNoUseRatio", 0, 1086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[0] * 100 / data_->header.num_entries); 1087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstLowUseRatio", 0, 1088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[1] * 100 / data_->header.num_entries); 1089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "FirstHighUseRatio", 0, 1090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[2] * 100 / data_->header.num_entries); 1091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.ResetRatios(); 1094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::CriticalError(int error) { 1097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Critical error found " << error; 1098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 1099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.OnEvent(Stats::FATAL_ERROR); 1102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LogStats(); 1103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportError(error); 1104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Setting the index table length to an invalid value will force re-creation 1106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of the cache files. 1107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.table_len = 1; 1108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disabled_ = true; 1109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!num_refs_) 1111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, 11123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen factory_.NewRunnableMethod(&BackendImpl::RestartCache, true)); 1113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::ReportError(int error) { 1116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We transmit positive numbers, instead of direct error codes. 1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LE(error, 0); 1118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(CACHE_ERROR, "Error", 0, error * -1); 1119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::OnEvent(Stats::Counters an_event) { 1122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(an_event); 1123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackendImpl::OnRead(int32 bytes) { 1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(bytes, 0); 1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch byte_count_ += bytes; 1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (byte_count_ < 0) 1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch byte_count_ = kint32max; 1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BackendImpl::OnWrite(int32 bytes) { 1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use the same implementation as OnRead... just log the number of bytes. 1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnRead(bytes); 1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BackendImpl::OnOperationCompleted(base::TimeDelta elapsed_time) { 11383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(TIMES, "TotalIOTime", 0, elapsed_time); 11393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cache_type() != net::DISK_CACHE) 11413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 11423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 114321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UMA_HISTOGRAM_TIMES(base::FieldTrial::MakeName("DiskCache.TotalIOTime", 114421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen "CacheThrottle").data(), 114521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen elapsed_time); 114621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!throttle_requests_) 11483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 11493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 115072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const int kMaxNormalDelayMS = 460; 11513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool throttling = io_delay_ > kMaxNormalDelayMS; 11533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We keep a simple exponential average of elapsed_time. 11553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick io_delay_ = (io_delay_ + static_cast<int>(elapsed_time.InMilliseconds())) / 2; 11563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (io_delay_ > kMaxNormalDelayMS && !throttling) 11573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick background_queue_.StartQueingOperations(); 11583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick else if (io_delay_ <= kMaxNormalDelayMS && throttling) 11593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick background_queue_.StopQueingOperations(); 11603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::OnStatsTimer() { 1163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::TIMER); 1164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 time = stats_.GetCounter(Stats::TIMER); 1165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES); 1166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // OPEN_ENTRIES is a sampled average of the number of open entries, avoiding 1168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the bias towards 0. 1169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (num_refs_ && (current != num_refs_)) { 1170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 diff = (num_refs_ - current) / 50; 1171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!diff) 1172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott diff = num_refs_ > current ? 1 : -1; 1173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott current = current + diff; 1174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::OPEN_ENTRIES, current); 1175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::MAX_ENTRIES, max_refs_); 1176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "NumberOfReferences", 0, num_refs_); 1179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS_10000, "EntryAccessRate", 0, entry_count_); 1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS, "ByteIORate", 0, byte_count_ / 1024); 1182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry_count_ = 0; 1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch byte_count_ = 0; 1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!data_) 1186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first_timer_ = false; 1187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (first_timer_) { 1188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first_timer_ = false; 1189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ShouldReportAgain()) 1190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ReportStats(); 1191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Save stats to disk at 5 min intervals. 1194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (time % 10 == 0) 1195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.Store(); 1196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::IncrementIoCount() { 1199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_pending_io_++; 1200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DecrementIoCount() { 1203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_pending_io_--; 1204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SetUnitTestMode() { 1207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_flags_ |= kUnitTestMode; 1208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unit_test_ = true; 1209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SetUpgradeMode() { 1212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_flags_ |= kUpgradeMode; 1213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott read_only_ = true; 1214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SetNewEviction() { 1217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_flags_ |= kNewEviction; 1218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_eviction_ = true; 1219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SetFlags(uint32 flags) { 1222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott user_flags_ |= flags; 1223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::ClearRefCountForTest() { 1226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_refs_ = 0; 1227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BackendImpl::FlushQueueForTest(CompletionCallback* callback) { 1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background_queue_.FlushQueue(callback); 1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return net::ERR_IO_PENDING; 1232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint BackendImpl::RunTaskForTest(Task* task, CompletionCallback* callback) { 12353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick background_queue_.RunTask(task, callback); 12363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return net::ERR_IO_PENDING; 12373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 12383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1239513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid BackendImpl::ThrottleRequestsForTest(bool throttle) { 1240513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (throttle) 1241513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch background_queue_.StartQueingOperations(); 1242513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch else 1243513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch background_queue_.StopQueingOperations(); 1244513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 1245513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 124672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid BackendImpl::TrimForTest(bool empty) { 124772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen eviction_.SetTestMode(); 124872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen eviction_.TrimCache(empty); 124972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 125072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 125172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid BackendImpl::TrimDeletedListForTest(bool empty) { 125272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen eviction_.SetTestMode(); 125372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen eviction_.TrimDeletedList(empty); 125472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 125572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BackendImpl::SelfCheck() { 1257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!init_) { 1258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Init failed"; 1259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_INIT_FAILED; 1260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_entries = rankings_.SelfCheck(); 1263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (num_entries < 0) { 1264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid rankings list, error " << num_entries; 1265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return num_entries; 1266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (num_entries != data_->header.num_entries) { 1269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Number of entries mismatch"; 1270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_NUM_ENTRIES_MISMATCH; 1271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CheckAllEntries(); 1274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ------------------------------------------------------------------------ 1277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint32 BackendImpl::GetEntryCount() const { 12793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!index_ || disabled_) 12803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return 0; 12813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // num_entries includes entries already evicted. 12823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int32 not_deleted = data_->header.num_entries - 12833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen data_->header.lru.sizes[Rankings::DELETED]; 12843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 12853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (not_deleted < 0) { 12863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED(); 12873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen not_deleted = 0; 12883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 12893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 12903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return not_deleted; 12913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 12923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 12933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::OpenEntry(const std::string& key, Entry** entry, 12943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 12953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 12963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.OpenEntry(key, entry, callback); 12973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 12983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 12993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::CreateEntry(const std::string& key, Entry** entry, 13013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 13023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.CreateEntry(key, entry, callback); 13043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::DoomEntry(const std::string& key, 13083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 13093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.DoomEntry(key, callback); 13113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::DoomAllEntries(CompletionCallback* callback) { 13153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.DoomAllEntries(callback); 13173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::DoomEntriesBetween(const base::Time initial_time, 13213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const base::Time end_time, 13223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 13233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.DoomEntriesBetween(initial_time, end_time, callback); 13253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::DoomEntriesSince(const base::Time initial_time, 13293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 13303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.DoomEntriesSince(initial_time, callback); 13323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenint BackendImpl::OpenNextEntry(void** iter, Entry** next_entry, 13363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CompletionCallback* callback) { 13373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(callback); 13383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.OpenNextEntry(iter, next_entry, callback); 13393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return net::ERR_IO_PENDING; 13403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid BackendImpl::EndEnumeration(void** iter) { 13433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen background_queue_.EndEnumeration(*iter); 13443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen *iter = NULL; 13453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid BackendImpl::GetStats(StatsItems* stats) { 13483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (disabled_) 13493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 13503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::pair<std::string, std::string> item; 13523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.first = "Entries"; 13543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.second = base::StringPrintf("%d", data_->header.num_entries); 13553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats->push_back(item); 13563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.first = "Pending IO"; 13583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.second = base::StringPrintf("%d", num_pending_io_); 13593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats->push_back(item); 13603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.first = "Max size"; 13623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.second = base::StringPrintf("%d", max_size_); 13633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats->push_back(item); 13643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.first = "Current size"; 13663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen item.second = base::StringPrintf("%d", data_->header.num_bytes); 13673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats->push_back(item); 13683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.GetItems(stats); 13703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 13713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 13723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// ------------------------------------------------------------------------ 13733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We just created a new file so we're going to write the header and set the 1375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// file length to include the hash table (zero filled). 1376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::CreateBackingStore(disk_cache::File* file) { 1377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AdjustMaxCacheSize(0); 1378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IndexHeader header; 1380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header.table_len = DesiredIndexTableLen(max_size_); 1381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We need file version 2.1 for the new eviction algorithm. 1383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (new_eviction_) 1384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header.version = 0x20001; 1385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header.create_time = Time::Now().ToInternalValue(); 1387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file->Write(&header, sizeof(header), 0)) 1389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return file->SetLength(GetIndexSize(header.table_len)); 1392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::InitBackingStore(bool* file_created) { 1395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_util::CreateDirectory(path_); 1396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath index_name = path_.AppendASCII(kIndexName); 1398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int flags = base::PLATFORM_FILE_READ | 1400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_WRITE | 1401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_OPEN_ALWAYS | 1402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::PLATFORM_FILE_EXCLUSIVE_WRITE; 1403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<disk_cache::File> file(new disk_cache::File( 14043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::CreatePlatformFile(index_name, flags, file_created, NULL))); 1405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file->IsValid()) 1407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ret = true; 1410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (*file_created) 1411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret = CreateBackingStore(file); 1412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file = NULL; 1414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ret) 1415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott index_ = new MappedFile(); 1418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = reinterpret_cast<Index*>(index_->Init(index_name, 0)); 1419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!data_) { 1420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Unable to map Index file"; 1421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (index_->GetLength() < sizeof(Index)) { 1425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We verify this again on CheckIndex() but it's easier to make sure now 1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that the header is there. 1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Corrupt Index file"; 1428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 1432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The maximum cache size will be either set explicitly by the caller, or 1435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// calculated by this code. 1436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::AdjustMaxCacheSize(int table_len) { 1437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_size_) 1438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If table_len is provided, the index file exists. 1441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!table_len || data_->header.magic); 1442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The user is not setting the size, let's figure it out. 144400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#ifdef ANDROID 144500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int64 available = 10 * 1024 * 1024; // 10 MB 144600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#else 1447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 available = base::SysInfo::AmountOfFreeDiskSpace(path_); 144800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#endif 1449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (available < 0) { 1450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_size_ = kDefaultCacheSize; 1451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (table_len) 1455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott available += data_->header.num_bytes; 1456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_size_ = PreferedCacheSize(available); 1458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Let's not use more than the default size while we tune-up the performance 1460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of bigger caches. TODO(rvargas): remove this limit. 1461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_size_ > kDefaultCacheSize * 4) 1462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_size_ = kDefaultCacheSize * 4; 1463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!table_len) 1465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we already have a table, adjust the size to it. 1468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int current_max_size = MaxStorageSizeForTable(table_len); 1469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_size_ > current_max_size) 1470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_size_= current_max_size; 1471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid BackendImpl::RestartCache(bool failure) { 1474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 errors = stats_.GetCounter(Stats::FATAL_ERROR); 14753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int64 full_dooms = stats_.GetCounter(Stats::DOOM_CACHE); 14763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int64 partial_dooms = stats_.GetCounter(Stats::DOOM_RECENT); 147772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); 14783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 14793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen PrepareForRestart(); 14803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (failure) { 14813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(!num_refs_); 14823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK(!open_entries_.size()); 14833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DelayedCacheCleanup(path_); 14843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 14853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DeleteCache(path_, false); 14863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Don't call Init() if directed by the unit test: we are simulating a failure 1489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // trying to re-enable the cache. 1490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (unit_test_) 1491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_ = true; // Let the destructor do proper cleanup. 14923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen else if (SyncInit() == net::OK) { 14933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.SetCounter(Stats::FATAL_ERROR, errors); 14943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.SetCounter(Stats::DOOM_CACHE, full_dooms); 14953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen stats_.SetCounter(Stats::DOOM_RECENT, partial_dooms); 149672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen stats_.SetCounter(Stats::LAST_REPORT, last_report); 14973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::PrepareForRestart() { 1501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Reset the mask_ if it was not given by the user. 1502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(user_flags_ & kMask)) 1503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mask_ = 0; 1504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(user_flags_ & kNewEviction)) 1506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new_eviction_ = false; 1507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen disabled_ = true; 1509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.crash = 0; 1510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott index_ = NULL; 1511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_ = NULL; 1512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott block_files_.CloseFiles(); 1513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rankings_.Reset(); 1514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott init_ = false; 1515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott restarted_ = true; 1516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { 1519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntriesMap::iterator it = open_entries_.find(address.value()); 1520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it != open_entries_.end()) { 1521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Easy job. This entry is already in memory. 1522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* this_entry = it->second; 1523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott this_entry->AddRef(); 1524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *entry = this_entry; 1525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *dirty = false; 1526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 1527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_refptr<EntryImpl> cache_entry( 15303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new EntryImpl(this, address, read_only_)); 1531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IncreaseNumRefs(); 1532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *entry = NULL; 1533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!address.is_initialized() || address.is_separate_file() || 1535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott address.file_type() != BLOCK_256) { 1536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "Wrong entry address."; 1537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_INVALID_ADDRESS; 1538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TimeTicks start = TimeTicks::Now(); 1541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->entry()->Load()) 1542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_READ_FAILURE; 1543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsLoaded()) { 1545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(AGE_MS, "LoadTime", GetSizeGroup(), start); 1546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->SanityCheck()) { 1549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "Messed up entry found."; 1550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_INVALID_ENTRY; 1551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->LoadNodeAddress()) 1554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_READ_FAILURE; 1555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *dirty = cache_entry->IsDirty(GetCurrentEntryId()); 1557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Prevent overwriting the dirty flag on the destructor. 1559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry->ClearDirtyFlag(); 1560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!rankings_.SanityCheck(cache_entry->rankings(), false)) 1562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_INVALID_LINKS; 1563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (*dirty) { 15653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Trace("Dirty entry 0x%p 0x%x", reinterpret_cast<void*>(cache_entry.get()), 15663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick address.value()); 15673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We only add clean entries to the map. 1569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott open_entries_[address.value()] = cache_entry; 15703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen cache_entry->BeginLogging(net_log_, false); 1573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry.swap(entry); 1574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 1575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottEntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, 157872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool find_parent, Addr entry_addr, 157972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool* match_error) { 1580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(data_->table[hash & mask_]); 1581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<EntryImpl> cache_entry, parent_entry; 1582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* tmp = NULL; 1583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool found = false; 158472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::set<CacheAddr> visited; 158572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *match_error = false; 1586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 1588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 1589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (visited.find(address.value()) != visited.end()) { 159272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // It's possible for a buggy version of the code to write a loop. Just 159372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // break it. 159472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Trace("Hash collision loop 0x%x", address.value()); 159572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen address.set_value(0); 159672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen parent_entry->SetNextAddress(address); 159772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 159872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen visited.insert(address.value()); 159972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!address.is_initialized()) { 1601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (find_parent) 1602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott found = true; 1603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1606c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool dirty; 1607c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int error = NewEntry(address, &tmp, &dirty); 1608c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry.swap(&tmp); 1609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (error || dirty) { 1611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This entry is dirty on disk (it was not properly closed): we cannot 1612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // trust it. 1613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr child(0); 1614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!error) 1615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott child.set_value(cache_entry->GetNextAddress()); 1616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1617c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (parent_entry) { 1618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry->SetNextAddress(child); 1619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry = NULL; 1620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->table[hash & mask_] = child.value(); 1622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!error) { 1625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // It is important to call DestroyInvalidEntry after removing this 1626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // entry from the table. 1627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyInvalidEntry(cache_entry); 1628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry = NULL; 1629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("NewEntry failed on MatchEntry 0x%x", address.value()); 1631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Restart the search. 1634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott address.set_value(data_->table[hash & mask_]); 163572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen visited.clear(); 1636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 1637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(hash & mask_, cache_entry->entry()->Data()->hash & mask_); 1640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (cache_entry->IsSameEntry(key, hash)) { 1641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->Update()) 1642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry = NULL; 1643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott found = true; 164472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (find_parent && entry_addr.value() != address.value()) { 164572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Trace("Entry not on the index 0x%x", address.value()); 164672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *match_error = true; 164772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen parent_entry = NULL; 164872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 1649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!cache_entry->Update()) 1652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry = NULL; 1653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry = cache_entry; 1654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry = NULL; 1655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!parent_entry) 1656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott address.set_value(parent_entry->GetNextAddress()); 1659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (parent_entry && (!find_parent || !found)) 1662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott parent_entry = NULL; 1663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (cache_entry && (find_parent || !found)) 1665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry = NULL; 1666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott find_parent ? parent_entry.swap(&tmp) : cache_entry.swap(&tmp); 1668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tmp; 1669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is the actual implementation for OpenNextEntry and OpenPrevEntry. 1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::OpenFollowingEntry(bool forward, void** iter) { 1673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(iter); 1677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int kListsToSearch = 3; 1679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<EntryImpl> entries[kListsToSearch]; 1680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<Rankings::Iterator> iterator( 1681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<Rankings::Iterator*>(*iter)); 1682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *iter = NULL; 1683c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1684c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!iterator.get()) { 1685c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott iterator.reset(new Rankings::Iterator(&rankings_)); 1686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ret = false; 1687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get an entry from each list. 1689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kListsToSearch; i++) { 1690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* temp = NULL; 1691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret |= OpenFollowingEntryFromList(forward, static_cast<Rankings::List>(i), 1692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &iterator->nodes[i], &temp); 1693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries[i].swap(&temp); // The entry was already addref'd. 1694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ret) 1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the next entry from the last list, and the actual entries for the 1699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // elements on the other lists. 1700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kListsToSearch; i++) { 1701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* temp = NULL; 1702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (iterator->list == i) { 1703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OpenFollowingEntryFromList(forward, iterator->list, 1704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &iterator->nodes[i], &temp); 1705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 170672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen temp = GetEnumeratedEntry(iterator->nodes[i]); 1707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries[i].swap(&temp); // The entry was already addref'd. 1710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int newest = -1; 1714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int oldest = -1; 1715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Time access_times[kListsToSearch]; 1716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kListsToSearch; i++) { 1717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (entries[i].get()) { 1718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott access_times[i] = entries[i]->GetLastUsed(); 1719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (newest < 0) { 1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_LT(oldest, 0); 1721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott newest = oldest = i; 1722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 1723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (access_times[i] > access_times[newest]) 1725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott newest = i; 1726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (access_times[i] < access_times[oldest]) 1727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott oldest = i; 1728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (newest < 0 || oldest < 0) 1732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EntryImpl* next_entry; 1735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (forward) { 1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_entry = entries[newest].release(); 1737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott iterator->list = static_cast<Rankings::List>(newest); 1738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 1739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_entry = entries[oldest].release(); 1740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott iterator->list = static_cast<Rankings::List>(oldest); 1741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *iter = iterator.release(); 1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return next_entry; 1745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::OpenFollowingEntryFromList(bool forward, Rankings::List list, 1748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheRankingsBlock** from_entry, 1749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl** next_entry) { 1750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (disabled_) 1751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!new_eviction_ && Rankings::NO_USE != list) 1754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Rankings::ScopedRankingsBlock rankings(&rankings_, *from_entry); 1757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheRankingsBlock* next_block = forward ? 1758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rankings_.GetNext(rankings.get(), list) : 1759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rankings_.GetPrev(rankings.get(), list); 1760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Rankings::ScopedRankingsBlock next(&rankings_, next_block); 1761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *from_entry = NULL; 1762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *next_entry = GetEnumeratedEntry(next.get()); 1764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!*next_entry) 1765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 1766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *from_entry = next.release(); 1768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 1769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenEntryImpl* BackendImpl::GetEnumeratedEntry(CacheRankingsBlock* next) { 1772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!next || disabled_) 1773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* entry; 1776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool dirty; 1777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (NewEntry(Addr(next->Data()->contents), &entry, &dirty)) 1778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dirty) { 1781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We cannot trust this entry. This code also releases the reference. 1782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyInvalidEntryFromEnumeration(entry); 1783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!entry->Update()) { 1787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->Release(); 1788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 1789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 179172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Note that it is unfortunate (but possible) for this entry to be clean, but 179272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // not actually the real entry. In other words, we could have lost this entry 179372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // from the index, and it could have been replaced with a newer one. It's not 179472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // worth checking that this entry is "the real one", so we just return it and 179572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // let the enumeration continue; this entry will be evicted at some point, and 179672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the regular path will work with the real entry. With time, this problem 179772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // will disasappear because this scenario is just a bug. 179872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure that we save the key for later. 1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->GetKey(); 1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return entry; 1803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1805c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochEntryImpl* BackendImpl::ResurrectEntry(EntryImpl* deleted_entry) { 1806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ENTRY_NORMAL == deleted_entry->entry()->Data()->state) { 1807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott deleted_entry->Release(); 1808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::CREATE_MISS); 1809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("create entry miss "); 1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We are attempting to create an entry and found out that the entry was 1814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // previously deleted. 1815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnCreateEntry(deleted_entry); 1817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry_count_++; 1818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stats_.OnEvent(Stats::RESURRECT_HIT); 1820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("Resurrect entry hit "); 1821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return deleted_entry; 1822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DestroyInvalidEntry(EntryImpl* entry) { 1825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(WARNING) << "Destroying invalid entry."; 1826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Trace("Destroying invalid entry 0x%p", entry); 1827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->SetPointerForInvalidEntry(GetCurrentEntryId()); 1829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott eviction_.OnDoomEntry(entry); 1831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->InternalDoom(); 1832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!new_eviction_) 1834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DecreaseNumEntries(); 1835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.OnEvent(Stats::INVALID_ENTRY); 1836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is kind of ugly. The entry may or may not be part of the cache index 1839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// table, and it may even have corrupt fields. If we just doom it, we may end up 1840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// deleting it twice (if all fields are right, and when looking up the parent of 1841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// chained entries wee see this one... and we delete it because it is dirty). If 1842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// we ignore it, we may leave it here forever. So we're going to attempt to 1843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// delete it through the provided object, without touching the index table 1844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (because we cannot jus call MatchEntry()), and also attempt to delete it from 1845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the table through the key: this may find a new entry (too bad), or an entry 1846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// that was just deleted and consider it a very corrupt entry. 1847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DestroyInvalidEntryFromEnumeration(EntryImpl* entry) { 1848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string key = entry->GetKey(); 1849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->SetPointerForInvalidEntry(GetCurrentEntryId()); 185072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CacheAddr next_entry = entry->GetNextAddress(); 1851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!next_entry) { 1852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyInvalidEntry(entry); 1853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->Release(); 1854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SyncDoomEntry(key); 1856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!next_entry) 1858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have a chained entry so instead of destroying first this entry and then 1861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // anything with this key, we just called DoomEntry() first. If that call 1862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // deleted everything, |entry| has invalid data. Let's see if there is 1863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // something else to do. We started with just a rankings node (we come from 1864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // an enumeration), so that one may still be there. 1865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheRankingsBlock* rankings = entry->rankings(); 1866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rankings->Load(); 1867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rankings->Data()->contents) { 1868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We still have something. Clean this up. 1869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DestroyInvalidEntry(entry); 1870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry->Release(); 1872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::AddStorageSize(int32 bytes) { 1875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.num_bytes += bytes; 1876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(data_->header.num_bytes, 0); 1877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::SubstractStorageSize(int32 bytes) { 1880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.num_bytes -= bytes; 1881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GE(data_->header.num_bytes, 0); 1882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::IncreaseNumRefs() { 1885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_refs_++; 1886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (max_refs_ < num_refs_) 1887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott max_refs_ = num_refs_; 1888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DecreaseNumRefs() { 1891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(num_refs_); 1892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_refs_--; 1893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!num_refs_ && disabled_) 1895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, 18963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen factory_.NewRunnableMethod(&BackendImpl::RestartCache, true)); 1897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::IncreaseNumEntries() { 1900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.num_entries++; 1901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_GT(data_->header.num_entries, 0); 1902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::DecreaseNumEntries() { 1905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.num_entries--; 1906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_->header.num_entries < 0) { 1907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 1908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.num_entries = 0; 1909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::LogStats() { 1913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StatsItems stats; 1914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GetStats(&stats); 1915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1916731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (size_t index = 0; index < stats.size(); index++) 1917731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << stats[index].first << ": " << stats[index].second; 1918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::ReportStats() { 1921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "Entries", 0, data_->header.num_entries); 19223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 19233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int current_size = data_->header.num_bytes / (1024 * 1024); 19243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int max_size = max_size_ / (1024 * 1024); 19253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(COUNTS_10000, "Size2", 0, current_size); 19263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(COUNTS_10000, "MaxSize2", 0, max_size); 19273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!max_size) 19283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick max_size++; 19293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(PERCENTAGE, "UsedSpace", 0, current_size * 100 / max_size); 1930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS_10000, "AverageOpenEntries2", 0, 1932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static_cast<int>(stats_.GetCounter(Stats::OPEN_ENTRIES))); 1933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS_10000, "MaxOpenEntries2", 0, 1934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); 1935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::MAX_ENTRIES, 0); 1936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CACHE_UMA(COUNTS_10000, "TotalFatalErrors", 0, 19383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<int>(stats_.GetCounter(Stats::FATAL_ERROR))); 19393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CACHE_UMA(COUNTS_10000, "TotalDoomCache", 0, 19403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<int>(stats_.GetCounter(Stats::DOOM_CACHE))); 19413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CACHE_UMA(COUNTS_10000, "TotalDoomRecentEntries", 0, 19423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<int>(stats_.GetCounter(Stats::DOOM_RECENT))); 194372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen stats_.SetCounter(Stats::FATAL_ERROR, 0); 194472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen stats_.SetCounter(Stats::DOOM_CACHE, 0); 194572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen stats_.SetCounter(Stats::DOOM_RECENT, 0); 19463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 19473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; 19483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!data_->header.create_time || !data_->header.lru.filled) { 19493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int cause = data_->header.create_time ? 0 : 1; 19503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!data_->header.lru.filled) 19513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick cause |= 2; 19523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(CACHE_ERROR, "ShortReport", 0, cause); 19533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen CACHE_UMA(HOURS, "TotalTimeNotFull", 0, static_cast<int>(total_hours)); 1954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 19553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This is an up to date client that will report FirstEviction() data. After 1958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // that event, start reporting this: 1959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(HOURS, "TotalTime", 0, static_cast<int>(total_hours)); 1961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; 1963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::LAST_REPORT_TIMER, stats_.GetCounter(Stats::TIMER)); 1964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We may see users with no use_hours at this point if this is the first time 1966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // we are running this code. 1967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (use_hours) 1968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott use_hours = total_hours - use_hours; 1969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!use_hours || !GetEntryCount() || !data_->header.num_bytes) 1971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 1972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(HOURS, "UseTime", 0, static_cast<int>(use_hours)); 19743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(PERCENTAGE, "HitRatio", data_->header.experiment, 19753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stats_.GetHitRatio()); 1976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; 1978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "TrimRate", 0, static_cast<int>(trim_rate)); 1979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int avg_size = data_->header.num_bytes / GetEntryCount(); 1981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(COUNTS, "EntrySize", 0, avg_size); 1982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(COUNTS, "EntriesFull", 0, data_->header.num_entries); 1983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CACHE_UMA(PERCENTAGE, "IndexLoad", 0, 1985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_->header.num_entries * 100 / (mask_ + 1)); 1986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int large_entries_bytes = stats_.GetLargeEntriesSize(); 1988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; 1989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "LargeEntriesRatio", 0, large_ratio); 1990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (new_eviction_) { 19923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(PERCENTAGE, "ResurrectRatio", data_->header.experiment, 19933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick stats_.GetResurrectRatio()); 1994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "NoUseRatio", 0, 1995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[0] * 100 / data_->header.num_entries); 1996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "LowUseRatio", 0, 1997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[1] * 100 / data_->header.num_entries); 1998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CACHE_UMA(PERCENTAGE, "HighUseRatio", 0, 1999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[2] * 100 / data_->header.num_entries); 20003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CACHE_UMA(PERCENTAGE, "DeletedRatio", data_->header.experiment, 2001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[4] * 100 / data_->header.num_entries); 2002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.ResetRatios(); 2005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats_.SetCounter(Stats::TRIM_ENTRY, 0); 2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cache_type_ == net::DISK_CACHE) 2008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch block_files_.ReportStats(); 2009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid BackendImpl::UpgradeTo2_1() { 2012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // 2.1 is basically the same as 2.0, except that new fields are actually 2013c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // updated by the new eviction algorithm. 2014c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(0x20000 == data_->header.version); 2015c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.version = 0x20001; 2016c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.lru.sizes[Rankings::NO_USE] = data_->header.num_entries; 2017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2018c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::CheckIndex() { 2020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(data_); 2021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t current_size = index_->GetLength(); 2023c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (current_size < sizeof(Index)) { 2024c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Corrupt Index file"; 2025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (new_eviction_) { 2029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We support versions 2.0 and 2.1, upgrading 2.0 to 2.1. 2030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kIndexMagic != data_->header.magic || 2031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kCurrentVersion >> 16 != data_->header.version >> 16) { 2032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid file version or magic"; 2033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kCurrentVersion == data_->header.version) { 2036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We need file version 2.1 for the new eviction algorithm. 2037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott UpgradeTo2_1(); 2038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 2040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (kIndexMagic != data_->header.magic || 2041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kCurrentVersion != data_->header.version) { 2042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid file version or magic"; 2043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2047c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!data_->header.table_len) { 2048c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid table size"; 2049c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2050c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2051c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (current_size < GetIndexSize(data_->header.table_len) || 2053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_->header.table_len & (kBaseTableLen - 1)) { 2054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Corrupt Index file"; 2055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2058c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AdjustMaxCacheSize(data_->header.table_len); 2059c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (data_->header.num_bytes < 0 || 2061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (max_size_ < kint32max - kDefaultCacheSize && 2062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_->header.num_bytes > max_size_ + kDefaultCacheSize)) { 2063c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid cache (current) size"; 2064c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2065c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2066c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2067c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (data_->header.num_entries < 0) { 2068c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Invalid number of entries"; 2069c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 2070c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2071c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2072c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!mask_) 2073c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott mask_ = data_->header.table_len - 1; 2074c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Load the table into memory with a single read. 2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_array<char> buf(new char[current_size]); 2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return index_->Read(buf.get(), current_size, 0); 2078c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2079c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2080c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint BackendImpl::CheckAllEntries() { 2081c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_dirty = 0; 2082c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int num_entries = 0; 2083c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(mask_ < kuint32max); 2084c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i <= static_cast<int>(mask_); i++) { 2085c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(data_->table[i]); 2086c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!address.is_initialized()) 2087c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott continue; 2088c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (;;) { 2089c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool dirty; 2090c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EntryImpl* tmp; 2091c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret = NewEntry(address, &tmp, &dirty); 2092c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ret) 2093c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 2094c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<EntryImpl> cache_entry; 2095c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_entry.swap(&tmp); 2096c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2097c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dirty) 2098c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_dirty++; 2099c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else if (CheckEntry(cache_entry.get())) 2100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott num_entries++; 2101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 2102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_INVALID_ENTRY; 2103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott address.set_value(cache_entry->GetNextAddress()); 2105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!address.is_initialized()) 2106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 2107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 21103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Trace("CheckAllEntries End"); 2111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (num_entries + num_dirty != data_->header.num_entries) { 2112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Number of entries mismatch"; 2113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ERR_NUM_ENTRIES_MISMATCH; 2114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 2115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return num_dirty; 2117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BackendImpl::CheckEntry(EntryImpl* cache_entry) { 21203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool ok = block_files_.IsValid(cache_entry->entry()->address()); 21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ok = ok && block_files_.IsValid(cache_entry->rankings()->address()); 21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EntryStore* data = cache_entry->entry()->Data(); 21233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (size_t i = 0; i < arraysize(data->data_addr); i++) { 21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (data->data_addr[i]) { 21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Addr address(data->data_addr[i]); 21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (address.is_block_file()) 21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ok = ok && block_files_.IsValid(address); 21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 21293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RankingsNode* rankings = cache_entry->rankings()->Data(); 21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ok && !rankings->dummy; 21333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 21343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint BackendImpl::MaxBuffersSize() { 21363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static int64 total_memory = base::SysInfo::AmountOfPhysicalMemory(); 21373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static bool done = false; 21383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!done) { 21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kMaxBuffersSize = 30 * 1024 * 1024; 21413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // We want to use up to 2% of the computer's memory. 21433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick total_memory = total_memory * 2 / 100; 21443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (total_memory > kMaxBuffersSize || total_memory <= 0) 21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick total_memory = kMaxBuffersSize; 21463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick done = true; 21483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return static_cast<int>(total_memory); 2151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 2152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 2153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace disk_cache 2154