OSDN Git Service

Merge WebKit at r73109: Initial merge by git.
[android-x86/external-webkit.git] / WebCore / loader / cache / MemoryCache.h
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 "loader.h"
32 #include <wtf/HashMap.h>
33 #include <wtf/HashSet.h>
34 #include <wtf/Noncopyable.h>
35 #include <wtf/Vector.h>
36 #include <wtf/text/StringHash.h>
37
38 namespace WebCore  {
39
40 class CachedCSSStyleSheet;
41 class CachedResource;
42 class CachedResourceLoader;
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 // The behavior of the cache changes in the following way if shouldMakeResourcePurgeableOnEviction
59 // returns true.
60 //
61 // 1. Dead resources in the cache are kept in non-purgeable memory.
62 // 2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable and
63 //    keep the resources until the kernel reclaims the purgeable memory.
64 //
65 // By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood of
66 // the kernel claiming that memory and forcing us to refetch the resource (for example when a user
67 // presses back).
68 //
69 // And by having an unbounded number of resource objects using purgeable memory, we can use as much
70 // memory as is available on the machine. The trade-off here is that the CachedResource object (and
71 // its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly
72 // more memory use due to this.
73
74 class MemoryCache : public Noncopyable {
75 public:
76     friend MemoryCache* cache();
77
78     typedef HashMap<String, CachedResource*> CachedResourceMap;
79
80     struct LRUList {
81         CachedResource* m_head;
82         CachedResource* m_tail;
83         LRUList() : m_head(0), m_tail(0) { }
84     };
85
86     struct TypeStatistic {
87         int count;
88         int size;
89         int liveSize;
90         int decodedSize;
91         int purgeableSize;
92         int purgedSize;
93         TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { }
94         void addResource(CachedResource*);
95     };
96     
97     struct Statistics {
98         TypeStatistic images;
99         TypeStatistic cssStyleSheets;
100         TypeStatistic scripts;
101 #if ENABLE(XSLT)
102         TypeStatistic xslStyleSheets;
103 #endif
104         TypeStatistic fonts;
105     };
106
107     // The loader that fetches resources.
108     Loader* loader() { return &m_loader; }
109
110     // Request resources from the cache.  A load will be initiated and a cache object created if the object is not
111     // found in the cache.
112     CachedResource* requestResource(CachedResourceLoader*, CachedResource::Type, const KURL& url, const String& charset, bool isPreload = false, bool forHistory = false);
113
114     CachedCSSStyleSheet* requestUserCSSStyleSheet(CachedResourceLoader*, const String& url, const String& charset);
115     
116     void revalidateResource(CachedResource*, CachedResourceLoader*);
117     void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
118     void revalidationFailed(CachedResource* revalidatingResource);
119     
120     // Sets the cache's memory capacities, in bytes. These will hold only approximately, 
121     // since the decoded cost of resources like scripts and stylesheets is not known.
122     //  - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure.
123     //  - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure.
124     //  - totalBytes: The maximum number of bytes that the cache should consume overall.
125     void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes);
126
127     // Turn the cache on and off.  Disabling the cache will remove all resources from the cache.  They may
128     // still live on if they are referenced by some Web page though.
129     void setDisabled(bool);
130     bool disabled() const { return m_disabled; }
131     
132     void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
133     void prune()
134     {
135         if (m_liveSize + m_deadSize <= m_capacity && m_maxDeadCapacity && m_deadSize <= m_maxDeadCapacity) // Fast path.
136             return;
137             
138         pruneDeadResources(); // Prune dead first, in case it was "borrowing" capacity from live.
139         pruneLiveResources();
140     }
141
142     void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; }
143     double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
144
145     // Remove an existing cache entry from both the resource map and from the LRU list.
146     void remove(CachedResource* resource) { evict(resource); }
147
148     void addCachedResourceLoader(CachedResourceLoader*);
149     void removeCachedResourceLoader(CachedResourceLoader*);
150
151     CachedResource* resourceForURL(const String&);
152
153     // Calls to put the cached resource into and out of LRU lists.
154     void insertInLRUList(CachedResource*);
155     void removeFromLRUList(CachedResource*);
156
157     // Called to adjust the cache totals when a resource changes size.
158     void adjustSize(bool live, int delta);
159
160     // Track decoded resources that are in the cache and referenced by a Web page.
161     void insertInLiveDecodedResourcesList(CachedResource*);
162     void removeFromLiveDecodedResourcesList(CachedResource*);
163
164     void addToLiveResourcesSize(CachedResource*);
165     void removeFromLiveResourcesSize(CachedResource*);
166
167     static bool shouldMakeResourcePurgeableOnEviction();
168
169     // Function to collect cache statistics for the caches window in the Safari Debug menu.
170     Statistics getStatistics();
171
172 #ifdef ANDROID_INSTRUMENT
173     unsigned getLiveSize() { return m_liveSize; }
174     unsigned getDeadSize() { return m_deadSize; }
175 #endif
176
177 private:
178     MemoryCache();
179     ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
180        
181     LRUList* lruListFor(CachedResource*);
182     void resourceAccessed(CachedResource*);
183 #ifndef NDEBUG
184     void dumpStats();
185     void dumpLRULists(bool includeLive) const;
186 #endif
187
188     unsigned liveCapacity() const;
189     unsigned deadCapacity() const;
190     
191     void pruneDeadResources(); // Flush decoded and encoded data from resources not referenced by Web pages.
192     void pruneLiveResources(); // Flush decoded data from resources still referenced by Web pages.
193
194     bool makeResourcePurgeable(CachedResource*);
195     void evict(CachedResource*);
196
197     // Member variables.
198     HashSet<CachedResourceLoader*> m_cachedResourceLoaders;
199     Loader m_loader;
200
201     bool m_disabled;  // Whether or not the cache is enabled.
202     bool m_pruneEnabled;
203     bool m_inPruneDeadResources;
204
205     unsigned m_capacity;
206     unsigned m_minDeadCapacity;
207     unsigned m_maxDeadCapacity;
208     double m_deadDecodedDataDeletionInterval;
209
210     unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
211     unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
212
213     // Size-adjusted and popularity-aware LRU list collection for cache objects.  This collection can hold
214     // more resources than the cached resource map, since it can also hold "stale" multiple versions of objects that are
215     // waiting to die when the clients referencing them go away.
216     Vector<LRUList, 32> m_allResources;
217     
218     // List just for live resources with decoded data.  Access to this list is based off of painting the resource.
219     LRUList m_liveDecodedResources;
220     
221     // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 
222     // referenced by a Web page).
223     HashMap<String, CachedResource*> m_resources;
224 };
225
226 inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
227 {
228 #if PLATFORM(IOS)
229     return true;
230 #else
231     return false;
232 #endif
233 }
234
235 // Function to obtain the global cache.
236 MemoryCache* cache();
237
238 }
239
240 #endif