initial import
[vuplus_webkit] / Source / 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 "CachedResource.h"
29 #include "PlatformString.h"
30 #include <wtf/HashMap.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/Noncopyable.h>
33 #include <wtf/Vector.h>
34 #include <wtf/text/StringHash.h>
35
36 namespace WebCore  {
37
38 class CachedCSSStyleSheet;
39 class CachedResource;
40 class CachedResourceLoader;
41 class KURL;
42 class SecurityOrigin;
43 struct SecurityOriginHash;
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 {
75     WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
76 public:
77     friend MemoryCache* memoryCache();
78
79     typedef HashMap<String, CachedResource*> CachedResourceMap;
80
81     struct LRUList {
82         CachedResource* m_head;
83         CachedResource* m_tail;
84         LRUList() : m_head(0), m_tail(0) { }
85     };
86
87     struct TypeStatistic {
88         int count;
89         int size;
90         int liveSize;
91         int decodedSize;
92         int purgeableSize;
93         int purgedSize;
94         TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { }
95         void addResource(CachedResource*);
96     };
97     
98     struct Statistics {
99         TypeStatistic images;
100         TypeStatistic cssStyleSheets;
101         TypeStatistic scripts;
102         TypeStatistic xslStyleSheets;
103         TypeStatistic fonts;
104     };
105     
106     CachedResource* resourceForURL(const KURL&);
107     
108     bool add(CachedResource* resource);
109     void remove(CachedResource* resource) { evict(resource); }
110
111     static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
112     
113     void revalidationSucceeded(CachedResource* revalidatingResource, const ResourceResponse&);
114     void revalidationFailed(CachedResource* revalidatingResource);
115     
116     // Sets the cache's memory capacities, in bytes. These will hold only approximately, 
117     // since the decoded cost of resources like scripts and stylesheets is not known.
118     //  - minDeadBytes: The maximum number of bytes that dead resources should consume when the cache is under pressure.
119     //  - maxDeadBytes: The maximum number of bytes that dead resources should consume when the cache is not under pressure.
120     //  - totalBytes: The maximum number of bytes that the cache should consume overall.
121     void setCapacities(unsigned minDeadBytes, unsigned maxDeadBytes, unsigned totalBytes);
122
123     // Turn the cache on and off.  Disabling the cache will remove all resources from the cache.  They may
124     // still live on if they are referenced by some Web page though.
125     void setDisabled(bool);
126     bool disabled() const { return m_disabled; }
127
128     void evictResources();
129     
130     void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
131     void prune();
132     void pruneToPercentage(float targetPercentLive);
133
134     void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; }
135     double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
136
137     void addCachedResourceLoader(CachedResourceLoader*);
138     void removeCachedResourceLoader(CachedResourceLoader*);
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     static bool shouldMakeResourcePurgeableOnEviction();
155
156     // Function to collect cache statistics for the caches window in the Safari Debug menu.
157     Statistics getStatistics();
158     
159     void resourceAccessed(CachedResource*);
160
161     typedef HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash> SecurityOriginSet;
162     void removeResourcesWithOrigin(SecurityOrigin*);
163     void getOriginsWithCache(SecurityOriginSet& origins);
164
165 private:
166     MemoryCache();
167     ~MemoryCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
168        
169     LRUList* lruListFor(CachedResource*);
170 #ifndef NDEBUG
171     void dumpStats();
172     void dumpLRULists(bool includeLive) const;
173 #endif
174
175     unsigned liveCapacity() const;
176     unsigned deadCapacity() const;
177
178     // pruneDead*() - Flush decoded and encoded data from resources not referenced by Web pages.
179     // pruneLive*() - Flush decoded data from resources still referenced by Web pages.
180     void pruneDeadResources(); // Automatically decide how much to prune.
181     void pruneLiveResources();
182     void pruneDeadResourcesToPercentage(float prunePercentage); // Prune to % current size
183     void pruneLiveResourcesToPercentage(float prunePercentage);
184     void pruneDeadResourcesToSize(unsigned targetSize);
185     void pruneLiveResourcesToSize(unsigned targetSize);
186
187     bool makeResourcePurgeable(CachedResource*);
188     void evict(CachedResource*);
189
190     bool m_disabled;  // Whether or not the cache is enabled.
191     bool m_pruneEnabled;
192     bool m_inPruneDeadResources;
193
194     unsigned m_capacity;
195     unsigned m_minDeadCapacity;
196     unsigned m_maxDeadCapacity;
197     double m_deadDecodedDataDeletionInterval;
198
199     unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
200     unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
201
202     // Size-adjusted and popularity-aware LRU list collection for cache objects.  This collection can hold
203     // more resources than the cached resource map, since it can also hold "stale" multiple versions of objects that are
204     // waiting to die when the clients referencing them go away.
205     Vector<LRUList, 32> m_allResources;
206     
207     // List just for live resources with decoded data.  Access to this list is based off of painting the resource.
208     LRUList m_liveDecodedResources;
209     
210     // A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being 
211     // referenced by a Web page).
212     HashMap<String, CachedResource*> m_resources;
213 };
214
215 inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
216 {
217 #if PLATFORM(IOS)
218     return true;
219 #else
220     return false;
221 #endif
222 }
223
224 // Function to obtain the global cache.
225 MemoryCache* memoryCache();
226
227 }
228
229 #endif