[WK2] Improve serialization of SubresourcesEntry to network disk cache
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Jun 2016 23:39:29 +0000 (23:39 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Jun 2016 23:39:29 +0000 (23:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158851

Reviewed by Antti Koivisto.

Improve serialization of SubresourcesEntry to network disk cache:
- Do not bother serializing SubresourceInfo's first party for cookies
  and HTTP headers data members if the resource is transient. This is
  because those are never used for transient resources. This patch also
  makes it so that we do not even bother initializing those data members
  if the transient flag is set.
- Update SubresourceInfo::encode() / decode() to encode and decode
  the HTTPHeaderMap data member with the right NetworkCache::Coder
  template specialization instead of using directly HTTPHeaderMap::decode()
  and HTTPHeaderMap::encode(). HTTPHeaderMap::decode() / encode() is
  unsafe in the disk cache case (see r200394).

Also update entry types as so:
- "resource" -> "Resource"
- "subresources" -> "SubResources"

These entry types are used a folder names in the disk cache and other
folder names were capitalized. Antti suggested this was a good time
to harmonize since we're bumping the cache version.

* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
(WebKit::NetworkCache::constructRevalidationRequest):
(WebKit::NetworkCache::SpeculativeLoadManager::startSpeculativeRevalidation):
* NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:
* NetworkProcess/cache/NetworkCacheStorage.h:
* NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
(WebKit::NetworkCache::SubresourceInfo::encode):
(WebKit::NetworkCache::SubresourceInfo::decode):
* NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
(WebKit::NetworkCache::SubresourceInfo::SubresourceInfo):
(WebKit::NetworkCache::SubresourceInfo::isTransient):
(WebKit::NetworkCache::SubresourceInfo::firstPartyForCookies):
(WebKit::NetworkCache::SubresourceInfo::requestHeaders):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@202148 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h
Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h
Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp
Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h

index 98f3704..017ae83 100644 (file)
@@ -1,3 +1,44 @@
+2016-06-16  Chris Dumez  <cdumez@apple.com>
+
+        [WK2] Improve serialization of SubresourcesEntry to network disk cache
+        https://bugs.webkit.org/show_bug.cgi?id=158851
+
+        Reviewed by Antti Koivisto.
+
+        Improve serialization of SubresourcesEntry to network disk cache:
+        - Do not bother serializing SubresourceInfo's first party for cookies
+          and HTTP headers data members if the resource is transient. This is
+          because those are never used for transient resources. This patch also
+          makes it so that we do not even bother initializing those data members
+          if the transient flag is set.
+        - Update SubresourceInfo::encode() / decode() to encode and decode
+          the HTTPHeaderMap data member with the right NetworkCache::Coder
+          template specialization instead of using directly HTTPHeaderMap::decode()
+          and HTTPHeaderMap::encode(). HTTPHeaderMap::decode() / encode() is
+          unsafe in the disk cache case (see r200394).
+
+        Also update entry types as so:
+        - "resource" -> "Resource"
+        - "subresources" -> "SubResources"
+
+        These entry types are used a folder names in the disk cache and other
+        folder names were capitalized. Antti suggested this was a good time
+        to harmonize since we're bumping the cache version.
+
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+        (WebKit::NetworkCache::constructRevalidationRequest):
+        (WebKit::NetworkCache::SpeculativeLoadManager::startSpeculativeRevalidation):
+        * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:
+        * NetworkProcess/cache/NetworkCacheStorage.h:
+        * NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
+        (WebKit::NetworkCache::SubresourceInfo::encode):
+        (WebKit::NetworkCache::SubresourceInfo::decode):
+        * NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
+        (WebKit::NetworkCache::SubresourceInfo::SubresourceInfo):
+        (WebKit::NetworkCache::SubresourceInfo::isTransient):
+        (WebKit::NetworkCache::SubresourceInfo::firstPartyForCookies):
+        (WebKit::NetworkCache::SubresourceInfo::requestHeaders):
+
 2016-06-16  Anders Carlsson  <andersca@apple.com>
 
         Fix macOS Sierra build
index 367b859..1f8e820 100644 (file)
@@ -55,7 +55,7 @@ namespace NetworkCache {
 static const AtomicString& resourceType()
 {
     ASSERT(WTF::isMainThread());
-    static NeverDestroyed<const AtomicString> resource("resource", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const AtomicString> resource("Resource", AtomicString::ConstructFromLiteral);
     return resource;
 }
 
index b978b99..47ff0fa 100644 (file)
@@ -46,7 +46,7 @@ Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, RefPtr<W
     , m_varyingRequestHeaders(varyingRequestHeaders)
     , m_buffer(WTFMove(buffer))
 {
-    ASSERT(m_key.type() == "resource");
+    ASSERT(m_key.type() == "Resource");
 }
 
 Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest& redirectRequest, const Vector<std::pair<String, String>>& varyingRequestHeaders)
@@ -55,7 +55,7 @@ Entry::Entry(const Key& key, const WebCore::ResourceResponse& response, const We
     , m_response(response)
     , m_varyingRequestHeaders(varyingRequestHeaders)
 {
-    ASSERT(m_key.type() == "resource");
+    ASSERT(m_key.type() == "Resource");
     // Redirect body is not needed even if exists.
 
     m_redirectRequest = std::make_unique<WebCore::ResourceRequest>();
@@ -78,7 +78,7 @@ Entry::Entry(const Storage::Record& storageEntry)
     , m_timeStamp(storageEntry.timeStamp)
     , m_sourceStorageRecord(storageEntry)
 {
-    ASSERT(m_key.type() == "resource");
+    ASSERT(m_key.type() == "Resource");
 }
 
 Storage::Record Entry::encodeAsStorageRecord() const
index 16d8555..e60f1fb 100644 (file)
@@ -75,7 +75,7 @@ static void logSpeculativeLoadingDiagnosticMessage(const GlobalFrameID& frameID,
 static const AtomicString& subresourcesType()
 {
     ASSERT(RunLoop::isMain());
-    static NeverDestroyed<const AtomicString> resource("subresources", AtomicString::ConstructFromLiteral);
+    static NeverDestroyed<const AtomicString> resource("SubResources", AtomicString::ConstructFromLiteral);
     return resource;
 }
 
@@ -87,8 +87,8 @@ static inline Key makeSubresourcesKey(const Key& resourceKey)
 static inline ResourceRequest constructRevalidationRequest(const Entry& entry, const SubresourceInfo& subResourceInfo)
 {
     ResourceRequest revalidationRequest(entry.key().identifier());
-    revalidationRequest.setHTTPHeaderFields(subResourceInfo.requestHeaders);
-    revalidationRequest.setFirstPartyForCookies(subResourceInfo.firstPartyForCookies);
+    revalidationRequest.setHTTPHeaderFields(subResourceInfo.requestHeaders());
+    revalidationRequest.setFirstPartyForCookies(subResourceInfo.firstPartyForCookies());
 #if ENABLE(CACHE_PARTITIONING)
     if (entry.key().hasPartition())
         revalidationRequest.setCachePartition(entry.key().partition());
@@ -504,7 +504,7 @@ void SpeculativeLoadManager::startSpeculativeRevalidation(const GlobalFrameID& f
     for (auto& subresourcePair : entry.subresources()) {
         auto& key = subresourcePair.key;
         auto& subresourceInfo = subresourcePair.value;
-        if (!subresourceInfo.isTransient)
+        if (!subresourceInfo.isTransient())
             preloadEntry(key, subresourceInfo, frameID);
         else {
             LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Not preloading '%s' because it is marked as transient", key.identifier().utf8().data());
@@ -518,7 +518,7 @@ void SpeculativeLoadManager::startSpeculativeRevalidation(const GlobalFrameID& f
 
 void SpeculativeLoadManager::retrieveSubresourcesEntry(const Key& storageKey, std::function<void (std::unique_ptr<SubresourcesEntry>)>&& completionHandler)
 {
-    ASSERT(storageKey.type() == "resource");
+    ASSERT(storageKey.type() == "Resource");
     auto subresourcesStorageKey = makeSubresourcesKey(storageKey);
     m_storage.retrieve(subresourcesStorageKey, static_cast<unsigned>(ResourceLoadPriority::Medium), [completionHandler = WTFMove(completionHandler)](auto record) {
         if (!record) {
index 6efde22..4255236 100644 (file)
@@ -40,8 +40,8 @@ namespace NetworkCache {
 
 class Entry;
 class SpeculativeLoad;
+class SubresourceInfo;
 class SubresourcesEntry;
-struct SubresourceInfo;
 
 class SpeculativeLoadManager {
     WTF_MAKE_FAST_ALLOCATED;
index 1d0824d..e8dc643 100644 (file)
@@ -141,7 +141,7 @@ void Statistics::bootstrapFromNetworkCache(const String& networkCachePath)
     LOG(NetworkCache, "(NetworkProcess) Bootstrapping the network cache statistics database from the network cache...");
 
     HashSet<String> hashes;
-    traverseRecordsFiles(networkCachePath, ASCIILiteral("resource"), [&hashes](const String& fileName, const String& hashString, const String& type, bool isBodyBlob, const String& recordDirectoryPath) {
+    traverseRecordsFiles(networkCachePath, ASCIILiteral("Resource"), [&hashes](const String& fileName, const String& hashString, const String& type, bool isBodyBlob, const String& recordDirectoryPath) {
         if (isBodyBlob)
             return;
 
index e25d38c..7a8bfad 100644 (file)
@@ -87,7 +87,7 @@ public:
     size_t capacity() const { return m_capacity; }
     size_t approximateSize() const;
 
-    static const unsigned version = 7;
+    static const unsigned version = 8;
 
     String basePath() const;
     String versionPath() const;
index a28cbca..4726979 100644 (file)
@@ -38,19 +38,30 @@ namespace NetworkCache {
 
 void SubresourceInfo::encode(Encoder& encoder) const
 {
-    encoder << firstPartyForCookies;
-    encoder << isTransient;
-    requestHeaders.encode(encoder);
+    encoder << m_isTransient;
+
+    // Do not bother serializing other data members of transient resources as they are empty.
+    if (m_isTransient)
+        return;
+
+    encoder << m_firstPartyForCookies;
+    encoder << m_requestHeaders;
 }
 
 bool SubresourceInfo::decode(Decoder& decoder, SubresourceInfo& info)
 {
-    if (!decoder.decode(info.firstPartyForCookies))
+    if (!decoder.decode(info.m_isTransient))
         return false;
-    if (!decoder.decode(info.isTransient))
+
+    if (info.m_isTransient)
+        return true;
+
+    if (!decoder.decode(info.m_firstPartyForCookies))
         return false;
-    if (!WebCore::HTTPHeaderMap::decode(decoder, info.requestHeaders))
+
+    if (!decoder.decode(info.m_requestHeaders))
         return false;
+
     return true;
 }
 
@@ -84,14 +95,14 @@ SubresourcesEntry::SubresourcesEntry(const Storage::Record& storageEntry)
     : m_key(storageEntry.key)
     , m_timeStamp(storageEntry.timeStamp)
 {
-    ASSERT(m_key.type() == "subresources");
+    ASSERT(m_key.type() == "SubResources");
 }
 
 SubresourcesEntry::SubresourcesEntry(Key&& key, const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
     : m_key(WTFMove(key))
     , m_timeStamp(std::chrono::system_clock::now())
 {
-    ASSERT(m_key.type() == "subresources");
+    ASSERT(m_key.type() == "SubResources");
     for (auto& subresourceLoad : subresourceLoads)
         m_subresources.add(subresourceLoad->key, SubresourceInfo(subresourceLoad->request));
 }
index 65c35b0..007f705 100644 (file)
 namespace WebKit {
 namespace NetworkCache {
 
-struct SubresourceInfo {
+class SubresourceInfo {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-
     void encode(Encoder&) const;
     static bool decode(Decoder&, SubresourceInfo&);
 
     SubresourceInfo() = default;
     SubresourceInfo(const WebCore::ResourceRequest& request, bool isTransient = false)
-        : firstPartyForCookies(request.firstPartyForCookies())
-        , requestHeaders(request.httpHeaderFields())
-        , isTransient(isTransient)
-    { }
+        : m_isTransient(isTransient)
+        , m_firstPartyForCookies(isTransient ? WebCore::URL() : request.firstPartyForCookies())
+        , m_requestHeaders(isTransient ? WebCore::HTTPHeaderMap() : request.httpHeaderFields())
+    {
+    }
 
-    WebCore::URL firstPartyForCookies;
-    WebCore::HTTPHeaderMap requestHeaders;
-    bool isTransient { false };
+    bool isTransient() const { return m_isTransient; }
+    const WebCore::URL& firstPartyForCookies() const { ASSERT(!m_isTransient); return m_firstPartyForCookies; }
+    const WebCore::HTTPHeaderMap& requestHeaders() const { ASSERT(!m_isTransient); return m_requestHeaders; }
+
+private:
+    bool m_isTransient { true };
+    WebCore::URL m_firstPartyForCookies;
+    WebCore::HTTPHeaderMap m_requestHeaders;
 };
 
 struct SubresourceLoad {