Changeset 231708 in webkit


Ignore:
Timestamp:
May 11, 2018 11:11:21 AM (6 years ago)
Author:
Antti Koivisto
Message:

Network process should not stat() all cache files on startup to find their sizes
https://bugs.webkit.org/show_bug.cgi?id=185542
<rdar://problem/40092953>

Reviewed by Chris Dumez.

This is done to compute how much disk space a cache is using. While the operation happens
in a background priority thread it is still quite a bit of work.

Large bodies are saved in separate blob files so record file sizes are capped. We can avoid work by
estimating their size instead of counting it exactly.

  • NetworkProcess/cache/NetworkCacheStorage.cpp:

(WebKit::NetworkCache::estimateRecordsSize):
(WebKit::NetworkCache::Storage::synchronize):

Use size estimation if blob storage is in use.
Remove the code that would delete empty files. Normal cache shrinking handles this.

(WebKit::NetworkCache::Storage::shouldStoreBodyAsBlob):

Location:
trunk/Source/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r231704 r231708  
     12018-05-11  Antti Koivisto  <antti@apple.com>
     2
     3        Network process should not stat() all cache files on startup to find their sizes
     4        https://bugs.webkit.org/show_bug.cgi?id=185542
     5        <rdar://problem/40092953>
     6
     7        Reviewed by Chris Dumez.
     8
     9        This is done to compute how much disk space a cache is using. While the operation happens
     10        in a background priority thread it is still quite a bit of work.
     11
     12        Large bodies are saved in separate blob files so record file sizes are capped. We can avoid work by
     13        estimating their size instead of counting it exactly.
     14
     15        * NetworkProcess/cache/NetworkCacheStorage.cpp:
     16        (WebKit::NetworkCache::estimateRecordsSize):
     17        (WebKit::NetworkCache::Storage::synchronize):
     18
     19            Use size estimation if blob storage is in use.
     20            Remove the code that would delete empty files. Normal cache shrinking handles this.
     21
     22        (WebKit::NetworkCache::Storage::shouldStoreBodyAsBlob):
     23
    1242018-05-11  Brady Eidson  <beidson@apple.com>
    225
  • trunk/Source/WebKit/NetworkProcess/cache/NetworkCacheStorage.cpp

    r231484 r231708  
    4646static const char blobsDirectoryName[] = "Blobs";
    4747static const char blobSuffix[] = "-blob";
     48constexpr size_t maximumInlineBodySize { 16 * 1024 };
    4849
    4950static double computeRecordWorth(FileTimes);
     
    262263}
    263264
     265static size_t estimateRecordsSize(unsigned recordCount, unsigned blobCount)
     266{
     267    auto inlineBodyCount = recordCount - std::min(blobCount, recordCount);
     268    auto headerSizes = recordCount * 4096;
     269    auto inlineBodySizes = (maximumInlineBodySize / 2) * inlineBodyCount;
     270    return headerSizes + inlineBodySizes;
     271}
     272
    264273void Storage::synchronize()
    265274{
     
    275284        auto recordFilter = std::make_unique<ContentsFilter>();
    276285        auto blobFilter = std::make_unique<ContentsFilter>();
     286
     287        // Most of the disk space usage is in blobs if we are using them. Approximate records file sizes to avoid expensive stat() calls.
     288        bool shouldComputeExactRecordsSize = !m_canUseBlobsForForBodyData;
    277289        size_t recordsSize = 0;
    278         unsigned count = 0;
     290        unsigned recordCount = 0;
     291        unsigned blobCount = 0;
     292
    279293        String anyType;
    280         traverseRecordsFiles(recordsPath(), anyType, [&recordFilter, &blobFilter, &recordsSize, &count](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
     294        traverseRecordsFiles(recordsPath(), anyType, [&](const String& fileName, const String& hashString, const String& type, bool isBlob, const String& recordDirectoryPath) {
    281295            auto filePath = WebCore::FileSystem::pathByAppendingComponent(recordDirectoryPath, fileName);
    282296
     
    286300                return;
    287301            }
    288             long long fileSize = 0;
    289             WebCore::FileSystem::getFileSize(filePath, fileSize);
    290             if (!fileSize) {
    291                 WebCore::FileSystem::deleteFile(filePath);
    292                 return;
    293             }
    294302
    295303            if (isBlob) {
     304                ++blobCount;
    296305                blobFilter->add(hash);
    297306                return;
    298307            }
    299308
     309            ++recordCount;
     310
     311            if (shouldComputeExactRecordsSize) {
     312                long long fileSize = 0;
     313                WebCore::FileSystem::getFileSize(filePath, fileSize);
     314                recordsSize += fileSize;
     315            }
     316
    300317            recordFilter->add(hash);
    301             recordsSize += fileSize;
    302             ++count;
    303         });
     318        });
     319
     320        if (!shouldComputeExactRecordsSize)
     321            recordsSize = estimateRecordsSize(recordCount, blobCount);
    304322
    305323        RunLoop::main().dispatch([this, recordFilter = WTFMove(recordFilter), blobFilter = WTFMove(blobFilter), recordsSize]() mutable {
     
    322340        deleteEmptyRecordsDirectories(recordsPath());
    323341
    324         LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu count=%u", recordsSize, count);
     342        LOG(NetworkCacheStorage, "(NetworkProcess) cache synchronization completed size=%zu recordCount=%u", recordsSize, recordCount);
    325343
    326344        RunLoop::main().dispatch([protectedThis = WTFMove(protectedThis)] { });
     
    757775    if (!m_canUseBlobsForForBodyData)
    758776        return false;
    759     const size_t maximumInlineBodySize { 16 * 1024 };
    760777    return bodyData.size() > maximumInlineBodySize;
    761778}
Note: See TracChangeset for help on using the changeset viewer.