• 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 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