Title: [191377] trunk/Source/WebKit2
Revision
191377
Author
cdu...@apple.com
Date
2015-10-20 23:41:13 -0700 (Tue, 20 Oct 2015)

Log Message

[WK2] Generalize NetworkCacheStorage API so it can store different types of metadata
https://bugs.webkit.org/show_bug.cgi?id=150221
<rdar://problem/23149771>

Reviewed by Darin Adler and Antti Koivisto.

Generalize NetworkCacheStorage API so it can store different types of
metadata alongside the network resources. This is a pre-requirement to
making our NetworkCache smarter by storing information about the
resources.

To keep the code simple, the entry type is now part of the entry key and
we store records of a specific type in a 'type' subfolder. The cache
structure looks like so:
- WebKitCache/Version 5/[Partition]/[Type]/[Hash]
- WebKitCache/Version 5/[Partition]/[Type]/[Hash]-blob (Optional)

Existing cache entries now that the 'resource' type as these are network
resources.

* NetworkProcess/cache/NetworkCache.cpp:
* NetworkProcess/cache/NetworkCacheKey.cpp:
* NetworkProcess/cache/NetworkCacheKey.h:
* NetworkProcess/cache/NetworkCacheStatistics.cpp:
* NetworkProcess/cache/NetworkCacheStorage.cpp:
* NetworkProcess/cache/NetworkCacheStorage.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (191376 => 191377)


--- trunk/Source/WebKit2/ChangeLog	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/ChangeLog	2015-10-21 06:41:13 UTC (rev 191377)
@@ -1,3 +1,32 @@
+2015-10-20  Chris Dumez  <cdu...@apple.com>
+
+        [WK2] Generalize NetworkCacheStorage API so it can store different types of metadata
+        https://bugs.webkit.org/show_bug.cgi?id=150221
+        <rdar://problem/23149771>
+
+        Reviewed by Darin Adler and Antti Koivisto.
+
+        Generalize NetworkCacheStorage API so it can store different types of
+        metadata alongside the network resources. This is a pre-requirement to
+        making our NetworkCache smarter by storing information about the
+        resources.
+
+        To keep the code simple, the entry type is now part of the entry key and
+        we store records of a specific type in a 'type' subfolder. The cache
+        structure looks like so:
+        - WebKitCache/Version 5/[Partition]/[Type]/[Hash]
+        - WebKitCache/Version 5/[Partition]/[Type]/[Hash]-blob (Optional)
+
+        Existing cache entries now that the 'resource' type as these are network
+        resources.
+
+        * NetworkProcess/cache/NetworkCache.cpp:
+        * NetworkProcess/cache/NetworkCacheKey.cpp:
+        * NetworkProcess/cache/NetworkCacheKey.h:
+        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
+        * NetworkProcess/cache/NetworkCacheStorage.cpp:
+        * NetworkProcess/cache/NetworkCacheStorage.h:
+
 2015-10-20  Hunseop Jeong  <hs85.je...@samsung.com>
 
         [EFL] ContextMenu doesn't work correctly on MiniBrowser after r191194.

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp	2015-10-21 06:41:13 UTC (rev 191377)
@@ -39,6 +39,7 @@
 #include <WebCore/ResourceRequest.h>
 #include <WebCore/ResourceResponse.h>
 #include <WebCore/SharedBuffer.h>
+#include <wtf/MainThread.h>
 #include <wtf/NeverDestroyed.h>
 #include <wtf/RunLoop.h>
 #include <wtf/text/StringBuilder.h>
@@ -50,6 +51,13 @@
 namespace WebKit {
 namespace NetworkCache {
 
+static const AtomicString& resourceType()
+{
+    ASSERT(WTF::isMainThread());
+    static NeverDestroyed<const AtomicString> resource("resource", AtomicString::ConstructFromLiteral);
+    return resource;
+}
+
 Cache& singleton()
 {
     static NeverDestroyed<Cache> instance;
@@ -113,7 +121,7 @@
     // FIXME: This implements minimal Range header disk cache support. We don't parse
     // ranges so only the same exact range request will be served from the cache.
     String range = request.httpHeaderField(WebCore::HTTPHeaderName::Range);
-    return { partition, range, request.url().string() };
+    return { partition, resourceType(), range, request.url().string() };
 }
 
 static String headerValueForVary(const WebCore::ResourceRequest& request, const String& headerName)
@@ -472,7 +480,7 @@
 {
     ASSERT(isEnabled());
 
-    m_storage->traverse(0, [traverseHandler](const Storage::Record* record, const Storage::RecordInfo&) {
+    m_storage->traverse(resourceType(), 0, [traverseHandler](const Storage::Record* record, const Storage::RecordInfo&) {
         if (!record) {
             traverseHandler(nullptr);
             return;
@@ -509,7 +517,7 @@
     Totals totals;
     auto flags = Storage::TraverseFlag::ComputeWorth | Storage::TraverseFlag::ShareCount;
     size_t capacity = m_storage->capacity();
-    m_storage->traverse(flags, [fd, totals, capacity](const Storage::Record* record, const Storage::RecordInfo& info) mutable {
+    m_storage->traverse(resourceType(), flags, [fd, totals, capacity](const Storage::Record* record, const Storage::RecordInfo& info) mutable {
         if (!record) {
             StringBuilder epilogue;
             epilogue.appendLiteral("{}\n],\n");
@@ -567,7 +575,8 @@
         RunLoop::main().dispatch(completionHandler);
         return;
     }
-    m_storage->clear(modifiedSince, WTF::move(completionHandler));
+    String anyType;
+    m_storage->clear(anyType, modifiedSince, WTF::move(completionHandler));
 
     deleteDumpFile();
 }

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp	2015-10-21 06:41:13 UTC (rev 191377)
@@ -38,14 +38,16 @@
 
 Key::Key(const Key& o)
     : m_partition(o.m_partition.isolatedCopy())
+    , m_type(o.m_type.isolatedCopy())
     , m_identifier(o.m_identifier.isolatedCopy())
     , m_range(o.m_range.isolatedCopy())
     , m_hash(o.m_hash)
 {
 }
 
-Key::Key(const String& partition, const String& range, const String& identifier)
+Key::Key(const String& partition, const String& type, const String& range, const String& identifier)
     : m_partition(partition.isolatedCopy())
+    , m_type(type.isolatedCopy())
     , m_identifier(identifier.isolatedCopy())
     , m_range(range.isolatedCopy())
     , m_hash(computeHash())
@@ -55,6 +57,7 @@
 Key& Key::operator=(const Key& other)
 {
     m_partition = other.m_partition.isolatedCopy();
+    m_type = other.m_type.isolatedCopy();
     m_identifier = other.m_identifier.isolatedCopy();
     m_range = other.m_range.isolatedCopy();
     m_hash = other.m_hash;
@@ -83,6 +86,7 @@
     // SHA1 just happens to be suitably sized, fast and available.
     SHA1 sha1;
     hashString(sha1, m_partition);
+    hashString(sha1, m_type);
     hashString(sha1, m_identifier);
     hashString(sha1, m_range);
     SHA1::Digest hash;
@@ -124,12 +128,13 @@
 
 bool Key::operator==(const Key& other) const
 {
-    return m_hash == other.m_hash && m_partition == other.m_partition && m_identifier == other.m_identifier && m_range == other.m_range;
+    return m_hash == other.m_hash && m_partition == other.m_partition && m_type == other.m_type && m_identifier == other.m_identifier && m_range == other.m_range;
 }
 
 void Key::encode(Encoder& encoder) const
 {
     encoder << m_partition;
+    encoder << m_type;
     encoder << m_identifier;
     encoder << m_range;
     encoder << m_hash;
@@ -137,7 +142,7 @@
 
 bool Key::decode(Decoder& decoder, Key& key)
 {
-    return decoder.decode(key.m_partition) && decoder.decode(key.m_identifier) && decoder.decode(key.m_range) && decoder.decode(key.m_hash);
+    return decoder.decode(key.m_partition) && decoder.decode(key.m_type) && decoder.decode(key.m_identifier) && decoder.decode(key.m_range) && decoder.decode(key.m_hash);
 }
 
 }

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h	2015-10-21 06:41:13 UTC (rev 191377)
@@ -44,7 +44,7 @@
     Key() { }
     Key(const Key&);
     Key(Key&&) = default;
-    Key(const String& partition, const String& range, const String& identifier);
+    Key(const String& partition, const String& type, const String& range, const String& identifier);
 
     Key& operator=(const Key&);
     Key& operator=(Key&&) = default;
@@ -53,6 +53,7 @@
 
     const String& partition() const { return m_partition; }
     const String& identifier() const { return m_identifier; }
+    const String& type() const { return m_type; }
 
     HashType hash() const { return m_hash; }
 
@@ -71,6 +72,7 @@
     HashType computeHash() const;
 
     String m_partition;
+    String m_type;
     String m_identifier;
     String m_range;
     HashType m_hash;

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp	2015-10-21 06:41:13 UTC (rev 191377)
@@ -144,7 +144,10 @@
     LOG(NetworkCache, "(NetworkProcess) Bootstrapping the network cache statistics database from the network cache...");
 
     Vector<StringCapture> hashes;
-    traverseRecordsFiles(networkCachePath, [&hashes](const String& hashString, const String&) {
+    traverseRecordsFiles(networkCachePath, ASCIILiteral("resource"), [&hashes](const String& fileName, const String& hashString, const String& type, bool isBodyBlob, const String& recordDirectoryPath) {
+        if (isBodyBlob)
+            return;
+
         Key::HashType hash;
         if (!Key::stringToHash(hashString, hash))
             return;

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp	2015-10-21 06:41:13 UTC (rev 191377)
@@ -46,7 +46,7 @@
 static const char versionDirectoryPrefix[] = "Version ";
 static const char recordsDirectoryName[] = "Records";
 static const char blobsDirectoryName[] = "Blobs";
-static const char bodyPostfix[] = "-body";
+static const char blobSuffix[] = "-blob";
 
 static double computeRecordWorth(FileTimes);
 
@@ -113,11 +113,13 @@
 struct Storage::TraverseOperation {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    TraverseOperation(TraverseFlags flags, const TraverseHandler& handler)
-        : flags(flags)
+    TraverseOperation(const String& type, TraverseFlags flags, const TraverseHandler& handler)
+        : type(type)
+        , flags(flags)
         , handler(handler)
     { }
 
+    const String type;
     const TraverseFlags flags;
     const TraverseHandler handler;
 
@@ -151,27 +153,49 @@
     return WebCore::pathByAppendingComponent(makeVersionedDirectoryPath(baseDirectoryPath), blobsDirectoryName);
 }
 
-void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>& function)
+void traverseRecordsFiles(const String& recordsPath, const String& expectedType, const std::function<void (const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath)>& function)
 {
-    traverseDirectory(recordsPath, [&recordsPath, &function](const String& subdirName, DirectoryEntryType type) {
-        if (type != DirectoryEntryType::Directory)
+    traverseDirectory(recordsPath, [&recordsPath, &function, &expectedType](const String& partitionName, DirectoryEntryType entryType) {
+        if (entryType != DirectoryEntryType::Directory)
             return;
-        String partitionPath = WebCore::pathByAppendingComponent(recordsPath, subdirName);
-        traverseDirectory(partitionPath, [&function, &partitionPath](const String& fileName, DirectoryEntryType type) {
-            if (type != DirectoryEntryType::File)
+        String partitionPath = WebCore::pathByAppendingComponent(recordsPath, partitionName);
+        traverseDirectory(partitionPath, [&function, &partitionPath, &expectedType](const String& actualType, DirectoryEntryType entryType) {
+            if (entryType != DirectoryEntryType::Directory)
                 return;
-            function(fileName, partitionPath);
+            if (!expectedType.isEmpty() && expectedType != actualType)
+                return;
+            String recordDirectoryPath = WebCore::pathByAppendingComponent(partitionPath, actualType);
+            traverseDirectory(recordDirectoryPath, [&function, &recordDirectoryPath, &actualType](const String& fileName, DirectoryEntryType entryType) {
+                if (entryType != DirectoryEntryType::File || fileName.length() < Key::hashStringLength())
+                    return;
+
+                String hashString = fileName.substring(0, Key::hashStringLength());
+                auto isBlob = fileName.length() > Key::hashStringLength() && fileName.endsWith(blobSuffix);
+                function(fileName, hashString, actualType, isBlob, recordDirectoryPath);
+            });
         });
     });
 }
 
 static void deleteEmptyRecordsDirectories(const String& recordsPath)
 {
-    traverseDirectory(recordsPath, [&recordsPath](const String& subdirName, DirectoryEntryType type) {
+    traverseDirectory(recordsPath, [&recordsPath](const String& partitionName, DirectoryEntryType type) {
         if (type != DirectoryEntryType::Directory)
             return;
+
+        // Delete [type] sub-folders.
+        String partitionPath = WebCore::pathByAppendingComponent(recordsPath, partitionName);
+        traverseDirectory(partitionPath, [&partitionPath](const String& subdirName, DirectoryEntryType entryType) {
+            if (entryType != DirectoryEntryType::Directory)
+                return;
+
+            // Let system figure out if it is really empty.
+            WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(partitionPath, subdirName));
+        });
+
+        // Delete [Partition] folders.
         // Let system figure out if it is really empty.
-        WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(recordsPath, subdirName));
+        WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(recordsPath, partitionName));
     });
 }
 
@@ -225,14 +249,13 @@
 
     backgroundIOQueue().dispatch([this] {
         auto recordFilter = std::make_unique<ContentsFilter>();
-        auto bodyFilter = std::make_unique<ContentsFilter>();
+        auto blobFilter = std::make_unique<ContentsFilter>();
         size_t recordsSize = 0;
         unsigned count = 0;
-        traverseRecordsFiles(recordsPath(), [&recordFilter, &bodyFilter, &recordsSize, &count](const String& fileName, const String& partitionPath) {
-            auto filePath = WebCore::pathByAppendingComponent(partitionPath, fileName);
+        String anyType;
+        traverseRecordsFiles(recordsPath(), anyType, [&recordFilter, &blobFilter, &recordsSize, &count](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
+            auto filePath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
 
-            bool isBody = fileName.endsWith(bodyPostfix);
-            String hashString = isBody ? fileName.substring(0, Key::hashStringLength()) : fileName;
             Key::HashType hash;
             if (!Key::stringToHash(hashString, hash)) {
                 WebCore::deleteFile(filePath);
@@ -244,31 +267,33 @@
                 WebCore::deleteFile(filePath);
                 return;
             }
-            if (isBody) {
-                bodyFilter->add(hash);
+
+            if (isBlob) {
+                blobFilter->add(hash);
                 return;
             }
+
             recordFilter->add(hash);
             recordsSize += fileSize;
             ++count;
         });
 
         auto* recordFilterPtr = recordFilter.release();
-        auto* bodyFilterPtr = bodyFilter.release();
-        RunLoop::main().dispatch([this, recordFilterPtr, bodyFilterPtr, recordsSize] {
+        auto* blobFilterPtr = blobFilter.release();
+        RunLoop::main().dispatch([this, recordFilterPtr, blobFilterPtr, recordsSize] {
             auto recordFilter = std::unique_ptr<ContentsFilter>(recordFilterPtr);
-            auto bodyFilter = std::unique_ptr<ContentsFilter>(bodyFilterPtr);
+            auto blobFilter = std::unique_ptr<ContentsFilter>(blobFilterPtr);
 
-            for (auto& hash : m_recordFilterHashesAddedDuringSynchronization)
-                recordFilter->add(hash);
+            for (auto& recordFilterKey : m_recordFilterHashesAddedDuringSynchronization)
+                recordFilter->add(recordFilterKey);
             m_recordFilterHashesAddedDuringSynchronization.clear();
 
-            for (auto& hash : m_bodyFilterHashesAddedDuringSynchronization)
-                bodyFilter->add(hash);
-            m_bodyFilterHashesAddedDuringSynchronization.clear();
+            for (auto& hash : m_blobFilterHashesAddedDuringSynchronization)
+                blobFilter->add(hash);
+            m_blobFilterHashesAddedDuringSynchronization.clear();
 
             m_recordFilter = WTF::move(recordFilter);
-            m_bodyFilter = WTF::move(bodyFilter);
+            m_blobFilter = WTF::move(blobFilter);
             m_approximateRecordsSize = recordsSize;
             m_synchronizationInProgress = false;
         });
@@ -277,7 +302,7 @@
 
         deleteEmptyRecordsDirectories(recordsPath());
 
-        LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%d", recordsSize, count);
+        LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%u", recordsSize, count);
     });
 }
 
@@ -299,30 +324,32 @@
     return !m_recordFilter || m_recordFilter->mayContain(key.hash());
 }
 
-String Storage::partitionPathForKey(const Key& key) const
+bool Storage::mayContainBlob(const Key& key) const
 {
-    ASSERT(!key.partition().isEmpty());
-    return WebCore::pathByAppendingComponent(recordsPath(), key.partition());
+    ASSERT(RunLoop::isMain());
+    return !m_blobFilter || m_blobFilter->mayContain(key.hash());
 }
 
-static String fileNameForKey(const Key& key)
+String Storage::recordDirectoryPathForKey(const Key& key) const
 {
-    return key.hashAsString();
+    ASSERT(!key.partition().isEmpty());
+    ASSERT(!key.type().isEmpty());
+    return WebCore::pathByAppendingComponent(WebCore::pathByAppendingComponent(recordsPath(), key.partition()), key.type());
 }
 
 String Storage::recordPathForKey(const Key& key) const
 {
-    return WebCore::pathByAppendingComponent(partitionPathForKey(key), fileNameForKey(key));
+    return WebCore::pathByAppendingComponent(recordDirectoryPathForKey(key), key.hashAsString());
 }
 
-static String bodyPathForRecordPath(const String& recordPath)
+static String blobPathForRecordPath(const String& recordPath)
 {
-    return recordPath + bodyPostfix;
+    return recordPath + blobSuffix;
 }
 
-String Storage::bodyPathForKey(const Key& key) const
+String Storage::blobPathForKey(const Key& key) const
 {
-    return bodyPathForRecordPath(recordPathForKey(key));
+    return blobPathForRecordPath(recordPathForKey(key));
 }
 
 struct RecordMetaData {
@@ -452,20 +479,20 @@
 
 Optional<BlobStorage::Blob> Storage::storeBodyAsBlob(WriteOperation& writeOperation)
 {
-    auto bodyPath = bodyPathForKey(writeOperation.record.key);
+    auto blobPath = blobPathForKey(writeOperation.record.key);
 
     // Store the body.
-    auto blob = m_blobStorage.add(bodyPath, writeOperation.record.body);
+    auto blob = m_blobStorage.add(blobPath, writeOperation.record.body);
     if (blob.data.isNull())
         return { };
 
     ++writeOperation.activeCount;
 
     RunLoop::main().dispatch([this, blob, &writeOperation] {
-        if (m_bodyFilter)
-            m_bodyFilter->add(writeOperation.record.key.hash());
+        if (m_blobFilter)
+            m_blobFilter->add(writeOperation.record.key.hash());
         if (m_synchronizationInProgress)
-            m_bodyFilterHashesAddedDuringSynchronization.append(writeOperation.record.key.hash());
+            m_blobFilterHashesAddedDuringSynchronization.append(writeOperation.record.key.hash());
 
         if (writeOperation.mappedBodyHandler)
             writeOperation.mappedBodyHandler(blob.data);
@@ -523,7 +550,7 @@
 
     serialBackgroundIOQueue().dispatch([this, key] {
         WebCore::deleteFile(recordPathForKey(key));
-        m_blobStorage.remove(bodyPathForKey(key));
+        m_blobStorage.remove(blobPathForKey(key));
     });
 }
 
@@ -546,7 +573,7 @@
     const auto readTimeout = 1500_ms;
     m_readOperationTimeoutTimer.startOneShot(readTimeout);
 
-    bool shouldGetBodyBlob = !m_bodyFilter || m_bodyFilter->mayContain(readOperation.key.hash());
+    bool shouldGetBodyBlob = mayContainBlob(readOperation.key);
 
     ioQueue().dispatch([this, &readOperation, shouldGetBodyBlob] {
         auto recordPath = recordPathForKey(readOperation.key);
@@ -563,9 +590,9 @@
         });
 
         if (shouldGetBodyBlob) {
-            // Read the body blob in parallel with the record read.
-            auto bodyPath = bodyPathForKey(readOperation.key);
-            readOperation.resultBodyBlob = m_blobStorage.get(bodyPath);
+            // Read the blob in parallel with the record read.
+            auto blobPath = blobPathForKey(readOperation.key);
+            readOperation.resultBodyBlob = m_blobStorage.get(blobPath);
             finishReadOperation(readOperation);
         }
     });
@@ -574,7 +601,7 @@
 void Storage::finishReadOperation(ReadOperation& readOperation)
 {
     ASSERT(readOperation.activeCount);
-    // Record and body blob reads must finish.
+    // Record and blob reads must finish.
     if (--readOperation.activeCount)
         return;
 
@@ -681,17 +708,17 @@
     addToRecordFilter(writeOperation.record.key);
 
     backgroundIOQueue().dispatch([this, &writeOperation] {
-        auto partitionPath = partitionPathForKey(writeOperation.record.key);
+        auto recordDirectorPath = recordDirectoryPathForKey(writeOperation.record.key);
         auto recordPath = recordPathForKey(writeOperation.record.key);
 
-        WebCore::makeAllDirectories(partitionPath);
+        WebCore::makeAllDirectories(recordDirectorPath);
 
         ++writeOperation.activeCount;
 
         bool shouldStoreAsBlob = shouldStoreBodyAsBlob(writeOperation.record.body);
-        auto bodyBlob = shouldStoreAsBlob ? storeBodyAsBlob(writeOperation) : Nullopt;
+        auto blob = shouldStoreAsBlob ? storeBodyAsBlob(writeOperation) : Nullopt;
 
-        auto recordData = encodeRecord(writeOperation.record, bodyBlob);
+        auto recordData = encodeRecord(writeOperation.record, blob);
 
         auto channel = IOChannel::open(recordPath, IOChannel::Type::Create);
         size_t recordSize = recordData.size();
@@ -770,28 +797,30 @@
     m_writeOperationDispatchTimer.startOneShot(initialWriteDelay);
 }
 
-void Storage::traverse(TraverseFlags flags, TraverseHandler&& traverseHandler)
+void Storage::traverse(const String& type, TraverseFlags flags, TraverseHandler&& traverseHandler)
 {
     ASSERT(RunLoop::isMain());
     ASSERT(traverseHandler);
     // Avoid non-thread safe std::function copies.
 
-    auto traverseOperationPtr = std::make_unique<TraverseOperation>(flags, WTF::move(traverseHandler));
+    auto traverseOperationPtr = std::make_unique<TraverseOperation>(type, flags, WTF::move(traverseHandler));
     auto& traverseOperation = *traverseOperationPtr;
     m_activeTraverseOperations.add(WTF::move(traverseOperationPtr));
 
     ioQueue().dispatch([this, &traverseOperation] {
-        traverseRecordsFiles(recordsPath(), [this, &traverseOperation](const String& fileName, const String& partitionPath) {
-            if (fileName.length() != Key::hashStringLength())
+        traverseRecordsFiles(recordsPath(), traverseOperation.type, [this, &traverseOperation](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
+            ASSERT(type == traverseOperation.type);
+            if (isBlob)
                 return;
-            auto recordPath = WebCore::pathByAppendingComponent(partitionPath, fileName);
 
+            auto recordPath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
+
             double worth = -1;
             if (traverseOperation.flags & TraverseFlag::ComputeWorth)
                 worth = computeRecordWorth(fileTimes(recordPath));
             unsigned bodyShareCount = 0;
             if (traverseOperation.flags & TraverseFlag::ShareCount)
-                bodyShareCount = m_blobStorage.shareCount(bodyPathForRecordPath(recordPath));
+                bodyShareCount = m_blobStorage.shareCount(blobPathForRecordPath(recordPath));
 
             std::unique_lock<Lock> lock(traverseOperation.activeMutex);
             ++traverseOperation.activeCount;
@@ -856,24 +885,24 @@
     shrinkIfNeeded();
 }
 
-void Storage::clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler)
+void Storage::clear(const String& type, std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
     LOG(NetworkCacheStorage, "(NetworkProcess) clearing cache");
 
     if (m_recordFilter)
         m_recordFilter->clear();
-    if (m_bodyFilter)
-        m_bodyFilter->clear();
+    if (m_blobFilter)
+        m_blobFilter->clear();
     m_approximateRecordsSize = 0;
 
     // Avoid non-thread safe std::function copies.
     auto* completionHandlerPtr = completionHandler ? new std::function<void ()>(WTF::move(completionHandler)) : nullptr;
-
-    ioQueue().dispatch([this, modifiedSinceTime, completionHandlerPtr] {
+    StringCapture typeCapture(type);
+    ioQueue().dispatch([this, modifiedSinceTime, completionHandlerPtr, typeCapture] {
         auto recordsPath = this->recordsPath();
-        traverseRecordsFiles(recordsPath, [modifiedSinceTime](const String& fileName, const String& partitionPath) {
-            auto filePath = WebCore::pathByAppendingComponent(partitionPath, fileName);
+        traverseRecordsFiles(recordsPath, typeCapture.string(), [modifiedSinceTime](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
+            auto filePath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
             if (modifiedSinceTime > std::chrono::system_clock::time_point::min()) {
                 auto times = fileTimes(filePath);
                 if (times.modification < modifiedSinceTime)
@@ -884,7 +913,7 @@
 
         deleteEmptyRecordsDirectories(recordsPath);
 
-        // This cleans unreferences blobs.
+        // This cleans unreferenced blobs.
         m_blobStorage.synchronize();
 
         if (completionHandlerPtr) {
@@ -950,14 +979,16 @@
 
     backgroundIOQueue().dispatch([this] {
         auto recordsPath = this->recordsPath();
-        traverseRecordsFiles(recordsPath, [this](const String& fileName, const String& partitionPath) {
-            if (fileName.length() != Key::hashStringLength())
+        String anyType;
+        traverseRecordsFiles(recordsPath, anyType, [this](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
+            if (isBlob)
                 return;
-            auto recordPath = WebCore::pathByAppendingComponent(partitionPath, fileName);
-            auto bodyPath = bodyPathForRecordPath(recordPath);
 
+            auto recordPath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
+            auto blobPath = blobPathForRecordPath(recordPath);
+
             auto times = fileTimes(recordPath);
-            unsigned bodyShareCount = m_blobStorage.shareCount(bodyPath);
+            unsigned bodyShareCount = m_blobStorage.shareCount(blobPath);
             auto probability = deletionProbability(times, bodyShareCount);
 
             bool shouldDelete = randomNumber() < probability;
@@ -966,7 +997,7 @@
 
             if (shouldDelete) {
                 WebCore::deleteFile(recordPath);
-                m_blobStorage.remove(bodyPath);
+                m_blobStorage.remove(blobPath);
             }
         });
 

Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h (191376 => 191377)


--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h	2015-10-21 06:20:58 UTC (rev 191376)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h	2015-10-21 06:41:13 UTC (rev 191377)
@@ -65,7 +65,7 @@
     void store(const Record&, MappedBodyHandler&&);
 
     void remove(const Key&);
-    void clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
+    void clear(const String& type, std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
 
     struct RecordInfo {
         size_t bodySize;
@@ -80,13 +80,13 @@
     typedef unsigned TraverseFlags;
     typedef std::function<void (const Record*, const RecordInfo&)> TraverseHandler;
     // Null record signals end.
-    void traverse(TraverseFlags, TraverseHandler&&);
+    void traverse(const String& type, TraverseFlags, TraverseHandler&&);
 
     void setCapacity(size_t);
     size_t capacity() const { return m_capacity; }
     size_t approximateSize() const;
 
-    static const unsigned version = 4;
+    static const unsigned version = 5;
 
     String basePath() const;
     String versionPath() const;
@@ -97,9 +97,9 @@
 private:
     Storage(const String& directoryPath);
 
-    String partitionPathForKey(const Key&) const;
+    String recordDirectoryPathForKey(const Key&) const;
     String recordPathForKey(const Key&) const;
-    String bodyPathForKey(const Key&) const;
+    String blobPathForKey(const Key&) const;
 
     void synchronize();
     void deleteOldVersions();
@@ -129,6 +129,7 @@
     WorkQueue& serialBackgroundIOQueue() { return m_serialBackgroundIOQueue.get(); }
 
     bool mayContain(const Key&) const;
+    bool mayContainBlob(const Key&) const;
 
     void addToRecordFilter(const Key&);
 
@@ -141,13 +142,13 @@
     // 2^18 bit filter can support up to 26000 entries with false positive rate < 1%.
     using ContentsFilter = BloomFilter<18>;
     std::unique_ptr<ContentsFilter> m_recordFilter;
-    std::unique_ptr<ContentsFilter> m_bodyFilter;
+    std::unique_ptr<ContentsFilter> m_blobFilter;
 
     bool m_synchronizationInProgress { false };
     bool m_shrinkInProgress { false };
 
     Vector<Key::HashType> m_recordFilterHashesAddedDuringSynchronization;
-    Vector<Key::HashType> m_bodyFilterHashesAddedDuringSynchronization;
+    Vector<Key::HashType> m_blobFilterHashesAddedDuringSynchronization;
 
     static const int maximumRetrievePriority = 4;
     Deque<std::unique_ptr<ReadOperation>> m_pendingReadOperationsByPriority[maximumRetrievePriority + 1];
@@ -169,7 +170,7 @@
 };
 
 // FIXME: Remove, used by NetworkCacheStatistics only.
-void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>&);
+void traverseRecordsFiles(const String& recordsPath, const String& type, const std::function<void (const String& fileName, const String& hashString, const String& type, bool isBodyBlob, const String& recordDirectoryPath)>&);
 
 }
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to