1 /* 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 3 Copyright (C) 2001 Dirk Mueller <mueller@kde.org> 4 Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public License 17 along with this library; see the file COPYING.LIB. If not, write to 18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20 21 This class provides all functionality needed for loading images, style sheets and html 22 pages from the web. It has a memory cache for these objects. 23 */ 24 25 #ifndef Cache_h 26 #define Cache_h 27 28 #include "CachePolicy.h" 29 #include "CachedResource.h" 30 #include "PlatformString.h" 31 #include "StringHash.h" 32 #include "loader.h" 33 #include <wtf/HashMap.h> 34 #include <wtf/HashSet.h> 35 #include <wtf/Noncopyable.h> 36 #include <wtf/Vector.h> 37 38 namespace WebCore { 39 40 class CachedCSSStyleSheet; 41 class CachedResource; 42 class DocLoader; 43 class KURL; 44 45 // This cache holds subresources used by Web pages: images, scripts, stylesheets, etc. 46 47 // The cache keeps a flexible but bounded window of dead resources that grows/shrinks 48 // depending on the live resource load. Here's an example of cache growth over time, 49 // with a min dead resource capacity of 25% and a max dead resource capacity of 50%: 50 51 // |-----| Dead: - 52 // |----------| Live: + 53 // --|----------| Cache boundary: | (objects outside this mark have been evicted) 54 // --|----------++++++++++| 55 // -------|-----+++++++++++++++| 56 // -------|-----+++++++++++++++|+++++ 57 58 class Cache : Noncopyable { 59 public: 60 friend Cache* cache(); 61 62 typedef HashMap<String, CachedResource*> CachedResourceMap; 63 64 struct LRUList { 65 CachedResource* m_head; 66 CachedResource* m_tail; LRUListLRUList67 LRUList() : m_head(0), m_tail(0) { } 68 }; 69 70 struct TypeStatistic { 71 int count; 72 int size; 73 int liveSize; 74 int decodedSize; 75 int purgeableSize; 76 int purgedSize; TypeStatisticTypeStatistic77 TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { } 78 void addResource(CachedResource*); 79 }; 80 81 struct Statistics { 82 TypeStatistic images; 83 TypeStatistic cssStyleSheets; 84 TypeStatistic scripts; 85 #if ENABLE(XSLT) 86 TypeStatistic xslStyleSheets; 87 #endif 88 #if ENABLE(XBL) 89 TypeStatistic xblDocs; 90 #endif 91 TypeStatistic fonts; 92 }; 93 94 // The loader that fetches resources. loader()95 Loader* loader() { return &m_loader; } 96 97 // Request resources from the cache. A load will be initiated and a cache object created if the object is not 98 // found in the cache. 99 CachedResource* requestResource(DocLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false); 100 101 CachedCSSStyleSheet* requestUserCSSStyleSheet(DocLoader*, const String& url, const String& charset); 102 103 void revalidateResource(CachedResource*, DocLoader*); 104 void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&); 105 void revalidationFailed(CachedResource* revalidatingResource); 106 107 // Sets the cache's memory capacities, in bytes. These will hold only approximately, 108 // since the decoded cost of resources like scripts and stylesheets is not known. 109 // - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure. 110 // - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure. 111 // - totalBytes: The maximum number of bytes that the cache should consume overall. 112 void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes); 113 114 // Turn the cache on and off. Disabling the cache will remove all resources from the cache. They may 115 // still live on if they are referenced by some Web page though. 116 void setDisabled(bool); disabled()117 bool disabled() const { return m_disabled; } 118 setPruneEnabled(bool enabled)119 void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; } prune()120 void prune() 121 { 122 if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path. 123 return; 124 125 pruneDeadResources(); // Prune dead first, in case it was "borrowing" capacity from live. 126 pruneLiveResources(); 127 } 128 setDeadDecodedDataDeletionInterval(double interval)129 void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; } deadDecodedDataDeletionInterval()130 double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; } 131 132 // Remove an existing cache entry from both the resource map and from the LRU list. remove(CachedResource * resource)133 void remove(CachedResource* resource) { evict(resource); } 134 135 void addDocLoader(DocLoader*); 136 void removeDocLoader(DocLoader*); 137 138 CachedResource* resourceForURL(const String&); 139 140 // Calls to put the cached resource into and out of LRU lists. 141 void insertInLRUList(CachedResource*); 142 void removeFromLRUList(CachedResource*); 143 144 // Called to adjust the cache totals when a resource changes size. 145 void adjustSize(bool live, int delta); 146 147 // Track decoded resources that are in the cache and referenced by a Web page. 148 void insertInLiveDecodedResourcesList(CachedResource*); 149 void removeFromLiveDecodedResourcesList(CachedResource*); 150 151 void addToLiveResourcesSize(CachedResource*); 152 void removeFromLiveResourcesSize(CachedResource*); 153 154 // Function to collect cache statistics for the caches window in the Safari Debug menu. 155 Statistics getStatistics(); 156 157 #ifdef ANDROID_INSTRUMENT getLiveSize()158 unsigned getLiveSize() { return m_liveSize; } getDeadSize()159 unsigned getDeadSize() { return m_deadSize; } 160 #endif 161 162 private: 163 Cache(); 164 ~Cache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons. 165 166 LRUList* lruListFor(CachedResource*); 167 void resourceAccessed(CachedResource*); 168 #ifndef NDEBUG 169 void dumpStats(); 170 void dumpLRULists(bool includeLive) const; 171 #endif 172 173 unsigned liveCapacity() const; 174 unsigned deadCapacity() const; 175 176 void pruneDeadResources(); // Flush decoded and encoded data from resources not referenced by Web pages. 177 void pruneLiveResources(); // Flush decoded data from resources still referenced by Web pages. 178 179 void evict(CachedResource*); 180 181 // Member variables. 182 HashSet<DocLoader*> m_docLoaders; 183 Loader m_loader; 184 185 bool m_disabled; // Whether or not the cache is enabled. 186 bool m_pruneEnabled; 187 bool m_inPruneDeadResources; 188 189 unsigned m_capacity; 190 unsigned m_minDeadCapacity; 191 unsigned m_maxDeadCapacity; 192 double m_deadDecodedDataDeletionInterval; 193 194 unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache. 195 unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache. 196 197 // Size-adjusted and popularity-aware LRU list collection for cache objects. This collection can hold 198 // more resources than the cached resource map, since it can also hold "stale" muiltiple versions of objects that are 199 // waiting to die when the clients referencing them go away. 200 Vector<LRUList, 32> m_allResources; 201 202 // List just for live resources with decoded data. Access to this list is based off of painting the resource. 203 LRUList m_liveDecodedResources; 204 205 // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 206 // referenced by a Web page). 207 HashMap<String, CachedResource*> m_resources; 208 }; 209 210 // Function to obtain the global cache. 211 Cache* cache(); 212 213 } 214 215 #endif 216