Changeset 179547 in webkit
- Timestamp:
- Feb 3, 2015, 6:17:12 AM (10 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r179546 r179547 1 2015-02-03 Antti Koivisto <antti@apple.com> 2 3 Memory cache for resources pending disk write 4 https://bugs.webkit.org/show_bug.cgi?id=141159 5 6 Reviewed by Andreas Kling. 7 8 If a resource was requested from the disk cache before it has been written we ended up 9 loading it again. Add a short lived memory cache to avoid this. 10 11 * NetworkProcess/cache/NetworkCache.cpp: 12 (WebKit::decodeStorageEntry): 13 * NetworkProcess/cache/NetworkCacheStorage.h: 14 (WebKit::NetworkCacheStorage::Data::isMap): 15 16 Add a way to know whether a Data is backed by map or not. SharedMemory does not work correctly 17 if it is not a map. 18 19 * NetworkProcess/cache/NetworkCacheStorageCocoa.mm: 20 (WebKit::NetworkCacheStorage::Data::Data): 21 (WebKit::NetworkCacheStorage::initialize): 22 23 Also do some renaming. 24 25 (WebKit::decodeEntry): 26 (WebKit::NetworkCacheStorage::removeEntry): 27 (WebKit::NetworkCacheStorage::retrieve): 28 (WebKit::NetworkCacheStorage::store): 29 (WebKit::NetworkCacheStorage::clear): 30 (WebKit::NetworkCacheStorage::shrinkIfNeeded): 31 1 32 2015-02-02 Antti Koivisto <antti@apple.com> 2 33 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
r179546 r179547 175 175 176 176 #if ENABLE(SHAREABLE_RESOURCE) 177 RefPtr<SharedMemory> sharedMemory = storageEntry.body. size() ? SharedMemory::createFromVMBuffer(const_cast<uint8_t*>(storageEntry.body.data()), storageEntry.body.size()) : nullptr;177 RefPtr<SharedMemory> sharedMemory = storageEntry.body.isMap() ? SharedMemory::createFromVMBuffer(const_cast<uint8_t*>(storageEntry.body.data()), storageEntry.body.size()) : nullptr; 178 178 RefPtr<ShareableResource> shareableResource = sharedMemory ? ShareableResource::create(sharedMemory.release(), 0, storageEntry.body.size()) : nullptr; 179 179 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h
r179546 r179547 106 106 class Data { 107 107 public: 108 Data() ;108 Data() { } 109 109 Data(const uint8_t*, size_t); 110 111 enum class Backing { Buffer, Map }; 110 112 #if PLATFORM(COCOA) 111 explicit Data(DispatchPtr<dispatch_data_t> );113 explicit Data(DispatchPtr<dispatch_data_t>, Backing = Backing::Buffer); 112 114 #endif 113 115 bool isNull() const; … … 115 117 const uint8_t* data() const; 116 118 size_t size() const { return m_size; } 119 bool isMap() const { return m_isMap; } 117 120 118 121 #if PLATFORM(COCOA) … … 123 126 mutable DispatchPtr<dispatch_data_t> m_dispatchData; 124 127 #endif 125 mutable const uint8_t* m_data; 126 size_t m_size; 128 mutable const uint8_t* m_data { nullptr }; 129 size_t m_size { 0 }; 130 bool m_isMap { false }; 127 131 }; 128 132 … … 161 165 size_t m_maximumSize { std::numeric_limits<size_t>::max() }; 162 166 163 BloomFilter<20> m_ keyFilter;167 BloomFilter<20> m_contentsFilter; 164 168 std::atomic<size_t> m_approximateEntryCount { 0 }; 165 169 std::atomic<bool> m_shrinkInProgress { false }; … … 167 171 Vector<Deque<RetrieveOperation>> m_pendingRetrieveOperationsByPriority; 168 172 unsigned m_activeRetrieveOperationCount { 0 }; 173 174 typedef std::pair<NetworkCacheKey, Entry> KeyEntryPair; 175 HashMap<NetworkCacheKey::HashType, std::shared_ptr<KeyEntryPair>, AlreadyHashed> m_writeCache; 169 176 170 177 #if PLATFORM(COCOA) -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm
r179546 r179547 74 74 } 75 75 76 NetworkCacheStorage::Data::Data()77 : m_data(nullptr)78 , m_size(0)79 {80 }81 82 76 NetworkCacheStorage::Data::Data(const uint8_t* data, size_t size) 83 77 : m_dispatchData(adoptDispatch(dispatch_data_create(data, size, nullptr, DISPATCH_DATA_DESTRUCTOR_DEFAULT))) 84 , m_data(nullptr)85 78 , m_size(size) 86 79 { 87 80 } 88 81 89 NetworkCacheStorage::Data::Data(DispatchPtr<dispatch_data_t> dispatchData )82 NetworkCacheStorage::Data::Data(DispatchPtr<dispatch_data_t> dispatchData, Backing backing) 90 83 { 91 84 const void* data; 92 85 m_dispatchData = adoptDispatch(dispatch_data_create_map(dispatchData.get(), &data, &m_size)); 93 86 m_data = static_cast<const uint8_t*>(data); 87 m_isMap = m_size && backing == Backing::Map; 94 88 } 95 89 … … 136 130 137 131 StringCapture cachePathCapture(m_directoryPath); 138 auto& keyFilter = m_keyFilter;132 auto& diskContentsFilter = m_contentsFilter; 139 133 auto& entryCount = m_approximateEntryCount; 140 134 141 dispatch_async(m_backgroundIOQueue.get(), [cachePathCapture, & keyFilter, &entryCount] {135 dispatch_async(m_backgroundIOQueue.get(), [cachePathCapture, &diskContentsFilter, &entryCount] { 142 136 String cachePath = cachePathCapture.string(); 143 traverseCacheFiles(cachePath, [& keyFilter, &entryCount](const String& fileName, const String&) {137 traverseCacheFiles(cachePath, [&diskContentsFilter, &entryCount](const String& fileName, const String&) { 144 138 NetworkCacheKey::HashType hash; 145 139 if (!NetworkCacheKey::stringToHash(fileName, hash)) 146 140 return; 147 keyFilter.add(hash);141 diskContentsFilter.add(hash); 148 142 ++entryCount; 149 143 }); … … 294 288 return std::make_unique<NetworkCacheStorage::Entry>(NetworkCacheStorage::Entry { 295 289 metaData.timeStamp, 296 NetworkCacheStorage::Data (headerData),297 NetworkCacheStorage::Data (bodyData)290 NetworkCacheStorage::Data { headerData }, 291 NetworkCacheStorage::Data { bodyData, NetworkCacheStorage::Data::Backing::Map } 298 292 }); 299 293 } … … 347 341 ASSERT(RunLoop::isMain()); 348 342 349 if (m_ keyFilter.mayContain(key.hash()))350 m_ keyFilter.remove(key.hash());343 if (m_contentsFilter.mayContain(key.hash())) 344 m_contentsFilter.remove(key.hash()); 351 345 352 346 StringCapture filePathCapture(filePathForKey(key, m_directoryPath)); … … 417 411 ASSERT(RunLoop::isMain()); 418 412 419 if (!m_ keyFilter.mayContain(key.hash())) {413 if (!m_contentsFilter.mayContain(key.hash())) { 420 414 completionHandler(nullptr); 421 415 return; 416 } 417 418 // Write cache is a temporary memory cache used to respond to requests while a write is pending. 419 if (auto keyEntryPair = m_writeCache.get(key.hash())) { 420 if (keyEntryPair->first == key) { 421 LOG(NetworkCacheStorage, "(NetworkProcess) found from the write cache"); 422 dispatch_async(dispatch_get_main_queue(), [keyEntryPair, completionHandler] { 423 completionHandler(std::make_unique<Entry>(keyEntryPair->second)); 424 }); 425 return; 426 } 422 427 } 423 428 … … 432 437 { 433 438 ASSERT(RunLoop::isMain()); 439 440 m_contentsFilter.add(key.hash()); 441 ++m_approximateEntryCount; 442 443 m_writeCache.set(key.hash(), std::make_shared<KeyEntryPair>(key, entry)); 434 444 435 445 StringCapture cachePathCapture(m_directoryPath); … … 442 452 ASSERT_UNUSED(done, done); 443 453 LOG(NetworkCacheStorage, "(NetworkProcess) write complete error=%d", error); 444 if (!error) { 445 m_keyFilter.add(key.hash()); 446 ++m_approximateEntryCount; 447 shrinkIfNeeded(); 454 if (error) { 455 if (m_contentsFilter.mayContain(key.hash())) 456 m_contentsFilter.remove(key.hash()); 457 if (m_approximateEntryCount) 458 --m_approximateEntryCount; 448 459 } 460 m_writeCache.remove(key.hash()); 461 449 462 completionHandler(!error); 450 463 }); 451 464 }); 465 466 shrinkIfNeeded(); 452 467 } 453 468 … … 456 471 ASSERT(RunLoop::isMain()); 457 472 458 if (!m_ keyFilter.mayContain(key.hash())) {473 if (!m_contentsFilter.mayContain(key.hash())) { 459 474 LOG(NetworkCacheStorage, "(NetworkProcess) existing entry not found, storing full entry"); 460 475 store(key, updateEntry, completionHandler); 461 476 return; 462 477 } 478 479 m_writeCache.set(key.hash(), std::make_shared<KeyEntryPair>(key, updateEntry)); 463 480 464 481 // Try to update the header of an existing entry. … … 485 502 if (error) 486 503 removeEntry(key); 504 m_writeCache.remove(key.hash()); 487 505 488 506 completionHandler(!error); … … 504 522 LOG(NetworkCacheStorage, "(NetworkProcess) clearing cache"); 505 523 506 m_keyFilter.clear(); 524 m_writeCache.clear(); 525 m_contentsFilter.clear(); 507 526 m_approximateEntryCount = 0; 508 527 … … 556 575 return; 557 576 dispatch_async(dispatch_get_main_queue(), [this, hash] { 558 if (m_ keyFilter.mayContain(hash))559 m_ keyFilter.remove(hash);577 if (m_contentsFilter.mayContain(hash)) 578 m_contentsFilter.remove(hash); 560 579 }); 561 580 });
Note:
See TracChangeset
for help on using the changeset viewer.