Changeset 191377 in webkit


Ignore:
Timestamp:
Oct 20, 2015 11:41:13 PM (9 years ago)
Author:
Chris Dumez
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:
Location:
trunk/Source/WebKit2
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r191368 r191377  
     12015-10-20  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2] Generalize NetworkCacheStorage API so it can store different types of metadata
     4        https://bugs.webkit.org/show_bug.cgi?id=150221
     5        <rdar://problem/23149771>
     6
     7        Reviewed by Darin Adler and Antti Koivisto.
     8
     9        Generalize NetworkCacheStorage API so it can store different types of
     10        metadata alongside the network resources. This is a pre-requirement to
     11        making our NetworkCache smarter by storing information about the
     12        resources.
     13
     14        To keep the code simple, the entry type is now part of the entry key and
     15        we store records of a specific type in a 'type' subfolder. The cache
     16        structure looks like so:
     17        - WebKitCache/Version 5/[Partition]/[Type]/[Hash]
     18        - WebKitCache/Version 5/[Partition]/[Type]/[Hash]-blob (Optional)
     19
     20        Existing cache entries now that the 'resource' type as these are network
     21        resources.
     22
     23        * NetworkProcess/cache/NetworkCache.cpp:
     24        * NetworkProcess/cache/NetworkCacheKey.cpp:
     25        * NetworkProcess/cache/NetworkCacheKey.h:
     26        * NetworkProcess/cache/NetworkCacheStatistics.cpp:
     27        * NetworkProcess/cache/NetworkCacheStorage.cpp:
     28        * NetworkProcess/cache/NetworkCacheStorage.h:
     29
    1302015-10-20  Hunseop Jeong  <hs85.jeong@samsung.com>
    231
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r191354 r191377  
    4040#include <WebCore/ResourceResponse.h>
    4141#include <WebCore/SharedBuffer.h>
     42#include <wtf/MainThread.h>
    4243#include <wtf/NeverDestroyed.h>
    4344#include <wtf/RunLoop.h>
     
    5051namespace WebKit {
    5152namespace NetworkCache {
     53
     54static const AtomicString& resourceType()
     55{
     56    ASSERT(WTF::isMainThread());
     57    static NeverDestroyed<const AtomicString> resource("resource", AtomicString::ConstructFromLiteral);
     58    return resource;
     59}
    5260
    5361Cache& singleton()
     
    114122    // ranges so only the same exact range request will be served from the cache.
    115123    String range = request.httpHeaderField(WebCore::HTTPHeaderName::Range);
    116     return { partition, range, request.url().string() };
     124    return { partition, resourceType(), range, request.url().string() };
    117125}
    118126
     
    473481    ASSERT(isEnabled());
    474482
    475     m_storage->traverse(0, [traverseHandler](const Storage::Record* record, const Storage::RecordInfo&) {
     483    m_storage->traverse(resourceType(), 0, [traverseHandler](const Storage::Record* record, const Storage::RecordInfo&) {
    476484        if (!record) {
    477485            traverseHandler(nullptr);
     
    510518    auto flags = Storage::TraverseFlag::ComputeWorth | Storage::TraverseFlag::ShareCount;
    511519    size_t capacity = m_storage->capacity();
    512     m_storage->traverse(flags, [fd, totals, capacity](const Storage::Record* record, const Storage::RecordInfo& info) mutable {
     520    m_storage->traverse(resourceType(), flags, [fd, totals, capacity](const Storage::Record* record, const Storage::RecordInfo& info) mutable {
    513521        if (!record) {
    514522            StringBuilder epilogue;
     
    568576        return;
    569577    }
    570     m_storage->clear(modifiedSince, WTF::move(completionHandler));
     578    String anyType;
     579    m_storage->clear(anyType, modifiedSince, WTF::move(completionHandler));
    571580
    572581    deleteDumpFile();
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp

    r191354 r191377  
    3939Key::Key(const Key& o)
    4040    : m_partition(o.m_partition.isolatedCopy())
     41    , m_type(o.m_type.isolatedCopy())
    4142    , m_identifier(o.m_identifier.isolatedCopy())
    4243    , m_range(o.m_range.isolatedCopy())
     
    4546}
    4647
    47 Key::Key(const String& partition, const String& range, const String& identifier)
     48Key::Key(const String& partition, const String& type, const String& range, const String& identifier)
    4849    : m_partition(partition.isolatedCopy())
     50    , m_type(type.isolatedCopy())
    4951    , m_identifier(identifier.isolatedCopy())
    5052    , m_range(range.isolatedCopy())
     
    5658{
    5759    m_partition = other.m_partition.isolatedCopy();
     60    m_type = other.m_type.isolatedCopy();
    5861    m_identifier = other.m_identifier.isolatedCopy();
    5962    m_range = other.m_range.isolatedCopy();
     
    8487    SHA1 sha1;
    8588    hashString(sha1, m_partition);
     89    hashString(sha1, m_type);
    8690    hashString(sha1, m_identifier);
    8791    hashString(sha1, m_range);
     
    125129bool Key::operator==(const Key& other) const
    126130{
    127     return m_hash == other.m_hash && m_partition == other.m_partition && m_identifier == other.m_identifier && m_range == other.m_range;
     131    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;
    128132}
    129133
     
    131135{
    132136    encoder << m_partition;
     137    encoder << m_type;
    133138    encoder << m_identifier;
    134139    encoder << m_range;
     
    138143bool Key::decode(Decoder& decoder, Key& key)
    139144{
    140     return decoder.decode(key.m_partition) && decoder.decode(key.m_identifier) && decoder.decode(key.m_range) && decoder.decode(key.m_hash);
     145    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);
    141146}
    142147
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h

    r191354 r191377  
    4545    Key(const Key&);
    4646    Key(Key&&) = default;
    47     Key(const String& partition, const String& range, const String& identifier);
     47    Key(const String& partition, const String& type, const String& range, const String& identifier);
    4848
    4949    Key& operator=(const Key&);
     
    5454    const String& partition() const { return m_partition; }
    5555    const String& identifier() const { return m_identifier; }
     56    const String& type() const { return m_type; }
    5657
    5758    HashType hash() const { return m_hash; }
     
    7273
    7374    String m_partition;
     75    String m_type;
    7476    String m_identifier;
    7577    String m_range;
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatistics.cpp

    r191354 r191377  
    145145
    146146    Vector<StringCapture> hashes;
    147     traverseRecordsFiles(networkCachePath, [&hashes](const String& hashString, const String&) {
     147    traverseRecordsFiles(networkCachePath, ASCIILiteral("resource"), [&hashes](const String& fileName, const String& hashString, const String& type, bool isBodyBlob, const String& recordDirectoryPath) {
     148        if (isBodyBlob)
     149            return;
     150
    148151        Key::HashType hash;
    149152        if (!Key::stringToHash(hashString, hash))
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp

    r191354 r191377  
    4747static const char recordsDirectoryName[] = "Records";
    4848static const char blobsDirectoryName[] = "Blobs";
    49 static const char bodyPostfix[] = "-body";
     49static const char blobSuffix[] = "-blob";
    5050
    5151static double computeRecordWorth(FileTimes);
     
    114114    WTF_MAKE_FAST_ALLOCATED;
    115115public:
    116     TraverseOperation(TraverseFlags flags, const TraverseHandler& handler)
    117         : flags(flags)
     116    TraverseOperation(const String& type, TraverseFlags flags, const TraverseHandler& handler)
     117        : type(type)
     118        , flags(flags)
    118119        , handler(handler)
    119120    { }
    120121
     122    const String type;
    121123    const TraverseFlags flags;
    122124    const TraverseHandler handler;
     
    152154}
    153155
    154 void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>& function)
    155 {
    156     traverseDirectory(recordsPath, [&recordsPath, &function](const String& subdirName, DirectoryEntryType type) {
     156void 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)
     157{
     158    traverseDirectory(recordsPath, [&recordsPath, &function, &expectedType](const String& partitionName, DirectoryEntryType entryType) {
     159        if (entryType != DirectoryEntryType::Directory)
     160            return;
     161        String partitionPath = WebCore::pathByAppendingComponent(recordsPath, partitionName);
     162        traverseDirectory(partitionPath, [&function, &partitionPath, &expectedType](const String& actualType, DirectoryEntryType entryType) {
     163            if (entryType != DirectoryEntryType::Directory)
     164                return;
     165            if (!expectedType.isEmpty() && expectedType != actualType)
     166                return;
     167            String recordDirectoryPath = WebCore::pathByAppendingComponent(partitionPath, actualType);
     168            traverseDirectory(recordDirectoryPath, [&function, &recordDirectoryPath, &actualType](const String& fileName, DirectoryEntryType entryType) {
     169                if (entryType != DirectoryEntryType::File || fileName.length() < Key::hashStringLength())
     170                    return;
     171
     172                String hashString = fileName.substring(0, Key::hashStringLength());
     173                auto isBlob = fileName.length() > Key::hashStringLength() && fileName.endsWith(blobSuffix);
     174                function(fileName, hashString, actualType, isBlob, recordDirectoryPath);
     175            });
     176        });
     177    });
     178}
     179
     180static void deleteEmptyRecordsDirectories(const String& recordsPath)
     181{
     182    traverseDirectory(recordsPath, [&recordsPath](const String& partitionName, DirectoryEntryType type) {
    157183        if (type != DirectoryEntryType::Directory)
    158184            return;
    159         String partitionPath = WebCore::pathByAppendingComponent(recordsPath, subdirName);
    160         traverseDirectory(partitionPath, [&function, &partitionPath](const String& fileName, DirectoryEntryType type) {
    161             if (type != DirectoryEntryType::File)
    162                 return;
    163             function(fileName, partitionPath);
    164         });
    165     });
    166 }
    167 
    168 static void deleteEmptyRecordsDirectories(const String& recordsPath)
    169 {
    170     traverseDirectory(recordsPath, [&recordsPath](const String& subdirName, DirectoryEntryType type) {
    171         if (type != DirectoryEntryType::Directory)
    172             return;
     185
     186        // Delete [type] sub-folders.
     187        String partitionPath = WebCore::pathByAppendingComponent(recordsPath, partitionName);
     188        traverseDirectory(partitionPath, [&partitionPath](const String& subdirName, DirectoryEntryType entryType) {
     189            if (entryType != DirectoryEntryType::Directory)
     190                return;
     191
     192            // Let system figure out if it is really empty.
     193            WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(partitionPath, subdirName));
     194        });
     195
     196        // Delete [Partition] folders.
    173197        // Let system figure out if it is really empty.
    174         WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(recordsPath, subdirName));
     198        WebCore::deleteEmptyDirectory(WebCore::pathByAppendingComponent(recordsPath, partitionName));
    175199    });
    176200}
     
    226250    backgroundIOQueue().dispatch([this] {
    227251        auto recordFilter = std::make_unique<ContentsFilter>();
    228         auto bodyFilter = std::make_unique<ContentsFilter>();
     252        auto blobFilter = std::make_unique<ContentsFilter>();
    229253        size_t recordsSize = 0;
    230254        unsigned count = 0;
    231         traverseRecordsFiles(recordsPath(), [&recordFilter, &bodyFilter, &recordsSize, &count](const String& fileName, const String& partitionPath) {
    232             auto filePath = WebCore::pathByAppendingComponent(partitionPath, fileName);
    233 
    234             bool isBody = fileName.endsWith(bodyPostfix);
    235             String hashString = isBody ? fileName.substring(0, Key::hashStringLength()) : fileName;
     255        String anyType;
     256        traverseRecordsFiles(recordsPath(), anyType, [&recordFilter, &blobFilter, &recordsSize, &count](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
     257            auto filePath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
     258
    236259            Key::HashType hash;
    237260            if (!Key::stringToHash(hashString, hash)) {
     
    245268                return;
    246269            }
    247             if (isBody) {
    248                 bodyFilter->add(hash);
     270
     271            if (isBlob) {
     272                blobFilter->add(hash);
    249273                return;
    250274            }
     275
    251276            recordFilter->add(hash);
    252277            recordsSize += fileSize;
     
    255280
    256281        auto* recordFilterPtr = recordFilter.release();
    257         auto* bodyFilterPtr = bodyFilter.release();
    258         RunLoop::main().dispatch([this, recordFilterPtr, bodyFilterPtr, recordsSize] {
     282        auto* blobFilterPtr = blobFilter.release();
     283        RunLoop::main().dispatch([this, recordFilterPtr, blobFilterPtr, recordsSize] {
    259284            auto recordFilter = std::unique_ptr<ContentsFilter>(recordFilterPtr);
    260             auto bodyFilter = std::unique_ptr<ContentsFilter>(bodyFilterPtr);
    261 
    262             for (auto& hash : m_recordFilterHashesAddedDuringSynchronization)
    263                 recordFilter->add(hash);
     285            auto blobFilter = std::unique_ptr<ContentsFilter>(blobFilterPtr);
     286
     287            for (auto& recordFilterKey : m_recordFilterHashesAddedDuringSynchronization)
     288                recordFilter->add(recordFilterKey);
    264289            m_recordFilterHashesAddedDuringSynchronization.clear();
    265290
    266             for (auto& hash : m_bodyFilterHashesAddedDuringSynchronization)
    267                 bodyFilter->add(hash);
    268             m_bodyFilterHashesAddedDuringSynchronization.clear();
     291            for (auto& hash : m_blobFilterHashesAddedDuringSynchronization)
     292                blobFilter->add(hash);
     293            m_blobFilterHashesAddedDuringSynchronization.clear();
    269294
    270295            m_recordFilter = WTF::move(recordFilter);
    271             m_bodyFilter = WTF::move(bodyFilter);
     296            m_blobFilter = WTF::move(blobFilter);
    272297            m_approximateRecordsSize = recordsSize;
    273298            m_synchronizationInProgress = false;
     
    278303        deleteEmptyRecordsDirectories(recordsPath());
    279304
    280         LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%d", recordsSize, count);
     305        LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%u", recordsSize, count);
    281306    });
    282307}
     
    300325}
    301326
    302 String Storage::partitionPathForKey(const Key& key) const
     327bool Storage::mayContainBlob(const Key& key) const
     328{
     329    ASSERT(RunLoop::isMain());
     330    return !m_blobFilter || m_blobFilter->mayContain(key.hash());
     331}
     332
     333String Storage::recordDirectoryPathForKey(const Key& key) const
    303334{
    304335    ASSERT(!key.partition().isEmpty());
    305     return WebCore::pathByAppendingComponent(recordsPath(), key.partition());
    306 }
    307 
    308 static String fileNameForKey(const Key& key)
    309 {
    310     return key.hashAsString();
     336    ASSERT(!key.type().isEmpty());
     337    return WebCore::pathByAppendingComponent(WebCore::pathByAppendingComponent(recordsPath(), key.partition()), key.type());
    311338}
    312339
    313340String Storage::recordPathForKey(const Key& key) const
    314341{
    315     return WebCore::pathByAppendingComponent(partitionPathForKey(key), fileNameForKey(key));
    316 }
    317 
    318 static String bodyPathForRecordPath(const String& recordPath)
    319 {
    320     return recordPath + bodyPostfix;
    321 }
    322 
    323 String Storage::bodyPathForKey(const Key& key) const
    324 {
    325     return bodyPathForRecordPath(recordPathForKey(key));
     342    return WebCore::pathByAppendingComponent(recordDirectoryPathForKey(key), key.hashAsString());
     343}
     344
     345static String blobPathForRecordPath(const String& recordPath)
     346{
     347    return recordPath + blobSuffix;
     348}
     349
     350String Storage::blobPathForKey(const Key& key) const
     351{
     352    return blobPathForRecordPath(recordPathForKey(key));
    326353}
    327354
     
    453480Optional<BlobStorage::Blob> Storage::storeBodyAsBlob(WriteOperation& writeOperation)
    454481{
    455     auto bodyPath = bodyPathForKey(writeOperation.record.key);
     482    auto blobPath = blobPathForKey(writeOperation.record.key);
    456483
    457484    // Store the body.
    458     auto blob = m_blobStorage.add(bodyPath, writeOperation.record.body);
     485    auto blob = m_blobStorage.add(blobPath, writeOperation.record.body);
    459486    if (blob.data.isNull())
    460487        return { };
     
    463490
    464491    RunLoop::main().dispatch([this, blob, &writeOperation] {
    465         if (m_bodyFilter)
    466             m_bodyFilter->add(writeOperation.record.key.hash());
     492        if (m_blobFilter)
     493            m_blobFilter->add(writeOperation.record.key.hash());
    467494        if (m_synchronizationInProgress)
    468             m_bodyFilterHashesAddedDuringSynchronization.append(writeOperation.record.key.hash());
     495            m_blobFilterHashesAddedDuringSynchronization.append(writeOperation.record.key.hash());
    469496
    470497        if (writeOperation.mappedBodyHandler)
     
    524551    serialBackgroundIOQueue().dispatch([this, key] {
    525552        WebCore::deleteFile(recordPathForKey(key));
    526         m_blobStorage.remove(bodyPathForKey(key));
     553        m_blobStorage.remove(blobPathForKey(key));
    527554    });
    528555}
     
    547574    m_readOperationTimeoutTimer.startOneShot(readTimeout);
    548575
    549     bool shouldGetBodyBlob = !m_bodyFilter || m_bodyFilter->mayContain(readOperation.key.hash());
     576    bool shouldGetBodyBlob = mayContainBlob(readOperation.key);
    550577
    551578    ioQueue().dispatch([this, &readOperation, shouldGetBodyBlob] {
     
    564591
    565592        if (shouldGetBodyBlob) {
    566             // Read the body blob in parallel with the record read.
    567             auto bodyPath = bodyPathForKey(readOperation.key);
    568             readOperation.resultBodyBlob = m_blobStorage.get(bodyPath);
     593            // Read the blob in parallel with the record read.
     594            auto blobPath = blobPathForKey(readOperation.key);
     595            readOperation.resultBodyBlob = m_blobStorage.get(blobPath);
    569596            finishReadOperation(readOperation);
    570597        }
     
    575602{
    576603    ASSERT(readOperation.activeCount);
    577     // Record and body blob reads must finish.
     604    // Record and blob reads must finish.
    578605    if (--readOperation.activeCount)
    579606        return;
     
    682709
    683710    backgroundIOQueue().dispatch([this, &writeOperation] {
    684         auto partitionPath = partitionPathForKey(writeOperation.record.key);
     711        auto recordDirectorPath = recordDirectoryPathForKey(writeOperation.record.key);
    685712        auto recordPath = recordPathForKey(writeOperation.record.key);
    686713
    687         WebCore::makeAllDirectories(partitionPath);
     714        WebCore::makeAllDirectories(recordDirectorPath);
    688715
    689716        ++writeOperation.activeCount;
    690717
    691718        bool shouldStoreAsBlob = shouldStoreBodyAsBlob(writeOperation.record.body);
    692         auto bodyBlob = shouldStoreAsBlob ? storeBodyAsBlob(writeOperation) : Nullopt;
    693 
    694         auto recordData = encodeRecord(writeOperation.record, bodyBlob);
     719        auto blob = shouldStoreAsBlob ? storeBodyAsBlob(writeOperation) : Nullopt;
     720
     721        auto recordData = encodeRecord(writeOperation.record, blob);
    695722
    696723        auto channel = IOChannel::open(recordPath, IOChannel::Type::Create);
     
    771798}
    772799
    773 void Storage::traverse(TraverseFlags flags, TraverseHandler&& traverseHandler)
     800void Storage::traverse(const String& type, TraverseFlags flags, TraverseHandler&& traverseHandler)
    774801{
    775802    ASSERT(RunLoop::isMain());
     
    777804    // Avoid non-thread safe std::function copies.
    778805
    779     auto traverseOperationPtr = std::make_unique<TraverseOperation>(flags, WTF::move(traverseHandler));
     806    auto traverseOperationPtr = std::make_unique<TraverseOperation>(type, flags, WTF::move(traverseHandler));
    780807    auto& traverseOperation = *traverseOperationPtr;
    781808    m_activeTraverseOperations.add(WTF::move(traverseOperationPtr));
    782809
    783810    ioQueue().dispatch([this, &traverseOperation] {
    784         traverseRecordsFiles(recordsPath(), [this, &traverseOperation](const String& fileName, const String& partitionPath) {
    785             if (fileName.length() != Key::hashStringLength())
    786                 return;
    787             auto recordPath = WebCore::pathByAppendingComponent(partitionPath, fileName);
     811        traverseRecordsFiles(recordsPath(), traverseOperation.type, [this, &traverseOperation](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
     812            ASSERT(type == traverseOperation.type);
     813            if (isBlob)
     814                return;
     815
     816            auto recordPath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
    788817
    789818            double worth = -1;
     
    792821            unsigned bodyShareCount = 0;
    793822            if (traverseOperation.flags & TraverseFlag::ShareCount)
    794                 bodyShareCount = m_blobStorage.shareCount(bodyPathForRecordPath(recordPath));
     823                bodyShareCount = m_blobStorage.shareCount(blobPathForRecordPath(recordPath));
    795824
    796825            std::unique_lock<Lock> lock(traverseOperation.activeMutex);
     
    857886}
    858887
    859 void Storage::clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler)
     888void Storage::clear(const String& type, std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler)
    860889{
    861890    ASSERT(RunLoop::isMain());
     
    864893    if (m_recordFilter)
    865894        m_recordFilter->clear();
    866     if (m_bodyFilter)
    867         m_bodyFilter->clear();
     895    if (m_blobFilter)
     896        m_blobFilter->clear();
    868897    m_approximateRecordsSize = 0;
    869898
    870899    // Avoid non-thread safe std::function copies.
    871900    auto* completionHandlerPtr = completionHandler ? new std::function<void ()>(WTF::move(completionHandler)) : nullptr;
    872 
    873     ioQueue().dispatch([this, modifiedSinceTime, completionHandlerPtr] {
     901    StringCapture typeCapture(type);
     902    ioQueue().dispatch([this, modifiedSinceTime, completionHandlerPtr, typeCapture] {
    874903        auto recordsPath = this->recordsPath();
    875         traverseRecordsFiles(recordsPath, [modifiedSinceTime](const String& fileName, const String& partitionPath) {
    876             auto filePath = WebCore::pathByAppendingComponent(partitionPath, fileName);
     904        traverseRecordsFiles(recordsPath, typeCapture.string(), [modifiedSinceTime](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
     905            auto filePath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
    877906            if (modifiedSinceTime > std::chrono::system_clock::time_point::min()) {
    878907                auto times = fileTimes(filePath);
     
    885914        deleteEmptyRecordsDirectories(recordsPath);
    886915
    887         // This cleans unreferences blobs.
     916        // This cleans unreferenced blobs.
    888917        m_blobStorage.synchronize();
    889918
     
    951980    backgroundIOQueue().dispatch([this] {
    952981        auto recordsPath = this->recordsPath();
    953         traverseRecordsFiles(recordsPath, [this](const String& fileName, const String& partitionPath) {
    954             if (fileName.length() != Key::hashStringLength())
    955                 return;
    956             auto recordPath = WebCore::pathByAppendingComponent(partitionPath, fileName);
    957             auto bodyPath = bodyPathForRecordPath(recordPath);
     982        String anyType;
     983        traverseRecordsFiles(recordsPath, anyType, [this](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
     984            if (isBlob)
     985                return;
     986
     987            auto recordPath = WebCore::pathByAppendingComponent(recordDirectoryPath, fileName);
     988            auto blobPath = blobPathForRecordPath(recordPath);
    958989
    959990            auto times = fileTimes(recordPath);
    960             unsigned bodyShareCount = m_blobStorage.shareCount(bodyPath);
     991            unsigned bodyShareCount = m_blobStorage.shareCount(blobPath);
    961992            auto probability = deletionProbability(times, bodyShareCount);
    962993
     
    967998            if (shouldDelete) {
    968999                WebCore::deleteFile(recordPath);
    969                 m_blobStorage.remove(bodyPath);
     1000                m_blobStorage.remove(blobPath);
    9701001            }
    9711002        });
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h

    r191354 r191377  
    6666
    6767    void remove(const Key&);
    68     void clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
     68    void clear(const String& type, std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
    6969
    7070    struct RecordInfo {
     
    8181    typedef std::function<void (const Record*, const RecordInfo&)> TraverseHandler;
    8282    // Null record signals end.
    83     void traverse(TraverseFlags, TraverseHandler&&);
     83    void traverse(const String& type, TraverseFlags, TraverseHandler&&);
    8484
    8585    void setCapacity(size_t);
     
    8787    size_t approximateSize() const;
    8888
    89     static const unsigned version = 4;
     89    static const unsigned version = 5;
    9090
    9191    String basePath() const;
     
    9898    Storage(const String& directoryPath);
    9999
    100     String partitionPathForKey(const Key&) const;
     100    String recordDirectoryPathForKey(const Key&) const;
    101101    String recordPathForKey(const Key&) const;
    102     String bodyPathForKey(const Key&) const;
     102    String blobPathForKey(const Key&) const;
    103103
    104104    void synchronize();
     
    130130
    131131    bool mayContain(const Key&) const;
     132    bool mayContainBlob(const Key&) const;
    132133
    133134    void addToRecordFilter(const Key&);
     
    142143    using ContentsFilter = BloomFilter<18>;
    143144    std::unique_ptr<ContentsFilter> m_recordFilter;
    144     std::unique_ptr<ContentsFilter> m_bodyFilter;
     145    std::unique_ptr<ContentsFilter> m_blobFilter;
    145146
    146147    bool m_synchronizationInProgress { false };
     
    148149
    149150    Vector<Key::HashType> m_recordFilterHashesAddedDuringSynchronization;
    150     Vector<Key::HashType> m_bodyFilterHashesAddedDuringSynchronization;
     151    Vector<Key::HashType> m_blobFilterHashesAddedDuringSynchronization;
    151152
    152153    static const int maximumRetrievePriority = 4;
     
    170171
    171172// FIXME: Remove, used by NetworkCacheStatistics only.
    172 void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>&);
     173void 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)>&);
    173174
    174175}
Note: See TracChangeset for help on using the changeset viewer.