0
|
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 : public 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;
|
|
67 |
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;
|
|
77 |
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.
|
|
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);
|
|
117 |
bool disabled() const { return m_disabled; }
|
|
118 |
|
|
119 |
void setPruneEnabled(bool enabled) { m_pruneEnabled = enabled; }
|
|
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 |
|
|
129 |
void setDeadDecodedDataDeletionInterval(double interval) { m_deadDecodedDataDeletionInterval = interval; }
|
|
130 |
double deadDecodedDataDeletionInterval() const { return m_deadDecodedDataDeletionInterval; }
|
|
131 |
|
|
132 |
// Remove an existing cache entry from both the resource map and from the LRU list.
|
|
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 |
private:
|
|
158 |
Cache();
|
|
159 |
~Cache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
|
|
160 |
|
|
161 |
LRUList* lruListFor(CachedResource*);
|
|
162 |
void resourceAccessed(CachedResource*);
|
|
163 |
#ifndef NDEBUG
|
|
164 |
void dumpStats();
|
|
165 |
void dumpLRULists(bool includeLive) const;
|
|
166 |
#endif
|
|
167 |
|
|
168 |
unsigned liveCapacity() const;
|
|
169 |
unsigned deadCapacity() const;
|
|
170 |
|
|
171 |
void pruneDeadResources(); // Flush decoded and encoded data from resources not referenced by Web pages.
|
|
172 |
void pruneLiveResources(); // Flush decoded data from resources still referenced by Web pages.
|
|
173 |
|
|
174 |
void evict(CachedResource*);
|
|
175 |
|
|
176 |
// Member variables.
|
|
177 |
HashSet<DocLoader*> m_docLoaders;
|
|
178 |
Loader m_loader;
|
|
179 |
|
|
180 |
bool m_disabled; // Whether or not the cache is enabled.
|
|
181 |
bool m_pruneEnabled;
|
|
182 |
bool m_inPruneDeadResources;
|
|
183 |
|
|
184 |
unsigned m_capacity;
|
|
185 |
unsigned m_minDeadCapacity;
|
|
186 |
unsigned m_maxDeadCapacity;
|
|
187 |
double m_deadDecodedDataDeletionInterval;
|
|
188 |
|
|
189 |
unsigned m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
|
|
190 |
unsigned m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
|
|
191 |
|
|
192 |
// Size-adjusted and popularity-aware LRU list collection for cache objects. This collection can hold
|
|
193 |
// more resources than the cached resource map, since it can also hold "stale" muiltiple versions of objects that are
|
|
194 |
// waiting to die when the clients referencing them go away.
|
|
195 |
Vector<LRUList, 32> m_allResources;
|
|
196 |
|
|
197 |
// List just for live resources with decoded data. Access to this list is based off of painting the resource.
|
|
198 |
LRUList m_liveDecodedResources;
|
|
199 |
|
|
200 |
// A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being
|
|
201 |
// referenced by a Web page).
|
|
202 |
HashMap<String, CachedResource*> m_resources;
|
|
203 |
};
|
|
204 |
|
|
205 |
// Function to obtain the global cache.
|
|
206 |
Cache* cache();
|
|
207 |
|
|
208 |
}
|
|
209 |
|
|
210 |
#endif
|