• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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