Diff
Modified: trunk/Source/WebKit2/ChangeLog (211479 => 211480)
--- trunk/Source/WebKit2/ChangeLog 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/ChangeLog 2017-02-01 13:38:49 UTC (rev 211480)
@@ -1,3 +1,74 @@
+2017-02-01 Antti Koivisto <an...@apple.com>
+
+ Load resources speculatively
+ https://bugs.webkit.org/show_bug.cgi?id=167660
+
+ Reviewed by Andreas Kling.
+
+ * NetworkProcess/cache/NetworkCache.cpp:
+ (WebKit::NetworkCache::Cache::makeEntry):
+
+ Factor to a function.
+
+ (WebKit::NetworkCache::Cache::store):
+ * NetworkProcess/cache/NetworkCache.h:
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp:
+ (WebKit::NetworkCache::SpeculativeLoad::SpeculativeLoad):
+
+ Support loads where we don't have existing cache entry to validate.
+
+ (WebKit::NetworkCache::SpeculativeLoad::didReceiveBuffer):
+
+ Synthesize a NetworkCache::Entry if we can't store it.
+
+ (WebKit::NetworkCache::SpeculativeLoad::didFinishLoading):
+ (WebKit::NetworkCache::SpeculativeLoad::didFailLoading):
+ (WebKit::NetworkCache::SpeculativeLoad::abort):
+ (WebKit::NetworkCache::SpeculativeLoad::didComplete):
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoad.h:
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp:
+ (WebKit::NetworkCache::constructRevalidationRequest):
+
+ Make having existing cache entry optional.
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::retrieveEntryFromStorage):
+
+ Allow validation without validation headers (that is, normal load).
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::revalidateSubresource):
+
+ Make having existing cache entry optional.
+
+ (WebKit::NetworkCache::canRevalidate):
+
+ Allow speculative loads without validation headers if we have high confidence that the
+ page is going to request this resource again. This is based on the time span we have
+ seen this resource being loaded on a given page and how much time has elapsed since we
+ last loaded it.
+
+ For example if we have seen the resource over the last 10 days we'll speculate that it will
+ be required for the next 5 days.
+
+ (WebKit::NetworkCache::SpeculativeLoadManager::preloadEntry):
+ (WebKit::NetworkCache::SpeculativeLoadManager::revalidateEntry): Deleted.
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h:
+ * NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp:
+ (WebKit::NetworkCache::SubresourceInfo::encode):
+ (WebKit::NetworkCache::SubresourceInfo::decode):
+
+ Encode the firstSeen and lastSeen time stamps.
+
+ (WebKit::NetworkCache::SubresourceInfo::SubresourceInfo):
+ (WebKit::NetworkCache::makeSubresourceInfoVector):
+ (WebKit::NetworkCache::SubresourcesEntry::SubresourcesEntry):
+ (WebKit::NetworkCache::SubresourcesEntry::updateSubresourceLoads):
+ * NetworkProcess/cache/NetworkCacheSubresourcesEntry.h:
+ (WebKit::NetworkCache::SubresourceInfo::lastSeen):
+ (WebKit::NetworkCache::SubresourceInfo::firstSeen):
+ (WebKit::NetworkCache::SubresourceInfo::setNonTransient):
+ (WebKit::NetworkCache::SubresourceInfo::SubresourceInfo): Deleted.
+ (WebKit::NetworkCache::SubresourceInfo::setTransient): Deleted.
+
2017-02-01 Csaba Osztrogonác <o...@webkit.org>
[Mac][cmake] Unreviewed speculative buildfix after r211403.
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp 2017-02-01 13:38:49 UTC (rev 211480)
@@ -389,6 +389,12 @@
});
}
+
+std::unique_ptr<Entry> Cache::makeEntry(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData)
+{
+ return std::make_unique<Entry>(makeCacheKey(request), response, WTFMove(responseData), WebCore::collectVaryingRequestHeaders(request, response));
+}
+
std::unique_ptr<Entry> Cache::store(const WebCore::ResourceRequest& request, const WebCore::ResourceResponse& response, RefPtr<WebCore::SharedBuffer>&& responseData, Function<void (MappedBody&)>&& completionHandler)
{
ASSERT(isEnabled());
@@ -413,7 +419,7 @@
return nullptr;
}
- auto cacheEntry = std::make_unique<Entry>(makeCacheKey(request), response, WTFMove(responseData), WebCore::collectVaryingRequestHeaders(request, response));
+ auto cacheEntry = makeEntry(request, response, WTFMove(responseData));
auto record = cacheEntry->encodeAsStorageRecord();
m_storage->store(record, [completionHandler = WTFMove(completionHandler)](const Data& bodyData) {
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h 2017-02-01 13:38:49 UTC (rev 211480)
@@ -123,6 +123,8 @@
void retrieveData(const DataKey&, Function<void (const uint8_t* data, size_t size)>);
void storeData(const DataKey&, const uint8_t* data, size_t);
+
+ std::unique_ptr<Entry> makeEntry(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&);
void dumpContentsToFile();
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.cpp 2017-02-01 13:38:49 UTC (rev 211480)
@@ -46,10 +46,9 @@
, m_completionHandler(WTFMove(completionHandler))
, m_originalRequest(request)
, m_bufferedDataForCache(SharedBuffer::create())
- , m_cacheEntryForValidation(WTFMove(cacheEntryForValidation))
+ , m_cacheEntry(WTFMove(cacheEntryForValidation))
{
- ASSERT(m_cacheEntryForValidation);
- ASSERT(m_cacheEntryForValidation->needsValidation());
+ ASSERT(!m_cacheEntry || m_cacheEntry->needsValidation());
NetworkLoadParameters parameters;
parameters.sessionID = SessionID::defaultSessionID();
@@ -82,13 +81,11 @@
if (m_response.isMultipart())
m_bufferedDataForCache = nullptr;
- ASSERT(m_cacheEntryForValidation);
-
bool validationSucceeded = m_response.httpStatusCode() == 304; // 304 Not Modified
- if (validationSucceeded)
- m_cacheEntryForValidation = NetworkCache::singleton().update(m_originalRequest, m_frameID, *m_cacheEntryForValidation, m_response);
+ if (validationSucceeded && m_cacheEntry)
+ m_cacheEntry = NetworkCache::singleton().update(m_originalRequest, m_frameID, *m_cacheEntry, m_response);
else
- m_cacheEntryForValidation = nullptr;
+ m_cacheEntry = nullptr;
return ShouldContinueDidReceiveResponse::Yes;
}
@@ -95,7 +92,7 @@
void SpeculativeLoad::didReceiveBuffer(Ref<SharedBuffer>&& buffer, int reportedEncodedDataLength)
{
- ASSERT(!m_cacheEntryForValidation);
+ ASSERT(!m_cacheEntry);
if (m_bufferedDataForCache) {
// Prevent memory growth in case of streaming data.
@@ -109,8 +106,12 @@
void SpeculativeLoad::didFinishLoading(double finishTime)
{
- if (!m_cacheEntryForValidation && m_bufferedDataForCache)
- m_cacheEntryForValidation = NetworkCache::singleton().store(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache), [](auto& mappedBody) { });
+ if (!m_cacheEntry && m_bufferedDataForCache) {
+ m_cacheEntry = NetworkCache::singleton().store(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache), [](auto& mappedBody) { });
+ // Create a synthetic cache entry if we can't store.
+ if (!m_cacheEntry && m_response.httpStatusCode() == 200)
+ m_cacheEntry = NetworkCache::singleton().makeEntry(m_originalRequest, m_response, WTFMove(m_bufferedDataForCache));
+ }
didComplete();
}
@@ -124,7 +125,7 @@
void SpeculativeLoad::didFailLoading(const ResourceError&)
{
- m_cacheEntryForValidation = nullptr;
+ m_cacheEntry = nullptr;
didComplete();
}
@@ -134,7 +135,7 @@
if (m_networkLoad)
m_networkLoad->cancel();
- m_cacheEntryForValidation = nullptr;
+ m_cacheEntry = nullptr;
didComplete();
}
@@ -145,10 +146,10 @@
m_networkLoad = nullptr;
// Make sure speculatively revalidated resources do not get validated by the NetworkResourceLoader again.
- if (m_cacheEntryForValidation)
- m_cacheEntryForValidation->setNeedsValidation(false);
+ if (m_cacheEntry)
+ m_cacheEntry->setNeedsValidation(false);
- m_completionHandler(WTFMove(m_cacheEntryForValidation));
+ m_completionHandler(WTFMove(m_cacheEntry));
}
} // namespace NetworkCache
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoad.h 2017-02-01 13:38:49 UTC (rev 211480)
@@ -76,7 +76,7 @@
WebCore::ResourceResponse m_response;
RefPtr<WebCore::SharedBuffer> m_bufferedDataForCache;
- std::unique_ptr<NetworkCache::Entry> m_cacheEntryForValidation;
+ std::unique_ptr<NetworkCache::Entry> m_cacheEntry;
};
} // namespace NetworkCache
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.cpp 2017-02-01 13:38:49 UTC (rev 211480)
@@ -84,25 +84,27 @@
return Key(resourceKey.partition(), subresourcesType(), resourceKey.range(), resourceKey.identifier(), salt);
}
-static inline ResourceRequest constructRevalidationRequest(const Entry& entry, const SubresourceInfo& subResourceInfo)
+static inline ResourceRequest constructRevalidationRequest(const Key& key, const SubresourceInfo& subResourceInfo, const Entry* entry)
{
- ResourceRequest revalidationRequest(entry.key().identifier());
+ ResourceRequest revalidationRequest(key.identifier());
revalidationRequest.setHTTPHeaderFields(subResourceInfo.requestHeaders());
revalidationRequest.setFirstPartyForCookies(subResourceInfo.firstPartyForCookies());
#if ENABLE(CACHE_PARTITIONING)
- if (!entry.key().partition().isEmpty())
- revalidationRequest.setCachePartition(entry.key().partition());
+ if (!key.partition().isEmpty())
+ revalidationRequest.setCachePartition(key.partition());
#endif
- ASSERT_WITH_MESSAGE(entry.key().range().isEmpty(), "range is not supported");
+ ASSERT_WITH_MESSAGE(key.range().isEmpty(), "range is not supported");
revalidationRequest.makeUnconditional();
- String eTag = entry.response().httpHeaderField(HTTPHeaderName::ETag);
- if (!eTag.isEmpty())
- revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
+ if (entry) {
+ String eTag = entry->response().httpHeaderField(HTTPHeaderName::ETag);
+ if (!eTag.isEmpty())
+ revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
- String lastModified = entry.response().httpHeaderField(HTTPHeaderName::LastModified);
- if (!lastModified.isEmpty())
- revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
+ String lastModified = entry->response().httpHeaderField(HTTPHeaderName::LastModified);
+ if (!lastModified.isEmpty())
+ revalidationRequest.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
+ }
revalidationRequest.setPriority(subResourceInfo.priority());
@@ -406,9 +408,9 @@
}));
}
-void SpeculativeLoadManager::retrieveEntryFromStorage(const Key& key, ResourceLoadPriority priority, RetrieveCompletionHandler&& completionHandler)
+void SpeculativeLoadManager::retrieveEntryFromStorage(const SubresourceInfo& info, RetrieveCompletionHandler&& completionHandler)
{
- m_storage.retrieve(key, static_cast<unsigned>(priority), [completionHandler = WTFMove(completionHandler)](auto record) {
+ m_storage.retrieve(info.key(), static_cast<unsigned>(info.priority()), [completionHandler = WTFMove(completionHandler)](auto record) {
if (!record) {
completionHandler(nullptr);
return false;
@@ -420,11 +422,6 @@
}
auto& response = entry->response();
- if (!response.hasCacheValidatorFields()) {
- completionHandler(nullptr);
- return true;
- }
-
if (responseNeedsRevalidation(response, entry->timeStamp())) {
// Do not use cached redirects that have expired.
if (entry->redirectRequest()) {
@@ -451,18 +448,17 @@
return true;
}
-void SpeculativeLoadManager::revalidateEntry(std::unique_ptr<Entry> entry, const SubresourceInfo& subresourceInfo, const GlobalFrameID& frameID)
+void SpeculativeLoadManager::revalidateSubresource(const SubresourceInfo& subresourceInfo, std::unique_ptr<Entry> entry, const GlobalFrameID& frameID)
{
- ASSERT(entry);
- ASSERT(entry->needsValidation());
+ ASSERT(!entry || entry->needsValidation());
- auto key = entry->key();
+ auto& key = subresourceInfo.key();
// Range is not supported.
if (!key.range().isEmpty())
return;
- ResourceRequest revalidationRequest = constructRevalidationRequest(*entry, subresourceInfo);
+ ResourceRequest revalidationRequest = constructRevalidationRequest(key, subresourceInfo, entry.get());
LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Speculatively revalidating '%s':", key.identifier().utf8().data());
@@ -484,14 +480,51 @@
});
m_pendingPreloads.add(key, WTFMove(revalidator));
}
+
+static bool canRevalidate(const SubresourceInfo& subresourceInfo, const Entry* entry)
+{
+ ASSERT(!subresourceInfo.isTransient());
+ ASSERT(!entry || entry->needsValidation());
+
+ if (entry && entry->response().hasCacheValidatorFields())
+ return true;
+
+ auto seenAge = subresourceInfo.lastSeen() - subresourceInfo.firstSeen();
+ if (seenAge == 0ms) {
+ LOG(NetworkCacheSpeculativePreloading, "Speculative load: Seen only once");
+ return false;
+ }
+
+ auto now = std::chrono::system_clock::now();
+ auto firstSeenAge = now - subresourceInfo.firstSeen();
+ auto lastSeenAge = now - subresourceInfo.lastSeen();
+ // Sanity check.
+ if (seenAge <= 0ms || firstSeenAge <= 0ms || lastSeenAge <= 0ms)
+ return false;
+
+ // Load full resources speculatively if they seem to stay the same.
+ const auto minimumAgeRatioToLoad = 2. / 3;
+ const auto recentMinimumAgeRatioToLoad = 1. / 3;
+ const auto recentThreshold = 5min;
+
+ auto ageRatio = std::chrono::duration_cast<std::chrono::duration<double>>(seenAge) / firstSeenAge;
+ auto minimumAgeRatio = lastSeenAge > recentThreshold ? minimumAgeRatioToLoad : recentMinimumAgeRatioToLoad;
+
+ LOG(NetworkCacheSpeculativePreloading, "Speculative load: ok=%d ageRatio=%f entry=%d", ageRatio > minimumAgeRatio, ageRatio, !!entry);
+
+ if (ageRatio > minimumAgeRatio)
+ return true;
+
+ return false;
+}
-void SpeculativeLoadManager::preloadEntry(const Key& key, const SubresourceInfo& subResourceInfo, const GlobalFrameID& frameID)
+void SpeculativeLoadManager::preloadEntry(const Key& key, const SubresourceInfo& subresourceInfo, const GlobalFrameID& frameID)
{
if (m_pendingPreloads.contains(key))
return;
+ m_pendingPreloads.add(key, nullptr);
- m_pendingPreloads.add(key, nullptr);
- retrieveEntryFromStorage(key, subResourceInfo.priority(), [this, key, subResourceInfo, frameID](std::unique_ptr<Entry> entry) {
+ retrieveEntryFromStorage(subresourceInfo, [this, key, subresourceInfo, frameID](std::unique_ptr<Entry> entry) {
ASSERT(!m_pendingPreloads.get(key));
bool removed = m_pendingPreloads.remove(key);
ASSERT_UNUSED(removed, removed);
@@ -501,14 +534,14 @@
logSpeculativeLoadingDiagnosticMessage(frameID, DiagnosticLoggingKeys::successfulSpeculativeWarmupWithoutRevalidationKey());
return;
}
-
- if (!entry)
+
+ if (!entry || entry->needsValidation()) {
+ if (canRevalidate(subresourceInfo, entry.get()))
+ revalidateSubresource(subresourceInfo, WTFMove(entry), frameID);
return;
-
- if (entry->needsValidation())
- revalidateEntry(WTFMove(entry), subResourceInfo, frameID);
- else
- addPreloadedEntry(WTFMove(entry), frameID);
+ }
+
+ addPreloadedEntry(WTFMove(entry), frameID);
});
}
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoadManager.h 2017-02-01 13:38:49 UTC (rev 211480)
@@ -61,8 +61,8 @@
void addPreloadedEntry(std::unique_ptr<Entry>, const GlobalFrameID&, std::optional<WebCore::ResourceRequest>&& revalidationRequest = std::nullopt);
void preloadEntry(const Key&, const SubresourceInfo&, const GlobalFrameID&);
- void retrieveEntryFromStorage(const Key&, WebCore::ResourceLoadPriority, RetrieveCompletionHandler&&);
- void revalidateEntry(std::unique_ptr<Entry>, const SubresourceInfo&, const GlobalFrameID&);
+ void retrieveEntryFromStorage(const SubresourceInfo&, RetrieveCompletionHandler&&);
+ void revalidateSubresource(const SubresourceInfo&, std::unique_ptr<Entry>, const GlobalFrameID&);
bool satisfyPendingRequests(const Key&, Entry*);
void retrieveSubresourcesEntry(const Key& storageKey, std::function<void (std::unique_ptr<SubresourcesEntry>)>&&);
void startSpeculativeRevalidation(const GlobalFrameID&, SubresourcesEntry&);
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp 2017-02-01 13:38:49 UTC (rev 211480)
@@ -31,6 +31,8 @@
#include "Logging.h"
#include "NetworkCacheCoders.h"
+using namespace std::chrono;
+
namespace WebKit {
namespace NetworkCache {
@@ -37,6 +39,8 @@
void SubresourceInfo::encode(WTF::Persistence::Encoder& encoder) const
{
encoder << m_key;
+ encoder << m_lastSeen;
+ encoder << m_firstSeen;
encoder << m_isTransient;
// Do not bother serializing other data members of transient resources as they are empty.
@@ -52,13 +56,17 @@
{
if (!decoder.decode(info.m_key))
return false;
-
+ if (!decoder.decode(info.m_lastSeen))
+ return false;
+ if (!decoder.decode(info.m_firstSeen))
+ return false;
+
if (!decoder.decode(info.m_isTransient))
return false;
-
+
if (info.m_isTransient)
return true;
-
+
if (!decoder.decode(info.m_firstPartyForCookies))
return false;
@@ -103,17 +111,46 @@
{
ASSERT(m_key.type() == "SubResources");
}
-
-static Vector<SubresourceInfo> makeSubresourceInfoVector(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
+
+SubresourceInfo::SubresourceInfo(const Key& key, const WebCore::ResourceRequest& request, const SubresourceInfo* previousInfo)
+ : m_key(key)
+ , m_lastSeen(std::chrono::system_clock::now())
+ , m_firstSeen(previousInfo ? previousInfo->firstSeen() : m_lastSeen)
+ , m_isTransient(!previousInfo)
+ , m_firstPartyForCookies(request.firstPartyForCookies())
+ , m_requestHeaders(request.httpHeaderFields())
+ , m_priority(request.priority())
{
+}
+
+static Vector<SubresourceInfo> makeSubresourceInfoVector(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads, Vector<SubresourceInfo>* previousSubresources)
+{
Vector<SubresourceInfo> result;
result.reserveInitialCapacity(subresourceLoads.size());
- HashSet<Key> seenKeys;
+ HashMap<Key, unsigned> previousMap;
+ if (previousSubresources) {
+ for (unsigned i = 0; i < previousSubresources->size(); ++i)
+ previousMap.add(previousSubresources->at(i).key(), i);
+ }
+
+ HashSet<Key> deduplicationSet;
for (auto& load : subresourceLoads) {
- if (!seenKeys.add(load->key).isNewEntry)
+ if (!deduplicationSet.add(load->key).isNewEntry)
continue;
- result.uncheckedAppend({ load->key, load->request });
+
+ SubresourceInfo* previousInfo = nullptr;
+ if (previousSubresources) {
+ auto it = previousMap.find(load->key);
+ if (it != previousMap.end())
+ previousInfo = &(*previousSubresources)[it->value];
+ }
+
+ result.uncheckedAppend({ load->key, load->request, previousInfo });
+
+ // FIXME: We should really consider all resources seen for the first time transient.
+ if (!previousSubresources)
+ result.last().setNonTransient();
}
return result;
@@ -122,24 +159,14 @@
SubresourcesEntry::SubresourcesEntry(Key&& key, const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
: m_key(WTFMove(key))
, m_timeStamp(std::chrono::system_clock::now())
- , m_subresources(makeSubresourceInfoVector(subresourceLoads))
+ , m_subresources(makeSubresourceInfoVector(subresourceLoads, nullptr))
{
ASSERT(m_key.type() == "SubResources");
}
-
+
void SubresourcesEntry::updateSubresourceLoads(const Vector<std::unique_ptr<SubresourceLoad>>& subresourceLoads)
{
- HashSet<Key> previousKeys;
- for (auto& info : m_subresources)
- previousKeys.add(info.key());
-
- m_subresources = makeSubresourceInfoVector(subresourceLoads);
-
- // Mark keys that are not common with the last load as transient.
- for (auto& subresourceInfo : m_subresources) {
- if (!previousKeys.contains(subresourceInfo.key()))
- subresourceInfo.setTransient();
- }
+ m_subresources = makeSubresourceInfoVector(subresourceLoads, &m_subresources);
}
} // namespace WebKit
Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h (211479 => 211480)
--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h 2017-02-01 11:29:25 UTC (rev 211479)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h 2017-02-01 13:38:49 UTC (rev 211480)
@@ -43,24 +43,23 @@
static bool decode(WTF::Persistence::Decoder&, SubresourceInfo&);
SubresourceInfo() = default;
- SubresourceInfo(const Key& key, const WebCore::ResourceRequest& request)
- : m_key(key)
- , m_firstPartyForCookies(request.firstPartyForCookies())
- , m_requestHeaders(request.httpHeaderFields())
- , m_priority(request.priority())
- {
- }
+ SubresourceInfo(const Key&, const WebCore::ResourceRequest&, const SubresourceInfo* previousInfo);
const Key& key() const { return m_key; }
+ std::chrono::system_clock::time_point lastSeen() const { return m_lastSeen; }
+ std::chrono::system_clock::time_point firstSeen() const { return m_firstSeen; }
+
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; }
WebCore::ResourceLoadPriority priority() const { ASSERT(!m_isTransient); return m_priority; }
- void setTransient() { m_isTransient = true; }
+ void setNonTransient() { m_isTransient = false; }
private:
Key m_key;
+ std::chrono::system_clock::time_point m_lastSeen;
+ std::chrono::system_clock::time_point m_firstSeen;
bool m_isTransient { false };
WebCore::URL m_firstPartyForCookies;
WebCore::HTTPHeaderMap m_requestHeaders;