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 MemoryCache_h 26 #define MemoryCache_h 27 28 #include "core/fetch/Resource.h" 29 #include "public/platform/WebThread.h" 30 #include "wtf/HashMap.h" 31 #include "wtf/Noncopyable.h" 32 #include "wtf/Vector.h" 33 #include "wtf/text/StringHash.h" 34 #include "wtf/text/WTFString.h" 35 36 namespace WebCore { 37 38 class CSSStyleSheetResource; 39 class Resource; 40 class ResourceFetcher; 41 class KURL; 42 class ExecutionContext; 43 class SecurityOrigin; 44 struct SecurityOriginHash; 45 46 // This cache holds subresources used by Web pages: images, scripts, stylesheets, etc. 47 48 // The cache keeps a flexible but bounded window of dead resources that grows/shrinks 49 // depending on the live resource load. Here's an example of cache growth over time, 50 // with a min dead resource capacity of 25% and a max dead resource capacity of 50%: 51 52 // |-----| Dead: - 53 // |----------| Live: + 54 // --|----------| Cache boundary: | (objects outside this mark have been evicted) 55 // --|----------++++++++++| 56 // -------|-----+++++++++++++++| 57 // -------|-----+++++++++++++++|+++++ 58 59 // Enable this macro to periodically log information about the memory cache. 60 #undef MEMORY_CACHE_STATS 61 62 class MemoryCache : public blink::WebThread::TaskObserver { 63 WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED; 64 public: 65 MemoryCache(); 66 virtual ~MemoryCache(); 67 68 typedef HashMap<String, Resource*> ResourceMap; 69 70 struct LRUList { 71 Resource* m_head; 72 Resource* m_tail; LRUListLRUList73 LRUList() : m_head(0), m_tail(0) { } 74 }; 75 76 struct TypeStatistic { 77 int count; 78 int size; 79 int liveSize; 80 int decodedSize; 81 int encodedSize; 82 int encodedSizeDuplicatedInDataURLs; 83 int purgeableSize; 84 int purgedSize; 85 TypeStatisticTypeStatistic86 TypeStatistic() 87 : count(0) 88 , size(0) 89 , liveSize(0) 90 , decodedSize(0) 91 , encodedSize(0) 92 , encodedSizeDuplicatedInDataURLs(0) 93 , purgeableSize(0) 94 , purgedSize(0) 95 { 96 } 97 98 void addResource(Resource*); 99 }; 100 101 struct Statistics { 102 TypeStatistic images; 103 TypeStatistic cssStyleSheets; 104 TypeStatistic scripts; 105 TypeStatistic xslStyleSheets; 106 TypeStatistic fonts; 107 TypeStatistic other; 108 }; 109 110 Resource* resourceForURL(const KURL&); 111 112 void add(Resource*); 113 void replace(Resource* newResource, Resource* oldResource); remove(Resource * resource)114 void remove(Resource* resource) { evict(resource); } 115 116 static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL); 117 118 // Sets the cache's memory capacities, in bytes. These will hold only approximately, 119 // since the decoded cost of resources like scripts and stylesheets is not known. 120 // - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure. 121 // - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure. 122 // - totalBytes: The maximum number of bytes that the cache should consume overall. 123 void setCapacities(size_t minDeadBytes, size_t maxDeadBytes, size_t totalBytes); setDelayBeforeLiveDecodedPrune(double seconds)124 void setDelayBeforeLiveDecodedPrune(double seconds) { m_delayBeforeLiveDecodedPrune = seconds; } setMaxPruneDeferralDelay(double seconds)125 void setMaxPruneDeferralDelay(double seconds) { m_maxPruneDeferralDelay = seconds; } 126 127 void evictResources(); 128 129 void prune(Resource* justReleasedResource = 0); 130 131 // Calls to put the cached resource into and out of LRU lists. 132 void insertInLRUList(Resource*); 133 void removeFromLRUList(Resource*); 134 135 // Called to adjust the cache totals when a resource changes size. 136 void adjustSize(bool live, ptrdiff_t delta); 137 138 // Track decoded resources that are in the cache and referenced by a Web page. 139 void insertInLiveDecodedResourcesList(Resource*); 140 void removeFromLiveDecodedResourcesList(Resource*); 141 142 void addToLiveResourcesSize(Resource*); 143 void removeFromLiveResourcesSize(Resource*); 144 145 static void removeURLFromCache(ExecutionContext*, const KURL&); 146 147 Statistics getStatistics(); 148 minDeadCapacity()149 size_t minDeadCapacity() const { return m_minDeadCapacity; } maxDeadCapacity()150 size_t maxDeadCapacity() const { return m_maxDeadCapacity; } capacity()151 size_t capacity() const { return m_capacity; } liveSize()152 size_t liveSize() const { return m_liveSize; } deadSize()153 size_t deadSize() const { return m_deadSize; } 154 155 // TaskObserver implementation 156 virtual void willProcessTask() OVERRIDE; 157 virtual void didProcessTask() OVERRIDE; 158 159 private: 160 LRUList* lruListFor(Resource*); 161 162 #ifdef MEMORY_CACHE_STATS 163 void dumpStats(Timer<MemoryCache>*); 164 void dumpLRULists(bool includeLive) const; 165 #endif 166 167 size_t liveCapacity() const; 168 size_t deadCapacity() const; 169 170 // pruneDeadResources() - Flush decoded and encoded data from resources not referenced by Web pages. 171 // pruneLiveResources() - Flush decoded data from resources still referenced by Web pages. 172 void pruneDeadResources(); // Automatically decide how much to prune. 173 void pruneLiveResources(); 174 void pruneNow(double currentTime); 175 176 void evict(Resource*); 177 178 static void removeURLFromCacheInternal(ExecutionContext*, const KURL&); 179 180 bool m_inPruneResources; 181 bool m_prunePending; 182 bool m_prePainting; 183 double m_maxPruneDeferralDelay; 184 double m_pruneTimeStamp; 185 double m_pruneFrameTimeStamp; 186 187 size_t m_capacity; 188 size_t m_minDeadCapacity; 189 size_t m_maxDeadCapacity; 190 size_t m_maxDeferredPruneDeadCapacity; 191 double m_delayBeforeLiveDecodedPrune; 192 double m_deadDecodedDataDeletionInterval; 193 194 size_t m_liveSize; // The number of bytes currently consumed by "live" resources in the cache. 195 size_t 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" multiple versions of objects that are 199 // waiting to die when the clients referencing them go away. 200 Vector<LRUList, 32> m_allResources; 201 202 // Lists just for live resources with decoded data. Access to this list is based off of painting the resource. 203 // The lists are ordered by decode priority, with higher indices having higher priorities. 204 LRUList m_liveDecodedResources[Resource::CacheLiveResourcePriorityHigh + 1]; 205 206 // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 207 // referenced by a Web page). 208 HashMap<String, Resource*> m_resources; 209 210 friend class MemoryCacheTest; 211 #ifdef MEMORY_CACHE_STATS 212 Timer<MemoryCache> m_statsTimer; 213 #endif 214 }; 215 216 // Returns the global cache. 217 MemoryCache* memoryCache(); 218 219 // Sets the global cache, used to swap in a test instance. 220 void setMemoryCacheForTesting(MemoryCache*); 221 222 } 223 224 #endif 225