Changeset 179546 in webkit


Ignore:
Timestamp:
Feb 3, 2015 4:41:52 AM (9 years ago)
Author:
Antti Koivisto
Message:

Update cache header after revalidation without rewriting the body data
https://bugs.webkit.org/show_bug.cgi?id=141182

Reviewed by Andreas Kling.

Currently we just rewrite the entire entry after revalidation.

  • NetworkProcess/cache/NetworkCache.cpp:

(WebKit::decodeStorageEntry):

Include the strorage entry to the cache response so we can more easily update it.

(WebKit::NetworkCache::update):

Call the storage update function with the new and the exisiting storage entry.

  • NetworkProcess/cache/NetworkCache.h:
  • NetworkProcess/cache/NetworkCacheStorage.h:
  • NetworkProcess/cache/NetworkCacheStorageCocoa.mm:

(WebKit::openFileForKey):

Added an option for opening a file for writing without creating a new one.
Renamed for clarity.

(WebKit::encodeEntryHeader):

Separate header encoding to a function.

(WebKit::encodeEntry):
(WebKit::NetworkCacheStorage::dispatchRetrieveOperation):
(WebKit::NetworkCacheStorage::store):
(WebKit::NetworkCacheStorage::update):

New update function.
If the page-rounded header size would stay unchanged we can just write the new header over the old one.
In the unlikely event it doesn't we rewrite the whole thing.

(WebKit::createIOChannelForKey): Deleted.

Location:
trunk/Source/WebKit2
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r179541 r179546  
     12015-02-02  Antti Koivisto  <antti@apple.com>
     2
     3        Update cache header after revalidation without rewriting the body data
     4        https://bugs.webkit.org/show_bug.cgi?id=141182
     5
     6        Reviewed by Andreas Kling.
     7
     8        Currently we just rewrite the entire entry after revalidation.
     9
     10        * NetworkProcess/cache/NetworkCache.cpp:
     11        (WebKit::decodeStorageEntry):
     12
     13            Include the strorage entry to the cache response so we can more easily update it.
     14
     15        (WebKit::NetworkCache::update):
     16
     17            Call the storage update function with the new and the exisiting storage entry.
     18
     19        * NetworkProcess/cache/NetworkCache.h:
     20        * NetworkProcess/cache/NetworkCacheStorage.h:
     21        * NetworkProcess/cache/NetworkCacheStorageCocoa.mm:
     22        (WebKit::openFileForKey):
     23
     24            Added an option for opening a file for writing without creating a new one.
     25            Renamed for clarity.
     26
     27        (WebKit::encodeEntryHeader):
     28
     29            Separate header encoding to a function.
     30
     31        (WebKit::encodeEntry):
     32        (WebKit::NetworkCacheStorage::dispatchRetrieveOperation):
     33        (WebKit::NetworkCacheStorage::store):
     34        (WebKit::NetworkCacheStorage::update):
     35
     36            New update function.
     37            If the page-rounded header size would stay unchanged we can just write the new header over the old one.
     38            In the unlikely event it doesn't we rewrite the whole thing.
     39
     40        (WebKit::createIOChannelForKey): Deleted.
     41
    1422015-02-02  Commit Queue  <commit-queue@webkit.org>
    243
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp

    r179529 r179546  
    168168
    169169    auto entry = std::make_unique<NetworkCache::Entry>();
     170    entry->storageEntry = storageEntry;
    170171    entry->needsRevalidation = needsRevalidation;
    171172
     
    317318    WebCore::updateResponseHeadersAfterRevalidation(response, validatingResponse);
    318319
    319     // FIXME: This rewrites the entire resource instead of just the header.
    320320    auto key = makeCacheKey(originalRequest);
    321     auto storageEntry = encodeStorageEntry(originalRequest, response, entry.buffer);
    322 
    323     m_storage->store(key, storageEntry, [](bool success) {
     321    auto updateEntry = encodeStorageEntry(originalRequest, response, entry.buffer);
     322
     323    m_storage->update(key, updateEntry, entry.storageEntry, [](bool success) {
    324324        LOG(NetworkCache, "(NetworkProcess) updated, success=%d", success);
    325325    });
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h

    r179529 r179546  
    5454
    5555    struct Entry {
     56        NetworkCacheStorage::Entry storageEntry;
    5657        WebCore::ResourceResponse response;
    5758        RefPtr<WebCore::SharedBuffer> buffer;
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h

    r179446 r179546  
    135135    void retrieve(const NetworkCacheKey&, unsigned priority, std::function<bool (std::unique_ptr<Entry>)>);
    136136    void store(const NetworkCacheKey&, const Entry&, std::function<void (bool success)>);
     137    void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)>);
    137138
    138139    void setMaximumSize(size_t);
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm

    r179446 r179546  
    162162}
    163163
    164 enum class IOChannelType { Read, Write };
    165 static DispatchPtr<dispatch_io_t> createIOChannelForKey(const NetworkCacheKey& key, IOChannelType type, const String& cachePath, int& fd)
     164enum class FileOpenType { Read, Write, Create };
     165static DispatchPtr<dispatch_io_t> openFileForKey(const NetworkCacheKey& key, FileOpenType type, const String& cachePath, int& fd)
    166166{
    167167    int oflag;
     
    169169
    170170    switch (type) {
    171     case IOChannelType::Write:
     171    case FileOpenType::Create:
    172172        oflag = O_WRONLY | O_CREAT | O_TRUNC | O_NONBLOCK;
    173173        mode = S_IRUSR | S_IWUSR;
    174174        WebCore::makeAllDirectories(directoryPathForKey(key, cachePath));
    175175        break;
    176     case IOChannelType::Read:
     176    case FileOpenType::Write:
     177        oflag = O_WRONLY | O_NONBLOCK;
     178        mode = S_IRUSR | S_IWUSR;
     179        break;
     180    case FileOpenType::Read:
    177181        oflag = O_RDONLY | O_NONBLOCK;
    178182        mode = 0;
     
    312316}
    313317
    314 static DispatchPtr<dispatch_data_t> encodeEntry(const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry)
     318static DispatchPtr<dispatch_data_t> encodeEntryHeader(const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry)
    315319{
    316320    EntryMetaData metaData(key);
     
    330334    Vector<uint8_t, 4096> filler(dataOffset - headerSize, 0);
    331335    auto alignmentData = adoptDispatch(dispatch_data_create(filler.data(), filler.size(), nullptr, DISPATCH_DATA_DESTRUCTOR_DEFAULT));
    332 
    333     auto headerWithAlignmentData = adoptDispatch(dispatch_data_create_concat(headerData.get(), alignmentData.get()));
    334 
    335     return adoptDispatch(dispatch_data_create_concat(headerWithAlignmentData.get(), entry.body.dispatchData()));
     336    return adoptDispatch(dispatch_data_create_concat(headerData.get(), alignmentData.get()));
     337}
     338
     339static DispatchPtr<dispatch_data_t> encodeEntry(const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry)
     340{
     341    auto encodedHeader = encodeEntryHeader(key, entry);
     342    return adoptDispatch(dispatch_data_create_concat(encodedHeader.get(), entry.body.dispatchData()));
    336343}
    337344
     
    361368    dispatch_async(m_ioQueue.get(), [this, retrieve, cachePathCapture] {
    362369        int fd;
    363         auto channel = createIOChannelForKey(retrieve.key, IOChannelType::Read, cachePathCapture.string(), fd);
     370        auto channel = openFileForKey(retrieve.key, FileOpenType::Read, cachePathCapture.string(), fd);
    364371
    365372        bool didCallCompletionHandler = false;
     
    429436    dispatch_async(m_backgroundIOQueue.get(), [this, key, entry, cachePathCapture, completionHandler] {
    430437        auto data = encodeEntry(key, entry);
     438
    431439        int fd;
    432         auto channel = createIOChannelForKey(key, IOChannelType::Write, cachePathCapture.string(), fd);
     440        auto channel = openFileForKey(key, FileOpenType::Create, cachePathCapture.string(), fd);
    433441        dispatch_io_write(channel.get(), 0, data.get(), dispatch_get_main_queue(), [this, key, completionHandler](bool done, dispatch_data_t, int error) {
    434442            ASSERT_UNUSED(done, done);
     
    439447                shrinkIfNeeded();
    440448            }
     449            completionHandler(!error);
     450        });
     451    });
     452}
     453
     454void NetworkCacheStorage::update(const NetworkCacheKey& key, const Entry& updateEntry, const Entry& existingEntry, std::function<void (bool success)> completionHandler)
     455{
     456    ASSERT(RunLoop::isMain());
     457
     458    if (!m_keyFilter.mayContain(key.hash())) {
     459        LOG(NetworkCacheStorage, "(NetworkProcess) existing entry not found, storing full entry");
     460        store(key, updateEntry, completionHandler);
     461        return;
     462    }
     463
     464    // Try to update the header of an existing entry.
     465    StringCapture cachePathCapture(m_directoryPath);
     466    dispatch_async(m_backgroundIOQueue.get(), [this, key, updateEntry, existingEntry, cachePathCapture, completionHandler] {
     467        auto headerData = encodeEntryHeader(key, updateEntry);
     468        auto existingHeaderData = encodeEntryHeader(key, existingEntry);
     469
     470        bool pageRoundedHeaderSizeChanged = dispatch_data_get_size(headerData.get()) != dispatch_data_get_size(existingHeaderData.get());
     471        if (pageRoundedHeaderSizeChanged) {
     472            LOG(NetworkCacheStorage, "(NetworkProcess) page-rounded header size changed, storing full entry");
     473            dispatch_async(dispatch_get_main_queue(), [this, key, updateEntry, completionHandler] {
     474                store(key, updateEntry, completionHandler);
     475            });
     476            return;
     477        }
     478
     479        int fd;
     480        auto channel = openFileForKey(key, FileOpenType::Write, cachePathCapture.string(), fd);
     481        dispatch_io_write(channel.get(), 0, headerData.get(), dispatch_get_main_queue(), [this, key, completionHandler](bool done, dispatch_data_t, int error) {
     482            ASSERT_UNUSED(done, done);
     483            LOG(NetworkCacheStorage, "(NetworkProcess) update complete error=%d", error);
     484
     485            if (error)
     486                removeEntry(key);
     487
    441488            completionHandler(!error);
    442489        });
Note: See TracChangeset for help on using the changeset viewer.