Title: [182090] trunk/Source/WebKit2
Revision
182090
Author
cdu...@apple.com
Date
2015-03-27 16:49:15 -0700 (Fri, 27 Mar 2015)

Log Message

[WK2][NetworkCache] Use WTF::WorkQueue abstraction inside NetworkCacheStatistics
https://bugs.webkit.org/show_bug.cgi?id=143154

Reviewed by Antti Koivisto.

Use WTF::WorkQueue abstraction inside NetworkCacheStatistics, like we
already do in NetworkCacheStorage.

* NetworkProcess/cache/NetworkCacheStatistics.cpp: Renamed from Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm.
(WebKit::NetworkCache::executeSQLCommand):
(WebKit::NetworkCache::executeSQLStatement):
(WebKit::NetworkCache::Statistics::open):
(WebKit::NetworkCache::Statistics::Statistics):
(WebKit::NetworkCache::Statistics::initialize):
(WebKit::NetworkCache::Statistics::bootstrapFromNetworkCache):
(WebKit::NetworkCache::Statistics::shrinkIfNeeded):
(WebKit::NetworkCache::Statistics::recordRetrievalRequest):
(WebKit::NetworkCache::Statistics::recordNotCachingResponse):
(WebKit::NetworkCache::retrieveDecisionToDiagnosticKey):
(WebKit::NetworkCache::Statistics::recordNotUsingCacheForRequest):
(WebKit::NetworkCache::storeDecisionToDiagnosticKey):
(WebKit::NetworkCache::Statistics::recordRetrievalFailure):
(WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
(WebKit::NetworkCache::Statistics::recordRetrievedCachedEntry):
(WebKit::NetworkCache::Statistics::markAsRequested):
(WebKit::NetworkCache::Statistics::writeTimerFired):
(WebKit::NetworkCache::Statistics::queryWasEverRequested):
(WebKit::NetworkCache::Statistics::clear):
(WebKit::NetworkCache::Statistics::addHashesToDatabase):
(WebKit::NetworkCache::Statistics::addStoreDecisionsToDatabase):
* NetworkProcess/cache/NetworkCacheStatistics.h:
(WebKit::NetworkCache::Statistics::serialBackgroundIOQueue):
* WebKit2.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (182089 => 182090)


--- trunk/Source/WebKit2/ChangeLog	2015-03-27 23:08:01 UTC (rev 182089)
+++ trunk/Source/WebKit2/ChangeLog	2015-03-27 23:49:15 UTC (rev 182090)
@@ -1,3 +1,39 @@
+2015-03-27  Chris Dumez  <cdu...@apple.com>
+
+        [WK2][NetworkCache] Use WTF::WorkQueue abstraction inside NetworkCacheStatistics
+        https://bugs.webkit.org/show_bug.cgi?id=143154
+
+        Reviewed by Antti Koivisto.
+
+        Use WTF::WorkQueue abstraction inside NetworkCacheStatistics, like we
+        already do in NetworkCacheStorage.
+
+        * NetworkProcess/cache/NetworkCacheStatistics.cpp: Renamed from Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm.
+        (WebKit::NetworkCache::executeSQLCommand):
+        (WebKit::NetworkCache::executeSQLStatement):
+        (WebKit::NetworkCache::Statistics::open):
+        (WebKit::NetworkCache::Statistics::Statistics):
+        (WebKit::NetworkCache::Statistics::initialize):
+        (WebKit::NetworkCache::Statistics::bootstrapFromNetworkCache):
+        (WebKit::NetworkCache::Statistics::shrinkIfNeeded):
+        (WebKit::NetworkCache::Statistics::recordRetrievalRequest):
+        (WebKit::NetworkCache::Statistics::recordNotCachingResponse):
+        (WebKit::NetworkCache::retrieveDecisionToDiagnosticKey):
+        (WebKit::NetworkCache::Statistics::recordNotUsingCacheForRequest):
+        (WebKit::NetworkCache::storeDecisionToDiagnosticKey):
+        (WebKit::NetworkCache::Statistics::recordRetrievalFailure):
+        (WebKit::NetworkCache::cachedEntryReuseFailureToDiagnosticKey):
+        (WebKit::NetworkCache::Statistics::recordRetrievedCachedEntry):
+        (WebKit::NetworkCache::Statistics::markAsRequested):
+        (WebKit::NetworkCache::Statistics::writeTimerFired):
+        (WebKit::NetworkCache::Statistics::queryWasEverRequested):
+        (WebKit::NetworkCache::Statistics::clear):
+        (WebKit::NetworkCache::Statistics::addHashesToDatabase):
+        (WebKit::NetworkCache::Statistics::addStoreDecisionsToDatabase):
+        * NetworkProcess/cache/NetworkCacheStatistics.h:
+        (WebKit::NetworkCache::Statistics::serialBackgroundIOQueue):
+        * WebKit2.xcodeproj/project.pbxproj:
+
 2015-03-27  Ryosuke Niwa  <rn...@webkit.org>
 
         Safari clears selection when its window gets activated via mouse down

Copied: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp (from rev 182089, trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm) (0 => 182090)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	2015-03-27 23:49:15 UTC (rev 182090)
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(NETWORK_CACHE)
+#include "NetworkCacheStatistics.h"
+
+#include "Logging.h"
+#include "NetworkCache.h"
+#include "NetworkCacheFileSystemPosix.h"
+#include "NetworkProcess.h"
+#include <WebCore/DiagnosticLoggingKeys.h>
+#include <WebCore/DiagnosticLoggingResultType.h>
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/SQLiteDatabaseTracker.h>
+#include <WebCore/SQLiteStatement.h>
+#include <WebCore/SQLiteTransaction.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+namespace NetworkCache {
+
+static const char* StatisticsDatabaseName = "WebKitCacheStatistics.db";
+static const std::chrono::milliseconds mininumWriteInterval = std::chrono::milliseconds(10000);
+
+static bool executeSQLCommand(WebCore::SQLiteDatabase& database, const String& sql)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
+    ASSERT(database.isOpen());
+
+    bool result = database.executeCommand(sql);
+    if (!result)
+        LOG_ERROR("Network cache statistics: failed to execute statement \"%s\" error \"%s\"", sql.utf8().data(), database.lastErrorMsg());
+
+    return result;
+}
+
+static bool executeSQLStatement(WebCore::SQLiteStatement& statement)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
+    ASSERT(statement.database().isOpen());
+
+    if (statement.step() != WebCore::SQLResultDone) {
+        LOG_ERROR("Network cache statistics: failed to execute statement \"%s\" error \"%s\"", statement.query().utf8().data(), statement.database().lastErrorMsg());
+        return false;
+    }
+
+    return true;
+}
+
+std::unique_ptr<Statistics> Statistics::open(const String& cachePath)
+{
+    ASSERT(RunLoop::isMain());
+
+    String databasePath = WebCore::pathByAppendingComponent(cachePath, StatisticsDatabaseName);
+    return std::unique_ptr<Statistics>(new Statistics(databasePath));
+}
+
+Statistics::Statistics(const String& databasePath)
+    : m_serialBackgroundIOQueue(WorkQueue::create("com.apple.WebKit.Cache.Statistics.Background", WorkQueue::Type::Serial, WorkQueue::QOS::Background))
+    , m_writeTimer(*this, &Statistics::writeTimerFired)
+{
+    initialize(databasePath);
+}
+
+void Statistics::initialize(const String& databasePath)
+{
+    ASSERT(RunLoop::isMain());
+
+    auto startTime = std::chrono::system_clock::now();
+
+    StringCapture databasePathCapture(databasePath);
+    StringCapture networkCachePathCapture(singleton().storagePath());
+    serialBackgroundIOQueue().dispatch([this, databasePathCapture, networkCachePathCapture, startTime] {
+        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
+
+        String databasePath = databasePathCapture.string();
+        if (!WebCore::makeAllDirectories(WebCore::directoryName(databasePath)))
+            return;
+
+        LOG(NetworkCache, "(NetworkProcess) Opening network cache statistics database at %s...", databasePath.utf8().data());
+        m_database.open(databasePath);
+        m_database.disableThreadingChecks();
+        if (!m_database.isOpen()) {
+            LOG_ERROR("Network cache statistics: Failed to open / create the network cache statistics database");
+            return;
+        }
+
+        executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS AlreadyRequested (hash TEXT PRIMARY KEY)"));
+        executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS UncachedReason (hash TEXT PRIMARY KEY, reason INTEGER)"));
+
+        WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT count(*) FROM AlreadyRequested"));
+        if (statement.prepareAndStep() != WebCore::SQLResultRow) {
+            LOG_ERROR("Network cache statistics: Failed to count the number of rows in AlreadyRequested table");
+            return;
+        }
+
+        m_approximateEntryCount = statement.getColumnInt(0);
+
+#if !LOG_DISABLED
+        auto elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count();
+#endif
+        LOG(NetworkCache, "(NetworkProcess) Network cache statistics database load complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS);
+
+        if (!m_approximateEntryCount) {
+            bootstrapFromNetworkCache(networkCachePathCapture.string());
+#if !LOG_DISABLED
+            elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count();
+#endif
+            LOG(NetworkCache, "(NetworkProcess) Network cache statistics database bootstrapping complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS);
+        }
+    });
+}
+
+void Statistics::bootstrapFromNetworkCache(const String& networkCachePath)
+{
+    ASSERT(!RunLoop::isMain());
+
+    LOG(NetworkCache, "(NetworkProcess) Bootstrapping the network cache statistics database from the network cache...");
+
+    Vector<StringCapture> hashes;
+    traverseCacheFiles(networkCachePath, [&hashes](const String& hash, const String&) {
+        hashes.append(hash);
+    });
+
+    WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
+    WebCore::SQLiteTransaction writeTransaction(m_database);
+    writeTransaction.begin();
+
+    addHashesToDatabase(hashes);
+
+    writeTransaction.commit();
+}
+
+void Statistics::shrinkIfNeeded()
+{
+    ASSERT(RunLoop::isMain());
+    const size_t maxEntries = 100000;
+
+    if (m_approximateEntryCount < maxEntries)
+        return;
+
+    LOG(NetworkCache, "(NetworkProcess) shrinking statistics cache m_approximateEntryCount=%lu, maxEntries=%lu", static_cast<size_t>(m_approximateEntryCount), maxEntries);
+
+    clear();
+
+    StringCapture networkCachePathCapture(singleton().storagePath());
+    serialBackgroundIOQueue().dispatch([this, networkCachePathCapture] {
+        bootstrapFromNetworkCache(networkCachePathCapture.string());
+        LOG(NetworkCache, "(NetworkProcess) statistics cache shrink completed m_approximateEntryCount=%lu", static_cast<size_t>(m_approximateEntryCount));
+    });
+}
+
+void Statistics::recordRetrievalRequest(uint64_t webPageID)
+{
+    NetworkProcess::singleton().logDiagnosticMessage(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::retrievalRequestKey(), WebCore::ShouldSample::Yes);
+}
+
+void Statistics::recordNotCachingResponse(const Key& key, StoreDecision storeDecision)
+{
+    ASSERT(storeDecision != StoreDecision::Yes);
+
+    m_storeDecisionsToAdd.set(key.hashAsString(), storeDecision);
+    if (!m_writeTimer.isActive())
+        m_writeTimer.startOneShot(mininumWriteInterval);
+}
+
+static String retrieveDecisionToDiagnosticKey(RetrieveDecision retrieveDecision)
+{
+    switch (retrieveDecision) {
+    case RetrieveDecision::NoDueToHTTPMethod:
+        return WebCore::DiagnosticLoggingKeys::unsupportedHTTPMethodKey();
+    case RetrieveDecision::NoDueToConditionalRequest:
+        return WebCore::DiagnosticLoggingKeys::isConditionalRequestKey();
+    case RetrieveDecision::NoDueToReloadIgnoringCache:
+        return WebCore::DiagnosticLoggingKeys::isReloadIgnoringCacheDataKey();
+    case RetrieveDecision::Yes:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+    return emptyString();
+}
+
+void Statistics::recordNotUsingCacheForRequest(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request, RetrieveDecision retrieveDecision)
+{
+    ASSERT(retrieveDecision != RetrieveDecision::Yes);
+
+    String hash = key.hashAsString();
+    WebCore::URL requestURL = request.url();
+    queryWasEverRequested(hash, NeedUncachedReason::No, [this, hash, requestURL, webPageID, retrieveDecision](bool wasEverRequested, const Optional<StoreDecision>&) {
+        if (wasEverRequested) {
+            String diagnosticKey = retrieveDecisionToDiagnosticKey(retrieveDecision);
+            LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s was previously requested but we are not using the cache, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
+            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::unusedKey(), diagnosticKey, WebCore::ShouldSample::Yes);
+        } else {
+            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::requestKey(), WebCore::DiagnosticLoggingKeys::neverSeenBeforeKey(), WebCore::ShouldSample::Yes);
+            markAsRequested(hash);
+        }
+    });
+}
+
+static String storeDecisionToDiagnosticKey(StoreDecision storeDecision)
+{
+    switch (storeDecision) {
+    case StoreDecision::NoDueToProtocol:
+        return WebCore::DiagnosticLoggingKeys::notHTTPFamilyKey();
+    case StoreDecision::NoDueToHTTPMethod:
+        return WebCore::DiagnosticLoggingKeys::unsupportedHTTPMethodKey();
+    case StoreDecision::NoDueToAttachmentResponse:
+        return WebCore::DiagnosticLoggingKeys::isAttachmentKey();
+    case StoreDecision::NoDueToNoStoreResponse:
+    case StoreDecision::NoDueToNoStoreRequest:
+        return WebCore::DiagnosticLoggingKeys::cacheControlNoStoreKey();
+    case StoreDecision::NoDueToHTTPStatusCode:
+        return WebCore::DiagnosticLoggingKeys::uncacheableStatusCodeKey();
+    case StoreDecision::Yes:
+        // It was stored but could not be retrieved so it must have been pruned from the cache.
+        return WebCore::DiagnosticLoggingKeys::noLongerInCacheKey();
+    }
+    return String();
+}
+
+void Statistics::recordRetrievalFailure(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request)
+{
+    String hash = key.hashAsString();
+    WebCore::URL requestURL = request.url();
+    queryWasEverRequested(hash, NeedUncachedReason::Yes, [this, hash, requestURL, webPageID](bool wasPreviouslyRequested, const Optional<StoreDecision>& storeDecision) {
+        if (wasPreviouslyRequested) {
+            String diagnosticKey = storeDecisionToDiagnosticKey(storeDecision.value());
+            LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s was previously request but is not in the cache, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
+            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::notInCacheKey(), diagnosticKey, WebCore::ShouldSample::Yes);
+        } else {
+            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::requestKey(), WebCore::DiagnosticLoggingKeys::neverSeenBeforeKey(), WebCore::ShouldSample::Yes);
+            markAsRequested(hash);
+        }
+    });
+}
+
+static String cachedEntryReuseFailureToDiagnosticKey(UseDecision decision)
+{
+    switch (decision) {
+    case UseDecision::NoDueToVaryingHeaderMismatch:
+        return WebCore::DiagnosticLoggingKeys::varyingHeaderMismatchKey();
+    case UseDecision::NoDueToMissingValidatorFields:
+        return WebCore::DiagnosticLoggingKeys::missingValidatorFieldsKey();
+    case UseDecision::NoDueToDecodeFailure:
+        return WebCore::DiagnosticLoggingKeys::otherKey();
+    case UseDecision::Use:
+    case UseDecision::Validate:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+    return emptyString();
+}
+
+void Statistics::recordRetrievedCachedEntry(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request, UseDecision decision)
+{
+    WebCore::URL requestURL = request.url();
+    if (decision == UseDecision::Use || decision == UseDecision::Validate) {
+        LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s is in the cache and is used", webPageID, requestURL.string().ascii().data());
+        NetworkProcess::singleton().logDiagnosticMessageWithResult(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::retrievalKey(), WebCore::DiagnosticLoggingResultPass, WebCore::ShouldSample::Yes);
+        return;
+    }
+
+    String diagnosticKey = cachedEntryReuseFailureToDiagnosticKey(decision);
+    LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s is in the cache but wasn't used, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
+    NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::unusableCachedEntryKey(), diagnosticKey, WebCore::ShouldSample::Yes);
+}
+
+void Statistics::markAsRequested(const String& hash)
+{
+    ASSERT(RunLoop::isMain());
+
+    m_hashesToAdd.add(hash);
+    if (!m_writeTimer.isActive())
+        m_writeTimer.startOneShot(mininumWriteInterval);
+}
+
+void Statistics::writeTimerFired()
+{
+    ASSERT(RunLoop::isMain());
+
+    Vector<StringCapture> hashesToAdd;
+    copyToVector(m_hashesToAdd, hashesToAdd);
+    m_hashesToAdd.clear();
+
+    Vector<std::pair<StringCapture, StoreDecision>> storeDecisionsToAdd;
+    copyToVector(m_storeDecisionsToAdd, storeDecisionsToAdd);
+    m_storeDecisionsToAdd.clear();
+
+    shrinkIfNeeded();
+
+    serialBackgroundIOQueue().dispatch([this, hashesToAdd, storeDecisionsToAdd] {
+        if (!m_database.isOpen())
+            return;
+
+        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
+        WebCore::SQLiteTransaction writeTransaction(m_database);
+        writeTransaction.begin();
+
+        addHashesToDatabase(hashesToAdd);
+        addStoreDecisionsToDatabase(storeDecisionsToAdd);
+
+        writeTransaction.commit();
+    });
+}
+
+void Statistics::queryWasEverRequested(const String& hash, NeedUncachedReason needUncachedReason, const RequestedCompletionHandler& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+
+    // Query pending writes first.
+    bool wasAlreadyRequested = m_hashesToAdd.contains(hash);
+    if (wasAlreadyRequested && needUncachedReason == NeedUncachedReason::No) {
+        completionHandler(true, Nullopt);
+        return;
+    }
+    if (needUncachedReason == NeedUncachedReason::Yes && m_storeDecisionsToAdd.contains(hash)) {
+        completionHandler(true, m_storeDecisionsToAdd.get(hash));
+        return;
+    }
+
+    // Query the database.
+    auto everRequestedQuery = std::make_unique<EverRequestedQuery>(EverRequestedQuery { hash, needUncachedReason == NeedUncachedReason::Yes, completionHandler });
+    auto& query = *everRequestedQuery;
+    m_activeQueries.add(WTF::move(everRequestedQuery));
+    serialBackgroundIOQueue().dispatch([this, wasAlreadyRequested, &query] () mutable {
+        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
+        Optional<StoreDecision> storeDecision;
+        if (m_database.isOpen()) {
+            if (!wasAlreadyRequested) {
+                WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT hash FROM AlreadyRequested WHERE hash=?"));
+                if (statement.prepare() == WebCore::SQLResultOk) {
+                    statement.bindText(1, query.hash);
+                    wasAlreadyRequested = (statement.step() == WebCore::SQLResultRow);
+                }
+            }
+            if (wasAlreadyRequested && query.needUncachedReason) {
+                WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT reason FROM UncachedReason WHERE hash=?"));
+                storeDecision = StoreDecision::Yes;
+                if (statement.prepare() == WebCore::SQLResultOk) {
+                    statement.bindText(1, query.hash);
+                    if (statement.step() == WebCore::SQLResultRow)
+                        storeDecision = static_cast<StoreDecision>(statement.getColumnInt(0));
+                }
+            }
+        }
+        RunLoop::main().dispatch([this, &query, wasAlreadyRequested, storeDecision] {
+            query.completionHandler(wasAlreadyRequested, storeDecision);
+            m_activeQueries.remove(&query);
+        });
+    });
+}
+
+void Statistics::clear()
+{
+    ASSERT(RunLoop::isMain());
+
+    serialBackgroundIOQueue().dispatch([this] {
+        if (m_database.isOpen()) {
+            WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
+            WebCore::SQLiteTransaction deleteTransaction(m_database);
+            deleteTransaction.begin();
+            executeSQLCommand(m_database, ASCIILiteral("DELETE FROM AlreadyRequested"));
+            executeSQLCommand(m_database, ASCIILiteral("DELETE FROM UncachedReason"));
+            deleteTransaction.commit();
+            m_approximateEntryCount = 0;
+        }
+    });
+}
+
+void Statistics::addHashesToDatabase(const Vector<StringCapture>& hashes)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
+    ASSERT(m_database.isOpen());
+
+    WebCore::SQLiteStatement statement(m_database, ASCIILiteral("INSERT OR IGNORE INTO AlreadyRequested (hash) VALUES (?)"));
+    if (statement.prepare() != WebCore::SQLResultOk)
+        return;
+
+    for (auto& hash : hashes) {
+        statement.bindText(1, hash.string());
+        if (executeSQLStatement(statement))
+            ++m_approximateEntryCount;
+        statement.reset();
+    }
+}
+
+void Statistics::addStoreDecisionsToDatabase(const Vector<std::pair<StringCapture, StoreDecision>>& storeDecisions)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
+    ASSERT(m_database.isOpen());
+
+    WebCore::SQLiteStatement statement(m_database, ASCIILiteral("INSERT OR REPLACE INTO UncachedReason (hash, reason) VALUES (?, ?)"));
+    if (statement.prepare() != WebCore::SQLResultOk)
+        return;
+
+    for (auto& pair : storeDecisions) {
+        statement.bindText(1, pair.first.string());
+        statement.bindInt(2, static_cast<int>(pair.second));
+        executeSQLStatement(statement);
+        statement.reset();
+    }
+}
+
+}
+}
+
+#endif // ENABLE(NETWORK_CACHE)

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.h (182089 => 182090)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.h	2015-03-27 23:08:01 UTC (rev 182089)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.h	2015-03-27 23:49:15 UTC (rev 182090)
@@ -30,9 +30,9 @@
 
 #include "NetworkCache.h"
 #include "NetworkCacheKey.h"
-#include "NetworkCacheStorage.h"
 #include <WebCore/SQLiteDatabase.h>
 #include <WebCore/Timer.h>
+#include <wtf/WorkQueue.h>
 
 namespace WebCore {
 class ResourceRequest;
@@ -56,6 +56,8 @@
 private:
     explicit Statistics(const String& databasePath);
 
+    WorkQueue& serialBackgroundIOQueue() { return m_serialBackgroundIOQueue.get(); }
+
     void initialize(const String& databasePath);
     void bootstrapFromNetworkCache(const String& networkCachePath);
     void shrinkIfNeeded();
@@ -77,9 +79,7 @@
 
     std::atomic<size_t> m_approximateEntryCount { 0 };
 
-#if PLATFORM(COCOA)
-    mutable DispatchPtr<dispatch_queue_t> m_backgroundIOQueue;
-#endif
+    mutable Ref<WorkQueue> m_serialBackgroundIOQueue;
     mutable HashSet<std::unique_ptr<const EverRequestedQuery>> m_activeQueries;
     WebCore::SQLiteDatabase m_database;
     HashSet<String> m_hashesToAdd;

Deleted: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm (182089 => 182090)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm	2015-03-27 23:08:01 UTC (rev 182089)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm	2015-03-27 23:49:15 UTC (rev 182090)
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(NETWORK_CACHE)
-#include "NetworkCacheStatistics.h"
-
-#include "Logging.h"
-#include "NetworkCache.h"
-#include "NetworkCacheFileSystemPosix.h"
-#include "NetworkProcess.h"
-#include <WebCore/DiagnosticLoggingKeys.h>
-#include <WebCore/DiagnosticLoggingResultType.h>
-#include <WebCore/ResourceRequest.h>
-#include <WebCore/SQLiteDatabaseTracker.h>
-#include <WebCore/SQLiteStatement.h>
-#include <WebCore/SQLiteTransaction.h>
-#include <wtf/RunLoop.h>
-
-namespace WebKit {
-namespace NetworkCache {
-
-static const char* StatisticsDatabaseName = "WebKitCacheStatistics.db";
-static const std::chrono::milliseconds mininumWriteInterval = std::chrono::milliseconds(10000);
-
-static bool executeSQLCommand(WebCore::SQLiteDatabase& database, const String& sql)
-{
-    ASSERT(!RunLoop::isMain());
-    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
-    ASSERT(database.isOpen());
-
-    bool result = database.executeCommand(sql);
-    if (!result)
-        LOG_ERROR("Network cache statistics: failed to execute statement \"%s\" error \"%s\"", sql.utf8().data(), database.lastErrorMsg());
-
-    return result;
-}
-
-static bool executeSQLStatement(WebCore::SQLiteStatement& statement)
-{
-    ASSERT(!RunLoop::isMain());
-    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
-    ASSERT(statement.database().isOpen());
-
-    if (statement.step() != WebCore::SQLResultDone) {
-        LOG_ERROR("Network cache statistics: failed to execute statement \"%s\" error \"%s\"", statement.query().utf8().data(), statement.database().lastErrorMsg());
-        return false;
-    }
-
-    return true;
-}
-
-std::unique_ptr<Statistics> Statistics::open(const String& cachePath)
-{
-    ASSERT(RunLoop::isMain());
-
-    String databasePath = WebCore::pathByAppendingComponent(cachePath, StatisticsDatabaseName);
-    return std::unique_ptr<Statistics>(new Statistics(databasePath));
-}
-
-Statistics::Statistics(const String& databasePath)
-    : m_backgroundIOQueue(adoptDispatch(dispatch_queue_create("com.apple.WebKit.Cache.Statistics.Background", DISPATCH_QUEUE_SERIAL)))
-    , m_writeTimer(*this, &Statistics::writeTimerFired)
-{
-    dispatch_set_target_queue(m_backgroundIOQueue.get(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0));
-
-    initialize(databasePath);
-}
-
-void Statistics::initialize(const String& databasePath)
-{
-    ASSERT(RunLoop::isMain());
-
-    auto startTime = std::chrono::system_clock::now();
-
-    StringCapture databasePathCapture(databasePath);
-    StringCapture networkCachePathCapture(singleton().storagePath());
-    dispatch_async(m_backgroundIOQueue.get(), [this, databasePathCapture, networkCachePathCapture, startTime] {
-        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
-
-        String databasePath = databasePathCapture.string();
-        if (!WebCore::makeAllDirectories(WebCore::directoryName(databasePath)))
-            return;
-
-        LOG(NetworkCache, "(NetworkProcess) Opening network cache statistics database at %s...", databasePath.utf8().data());
-        m_database.open(databasePath);
-        m_database.disableThreadingChecks();
-        if (!m_database.isOpen()) {
-            LOG_ERROR("Network cache statistics: Failed to open / create the network cache statistics database");
-            return;
-        }
-
-        executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS AlreadyRequested (hash TEXT PRIMARY KEY)"));
-        executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS UncachedReason (hash TEXT PRIMARY KEY, reason INTEGER)"));
-
-        WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT count(*) FROM AlreadyRequested"));
-        if (statement.prepareAndStep() != WebCore::SQLResultRow) {
-            LOG_ERROR("Network cache statistics: Failed to count the number of rows in AlreadyRequested table");
-            return;
-        }
-
-        m_approximateEntryCount = statement.getColumnInt(0);
-
-#if !LOG_DISABLED
-        auto elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count();
-#endif
-        LOG(NetworkCache, "(NetworkProcess) Network cache statistics database load complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS);
-
-        if (!m_approximateEntryCount) {
-            bootstrapFromNetworkCache(networkCachePathCapture.string());
-#if !LOG_DISABLED
-            elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count();
-#endif
-            LOG(NetworkCache, "(NetworkProcess) Network cache statistics database bootstrapping complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS);
-        }
-    });
-}
-
-void Statistics::bootstrapFromNetworkCache(const String& networkCachePath)
-{
-    ASSERT(!RunLoop::isMain());
-
-    LOG(NetworkCache, "(NetworkProcess) Bootstrapping the network cache statistics database from the network cache...");
-
-    Vector<StringCapture> hashes;
-    traverseCacheFiles(networkCachePath, [&hashes](const String& hash, const String&) {
-        hashes.append(hash);
-    });
-
-    WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
-    WebCore::SQLiteTransaction writeTransaction(m_database);
-    writeTransaction.begin();
-
-    addHashesToDatabase(hashes);
-
-    writeTransaction.commit();
-}
-
-void Statistics::shrinkIfNeeded()
-{
-    ASSERT(RunLoop::isMain());
-    const size_t maxEntries = 100000;
-
-    if (m_approximateEntryCount < maxEntries)
-        return;
-
-    LOG(NetworkCache, "(NetworkProcess) shrinking statistics cache m_approximateEntryCount=%lu, maxEntries=%lu", static_cast<size_t>(m_approximateEntryCount), maxEntries);
-
-    clear();
-
-    StringCapture networkCachePathCapture(singleton().storagePath());
-    dispatch_async(m_backgroundIOQueue.get(), [this, networkCachePathCapture] {
-        bootstrapFromNetworkCache(networkCachePathCapture.string());
-        LOG(NetworkCache, "(NetworkProcess) statistics cache shrink completed m_approximateEntryCount=%lu", static_cast<size_t>(m_approximateEntryCount));
-    });
-}
-
-void Statistics::recordRetrievalRequest(uint64_t webPageID)
-{
-    NetworkProcess::singleton().logDiagnosticMessage(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::retrievalRequestKey(), WebCore::ShouldSample::Yes);
-}
-
-void Statistics::recordNotCachingResponse(const Key& key, StoreDecision storeDecision)
-{
-    ASSERT(storeDecision != StoreDecision::Yes);
-
-    m_storeDecisionsToAdd.set(key.hashAsString(), storeDecision);
-    if (!m_writeTimer.isActive())
-        m_writeTimer.startOneShot(mininumWriteInterval);
-}
-
-static String retrieveDecisionToDiagnosticKey(RetrieveDecision retrieveDecision)
-{
-    switch (retrieveDecision) {
-    case RetrieveDecision::NoDueToHTTPMethod:
-        return WebCore::DiagnosticLoggingKeys::unsupportedHTTPMethodKey();
-    case RetrieveDecision::NoDueToConditionalRequest:
-        return WebCore::DiagnosticLoggingKeys::isConditionalRequestKey();
-    case RetrieveDecision::NoDueToReloadIgnoringCache:
-        return WebCore::DiagnosticLoggingKeys::isReloadIgnoringCacheDataKey();
-    case RetrieveDecision::Yes:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-    return emptyString();
-}
-
-void Statistics::recordNotUsingCacheForRequest(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request, RetrieveDecision retrieveDecision)
-{
-    ASSERT(retrieveDecision != RetrieveDecision::Yes);
-
-    String hash = key.hashAsString();
-    WebCore::URL requestURL = request.url();
-    queryWasEverRequested(hash, NeedUncachedReason::No, [this, hash, requestURL, webPageID, retrieveDecision](bool wasEverRequested, const Optional<StoreDecision>&) {
-        if (wasEverRequested) {
-            String diagnosticKey = retrieveDecisionToDiagnosticKey(retrieveDecision);
-            LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s was previously requested but we are not using the cache, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
-            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::unusedKey(), diagnosticKey, WebCore::ShouldSample::Yes);
-        } else {
-            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::requestKey(), WebCore::DiagnosticLoggingKeys::neverSeenBeforeKey(), WebCore::ShouldSample::Yes);
-            markAsRequested(hash);
-        }
-    });
-}
-
-static String storeDecisionToDiagnosticKey(StoreDecision storeDecision)
-{
-    switch (storeDecision) {
-    case StoreDecision::NoDueToProtocol:
-        return WebCore::DiagnosticLoggingKeys::notHTTPFamilyKey();
-    case StoreDecision::NoDueToHTTPMethod:
-        return WebCore::DiagnosticLoggingKeys::unsupportedHTTPMethodKey();
-    case StoreDecision::NoDueToAttachmentResponse:
-        return WebCore::DiagnosticLoggingKeys::isAttachmentKey();
-    case StoreDecision::NoDueToNoStoreResponse:
-    case StoreDecision::NoDueToNoStoreRequest:
-        return WebCore::DiagnosticLoggingKeys::cacheControlNoStoreKey();
-    case StoreDecision::NoDueToHTTPStatusCode:
-        return WebCore::DiagnosticLoggingKeys::uncacheableStatusCodeKey();
-    case StoreDecision::Yes:
-        // It was stored but could not be retrieved so it must have been pruned from the cache.
-        return WebCore::DiagnosticLoggingKeys::noLongerInCacheKey();
-    }
-    return String();
-}
-
-void Statistics::recordRetrievalFailure(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request)
-{
-    String hash = key.hashAsString();
-    WebCore::URL requestURL = request.url();
-    queryWasEverRequested(hash, NeedUncachedReason::Yes, [this, hash, requestURL, webPageID](bool wasPreviouslyRequested, const Optional<StoreDecision>& storeDecision) {
-        if (wasPreviouslyRequested) {
-            String diagnosticKey = storeDecisionToDiagnosticKey(storeDecision.value());
-            LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s was previously request but is not in the cache, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
-            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::notInCacheKey(), diagnosticKey, WebCore::ShouldSample::Yes);
-        } else {
-            NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::requestKey(), WebCore::DiagnosticLoggingKeys::neverSeenBeforeKey(), WebCore::ShouldSample::Yes);
-            markAsRequested(hash);
-        }
-    });
-}
-
-static String cachedEntryReuseFailureToDiagnosticKey(UseDecision decision)
-{
-    switch (decision) {
-    case UseDecision::NoDueToVaryingHeaderMismatch:
-        return WebCore::DiagnosticLoggingKeys::varyingHeaderMismatchKey();
-    case UseDecision::NoDueToMissingValidatorFields:
-        return WebCore::DiagnosticLoggingKeys::missingValidatorFieldsKey();
-    case UseDecision::NoDueToDecodeFailure:
-        return WebCore::DiagnosticLoggingKeys::otherKey();
-    case UseDecision::Use:
-    case UseDecision::Validate:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-    return emptyString();
-}
-
-void Statistics::recordRetrievedCachedEntry(uint64_t webPageID, const Key& key, const WebCore::ResourceRequest& request, UseDecision decision)
-{
-    WebCore::URL requestURL = request.url();
-    if (decision == UseDecision::Use || decision == UseDecision::Validate) {
-        LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s is in the cache and is used", webPageID, requestURL.string().ascii().data());
-        NetworkProcess::singleton().logDiagnosticMessageWithResult(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::retrievalKey(), WebCore::DiagnosticLoggingResultPass, WebCore::ShouldSample::Yes);
-        return;
-    }
-
-    String diagnosticKey = cachedEntryReuseFailureToDiagnosticKey(decision);
-    LOG(NetworkCache, "(NetworkProcess) webPageID %llu: %s is in the cache but wasn't used, reason: %s", webPageID, requestURL.string().ascii().data(), diagnosticKey.utf8().data());
-    NetworkProcess::singleton().logDiagnosticMessageWithValue(webPageID, WebCore::DiagnosticLoggingKeys::networkCacheKey(), WebCore::DiagnosticLoggingKeys::unusableCachedEntryKey(), diagnosticKey, WebCore::ShouldSample::Yes);
-}
-
-void Statistics::markAsRequested(const String& hash)
-{
-    ASSERT(RunLoop::isMain());
-
-    m_hashesToAdd.add(hash);
-    if (!m_writeTimer.isActive())
-        m_writeTimer.startOneShot(mininumWriteInterval);
-}
-
-void Statistics::writeTimerFired()
-{
-    ASSERT(RunLoop::isMain());
-
-    Vector<StringCapture> hashesToAdd;
-    copyToVector(m_hashesToAdd, hashesToAdd);
-    m_hashesToAdd.clear();
-
-    Vector<std::pair<StringCapture, StoreDecision>> storeDecisionsToAdd;
-    copyToVector(m_storeDecisionsToAdd, storeDecisionsToAdd);
-    m_storeDecisionsToAdd.clear();
-
-    shrinkIfNeeded();
-
-    dispatch_async(m_backgroundIOQueue.get(), [this, hashesToAdd, storeDecisionsToAdd] {
-        if (!m_database.isOpen())
-            return;
-
-        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
-        WebCore::SQLiteTransaction writeTransaction(m_database);
-        writeTransaction.begin();
-
-        addHashesToDatabase(hashesToAdd);
-        addStoreDecisionsToDatabase(storeDecisionsToAdd);
-
-        writeTransaction.commit();
-    });
-}
-
-void Statistics::queryWasEverRequested(const String& hash, NeedUncachedReason needUncachedReason, const RequestedCompletionHandler& completionHandler)
-{
-    ASSERT(RunLoop::isMain());
-
-    // Query pending writes first.
-    bool wasAlreadyRequested = m_hashesToAdd.contains(hash);
-    if (wasAlreadyRequested && needUncachedReason == NeedUncachedReason::No) {
-        completionHandler(true, Nullopt);
-        return;
-    }
-    if (needUncachedReason == NeedUncachedReason::Yes && m_storeDecisionsToAdd.contains(hash)) {
-        completionHandler(true, m_storeDecisionsToAdd.get(hash));
-        return;
-    }
-
-    // Query the database.
-    auto everRequestedQuery = std::make_unique<EverRequestedQuery>(EverRequestedQuery { hash, needUncachedReason == NeedUncachedReason::Yes, completionHandler });
-    auto& query = *everRequestedQuery;
-    m_activeQueries.add(WTF::move(everRequestedQuery));
-    dispatch_async(m_backgroundIOQueue.get(), [this, wasAlreadyRequested, &query] () mutable {
-        WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
-        Optional<StoreDecision> storeDecision;
-        if (m_database.isOpen()) {
-            if (!wasAlreadyRequested) {
-                WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT hash FROM AlreadyRequested WHERE hash=?"));
-                if (statement.prepare() == WebCore::SQLResultOk) {
-                    statement.bindText(1, query.hash);
-                    wasAlreadyRequested = (statement.step() == WebCore::SQLResultRow);
-                }
-            }
-            if (wasAlreadyRequested && query.needUncachedReason) {
-                WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT reason FROM UncachedReason WHERE hash=?"));
-                storeDecision = StoreDecision::Yes;
-                if (statement.prepare() == WebCore::SQLResultOk) {
-                    statement.bindText(1, query.hash);
-                    if (statement.step() == WebCore::SQLResultRow)
-                        storeDecision = static_cast<StoreDecision>(statement.getColumnInt(0));
-                }
-            }
-        }
-        dispatch_async(dispatch_get_main_queue(), [this, &query, wasAlreadyRequested, storeDecision] {
-            query.completionHandler(wasAlreadyRequested, storeDecision);
-            m_activeQueries.remove(&query);
-        });
-    });
-}
-
-void Statistics::clear()
-{
-    ASSERT(RunLoop::isMain());
-
-    dispatch_async(m_backgroundIOQueue.get(), [this] {
-        if (m_database.isOpen()) {
-            WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter;
-            WebCore::SQLiteTransaction deleteTransaction(m_database);
-            deleteTransaction.begin();
-            executeSQLCommand(m_database, ASCIILiteral("DELETE FROM AlreadyRequested"));
-            executeSQLCommand(m_database, ASCIILiteral("DELETE FROM UncachedReason"));
-            deleteTransaction.commit();
-            m_approximateEntryCount = 0;
-        }
-    });
-}
-
-void Statistics::addHashesToDatabase(const Vector<StringCapture>& hashes)
-{
-    ASSERT(!RunLoop::isMain());
-    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
-    ASSERT(m_database.isOpen());
-
-    WebCore::SQLiteStatement statement(m_database, ASCIILiteral("INSERT OR IGNORE INTO AlreadyRequested (hash) VALUES (?)"));
-    if (statement.prepare() != WebCore::SQLResultOk)
-        return;
-
-    for (auto& hash : hashes) {
-        statement.bindText(1, hash.string());
-        if (executeSQLStatement(statement))
-            ++m_approximateEntryCount;
-        statement.reset();
-    }
-}
-
-void Statistics::addStoreDecisionsToDatabase(const Vector<std::pair<StringCapture, StoreDecision>>& storeDecisions)
-{
-    ASSERT(!RunLoop::isMain());
-    ASSERT(WebCore::SQLiteDatabaseTracker::hasTransactionInProgress());
-    ASSERT(m_database.isOpen());
-
-    WebCore::SQLiteStatement statement(m_database, ASCIILiteral("INSERT OR REPLACE INTO UncachedReason (hash, reason) VALUES (?, ?)"));
-    if (statement.prepare() != WebCore::SQLResultOk)
-        return;
-
-    for (auto& pair : storeDecisions) {
-        statement.bindText(1, pair.first.string());
-        statement.bindInt(2, static_cast<int>(pair.second));
-        executeSQLStatement(statement);
-        statement.reset();
-    }
-}
-
-}
-}
-
-#endif // ENABLE(NETWORK_CACHE)

Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (182089 => 182090)


--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj	2015-03-27 23:08:01 UTC (rev 182089)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj	2015-03-27 23:49:15 UTC (rev 182090)
@@ -1177,7 +1177,6 @@
 		7EC4F0FB18E4ACBB008056AF /* NetworkProcessCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7EC4F0F918E4A945008056AF /* NetworkProcessCocoa.mm */; };
 		834B250F1A831A8D00CFB150 /* NetworkCacheFileSystemPosix.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystemPosix.h */; };
 		834B25121A842C8700CFB150 /* NetworkCacheStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */; };
-		834B25131A842C8700CFB150 /* NetworkCacheStatisticsCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 834B25111A842C8700CFB150 /* NetworkCacheStatisticsCocoa.mm */; };
 		8372DB251A674C8F00C697C5 /* WKPageDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB241A674C8F00C697C5 /* WKPageDiagnosticLoggingClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		8372DB281A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */; };
 		8372DB291A67562800C697C5 /* WebPageDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */; };
@@ -1186,6 +1185,7 @@
 		83891B691A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		83891B6C1A68C30B0030F386 /* DiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */; };
 		83891B6D1A68C30B0030F386 /* DiagnosticLoggingClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83891B6B1A68C30B0030F386 /* DiagnosticLoggingClient.mm */; };
+		83BDCCB91AC5FDB6003F6441 /* NetworkCacheStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83BDCCB81AC5FDB6003F6441 /* NetworkCacheStatistics.cpp */; };
 		84477853176FCC0800CDC7BB /* InjectedBundleHitTestResultMediaType.h in Headers */ = {isa = PBXBuildFile; fileRef = 84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */; };
 		868160D0187645570021E79D /* WindowServerConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 868160CF187645370021E79D /* WindowServerConnection.mm */; };
 		86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E67A21190F411800004AB7 /* ProcessThrottler.h */; };
@@ -3385,7 +3385,6 @@
 		7EC4F0F918E4A945008056AF /* NetworkProcessCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkProcessCocoa.mm; path = NetworkProcess/cocoa/NetworkProcessCocoa.mm; sourceTree = "<group>"; };
 		834B250E1A831A8D00CFB150 /* NetworkCacheFileSystemPosix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheFileSystemPosix.h; sourceTree = "<group>"; };
 		834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheStatistics.h; sourceTree = "<group>"; };
-		834B25111A842C8700CFB150 /* NetworkCacheStatisticsCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NetworkCacheStatisticsCocoa.mm; sourceTree = "<group>"; };
 		8372DB241A674C8F00C697C5 /* WKPageDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPageDiagnosticLoggingClient.h; sourceTree = "<group>"; };
 		8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageDiagnosticLoggingClient.cpp; sourceTree = "<group>"; };
 		8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageDiagnosticLoggingClient.h; sourceTree = "<group>"; };
@@ -3394,6 +3393,7 @@
 		83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDiagnosticLoggingDelegate.h; sourceTree = "<group>"; };
 		83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingClient.h; sourceTree = "<group>"; };
 		83891B6B1A68C30B0030F386 /* DiagnosticLoggingClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DiagnosticLoggingClient.mm; sourceTree = "<group>"; };
+		83BDCCB81AC5FDB6003F6441 /* NetworkCacheStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheStatistics.cpp; sourceTree = "<group>"; };
 		84477851176FCAC100CDC7BB /* InjectedBundleHitTestResultMediaType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InjectedBundleHitTestResultMediaType.h; sourceTree = "<group>"; };
 		868160CD18763D4B0021E79D /* WindowServerConnection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WindowServerConnection.h; sourceTree = "<group>"; };
 		868160CF187645370021E79D /* WindowServerConnection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WindowServerConnection.mm; sourceTree = "<group>"; };
@@ -7484,8 +7484,8 @@
 				E42E060D1AA750E500B11699 /* NetworkCacheIOChannelCocoa.mm */,
 				E4436EC01A0CFDB200EAD204 /* NetworkCacheKey.cpp */,
 				E4436EC11A0CFDB200EAD204 /* NetworkCacheKey.h */,
+				83BDCCB81AC5FDB6003F6441 /* NetworkCacheStatistics.cpp */,
 				834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */,
-				834B25111A842C8700CFB150 /* NetworkCacheStatisticsCocoa.mm */,
 				E4436EC31A0CFDB200EAD204 /* NetworkCacheStorage.cpp */,
 				E4436EC21A0CFDB200EAD204 /* NetworkCacheStorage.h */,
 			);
@@ -9712,6 +9712,7 @@
 				512E352E130B55AF00ABD19A /* WebApplicationCacheManager.cpp in Sources */,
 				512E356A130B57F000ABD19A /* WebApplicationCacheManagerMessageReceiver.cpp in Sources */,
 				512E3524130B550600ABD19A /* WebApplicationCacheManagerProxy.cpp in Sources */,
+				83BDCCB91AC5FDB6003F6441 /* NetworkCacheStatistics.cpp in Sources */,
 				512E35F8130B642E00ABD19A /* WebApplicationCacheManagerProxyMessageReceiver.cpp in Sources */,
 				BC72BA1D11E64907001EB4EA /* WebBackForwardList.cpp in Sources */,
 				518D2CAD12D5153B003BB93B /* WebBackForwardListItem.cpp in Sources */,
@@ -10019,7 +10020,6 @@
 				1C8E293A12761E5B00BC7BD0 /* WKInspector.cpp in Sources */,
 				0F3C725C196F605200AEDD0C /* WKInspectorHighlightView.mm in Sources */,
 				A54293A5195A43DD002782C7 /* WKInspectorNodeSearchGestureRecognizer.mm in Sources */,
-				834B25131A842C8700CFB150 /* NetworkCacheStatisticsCocoa.mm in Sources */,
 				51A9E10A1315CD18009E7031 /* WKKeyValueStorageManager.cpp in Sources */,
 				33D3A3B51339600B00709BE4 /* WKMediaCacheManager.cpp in Sources */,
 				BC4075FD124FF0270068F20A /* WKMutableArray.cpp in Sources */,
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to