Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: d59388dcdfbd0c749ace56cf3b21969f03ecda6b
      
https://github.com/WebKit/WebKit/commit/d59388dcdfbd0c749ace56cf3b21969f03ecda6b
  Author: Ahmad Saleem <[email protected]>
  Date:   2026-08-26 (Wed, 26 Aug 2026)

  Changed paths:
    M 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any-expected.txt
    M 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.js
    M 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt
    M 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt
    M 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.worker-expected.txt
    M Source/WebCore/Modules/cache/DOMCache.cpp

  Log Message:
  -----------
  Avoid quadratic duplicate detection in Cache.addAll()
https://bugs.webkit.org/show_bug.cgi?id=322387
rdar://185671311

Reviewed by Youenn Fablet.

Cache.addAll() rejects with InvalidStateError when two of its requests match
each other. It checked this by walking every already-staged record as each
fetch completed, which is O(n^2): 500 URLs means ~125000 comparisons. Each
comparison was also far more expensive than it looks, because
FetchRequest::resourceRequest() is not an accessor -- it copies the whole
ResourceRequest, sets the header fields, and calls bodyAsFormData() when a body
is present -- and it was invoked inside the loop.

Give FetchTasksHandler a map from URL to the positions of the records staged
under it and let it answer the query via hasMatchingRecord(). The key is the
fragment-stripped URL, which is exactly the equality queryCacheMatch() applies
here: options is default-constructed, so ignoreSearch is false and matchURLs()
reduces to equalIgnoringFragmentIdentifier(). queryCacheMatch() still runs
against every record in the bucket, so Vary continues to distinguish records
sharing a URL. resourceRequest() is now called once per completed fetch.
Positions rather than pointers, because m_records reallocates as it grows.

This mirrors CacheStorageCache in the network process, which already keys its
records map with computeKeyURL(). That map also strips the query, because it
serves ignoreSearch lookups; addAll() does not, so keying on the query here is
correct and more selective.

Added a WPT subtest covering two entries that differ only by fragment, which
must be rejected as duplicates. This is the case the new URL key depends on,
and nothing covered it before.

* 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any-expected.txt:
* 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.js:
(cache_test.async cache):
* 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.serviceworker-expected.txt:
* 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.sharedworker-expected.txt:
* 
LayoutTests/imported/w3c/web-platform-tests/service-workers/cache-storage/cache-add.https.any.worker-expected.txt:
* Source/WebCore/Modules/cache/DOMCache.cpp:
(WebCore::FetchTasksHandler::hasMatchingRecord const):
(WebCore::FetchTasksHandler::addRecord):
(WebCore::DOMCache::addAll):
(WebCore::FetchTasksHandler::records const): Deleted.

Canonical link: https://commits.webkit.org/319869@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to