Home | History | Annotate | Download | only in fetch
      1 /*
      2     Copyright (C) 1998 Lars Knoll (knoll (at) mpi-hd.mpg.de)
      3     Copyright (C) 2001 Dirk Mueller <mueller (at) 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;
     73         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 
     86         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);
    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);
    124     void setDelayBeforeLiveDecodedPrune(double seconds) { m_delayBeforeLiveDecodedPrune = 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 
    149     size_t minDeadCapacity() const { return m_minDeadCapacity; }
    150     size_t maxDeadCapacity() const { return m_maxDeadCapacity; }
    151     size_t capacity() const { return m_capacity; }
    152     size_t liveSize() const { return m_liveSize; }
    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