Changeset 181700 in webkit
- Timestamp:
- Mar 18, 2015, 10:40:34 AM (11 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
NetworkProcess/cache/NetworkCacheFileSystemPosix.h (modified) (2 diffs)
-
NetworkProcess/cache/NetworkCacheIOChannel.h (modified) (1 diff)
-
NetworkProcess/cache/NetworkCacheIOChannelCocoa.mm (modified) (2 diffs)
-
NetworkProcess/cache/NetworkCacheStorage.cpp (modified) (5 diffs)
-
NetworkProcess/cache/NetworkCacheStorage.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r181689 r181700 1 2015-03-17 Antti Koivisto <antti@apple.com> 2 3 Prune least valuable cache entries first 4 https://bugs.webkit.org/show_bug.cgi?id=142810 5 rdar://problem/19632130 6 7 Reviewed by Darin Adler. 8 9 When pruning the cache estimate relative value of each entry using formula 10 11 age = current time - creation time 12 accessAge = last access time - creation time 13 value = accessAge / age 14 15 That is, we value entries that have been accessed recently and survived in the cache longest. 16 17 The most valuable entries don't get deleted at all while the deletion probablity ramps up for 18 lower value entries. 19 20 * NetworkProcess/cache/NetworkCacheFileSystemPosix.h: 21 (WebKit::NetworkCache::fileTimes): 22 23 Get the creation time and access time for a file. 24 25 (WebKit::NetworkCache::updateFileAccessTimeIfNeeded): 26 27 Update access time manually if the file system doesn't do it automatically. 28 29 * NetworkProcess/cache/NetworkCacheIOChannel.h: 30 (WebKit::NetworkCache::IOChannel::path): 31 (WebKit::NetworkCache::IOChannel::type): 32 * NetworkProcess/cache/NetworkCacheIOChannelCocoa.mm: 33 (WebKit::NetworkCache::IOChannel::IOChannel): 34 (WebKit::NetworkCache::IOChannel::open): 35 36 Remember the file path and move most of the work to constructor. 37 38 * NetworkProcess/cache/NetworkCacheStorage.cpp: 39 (WebKit::NetworkCache::Storage::Storage): 40 (WebKit::NetworkCache::Storage::remove): 41 (WebKit::NetworkCache::Storage::updateFileAccessTime): 42 (WebKit::NetworkCache::Storage::dispatchReadOperation): 43 (WebKit::NetworkCache::deletionProbability): 44 45 Compute the probability based on entry age and access time. 46 47 (WebKit::NetworkCache::Storage::shrinkIfNeeded): 48 * NetworkProcess/cache/NetworkCacheStorage.h: 49 (WebKit::NetworkCache::Storage::serialBackgroundIOQueue): 50 (WebKit::NetworkCache::Storage::deleteQueue): Deleted. 51 52 More generic name. 53 1 54 2015-03-18 Chris Dumez <cdumez@apple.com> 2 55 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheFileSystemPosix.h
r181140 r181700 32 32 #include <WebCore/FileSystem.h> 33 33 #include <dirent.h> 34 #include <sys/stat.h> 35 #include <sys/time.h> 34 36 #include <wtf/text/CString.h> 35 37 … … 68 70 } 69 71 72 struct FileTimes { 73 std::chrono::system_clock::time_point creation; 74 std::chrono::system_clock::time_point access; 75 }; 76 77 inline FileTimes fileTimes(const String& path) 78 { 79 struct stat fileInfo; 80 if (stat(WebCore::fileSystemRepresentation(path).data(), &fileInfo)) 81 return { }; 82 return { std::chrono::system_clock::from_time_t(fileInfo.st_birthtime), std::chrono::system_clock::from_time_t(fileInfo.st_atime) }; 83 } 84 85 inline void updateFileAccessTimeIfNeeded(const String& path) 86 { 87 auto times = fileTimes(path); 88 if (times.creation != times.access) { 89 // Don't update more than once per hour; 90 if (std::chrono::system_clock::now() - times.access < std::chrono::hours(1)) 91 return; 92 } 93 // This really updates both access time and modification time. 94 utimes(WebCore::fileSystemRepresentation(path).data(), 0); 95 } 96 70 97 } 71 98 } -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannel.h
r181161 r181700 46 46 void write(size_t offset, const Data&, std::function<void (int error)>); 47 47 48 const String& path() const { return m_path; } 49 Type type() const { return m_type; } 50 48 51 int fileDescriptor() const { return m_fileDescriptor; } 49 52 50 53 private: 51 IOChannel( int fd);54 IOChannel(const String& filePath, IOChannel::Type); 52 55 56 String m_path; 57 Type m_type; 58 59 int m_fileDescriptor { 0 }; 53 60 #if PLATFORM(COCOA) 54 61 DispatchPtr<dispatch_io_t> m_dispatchIO; 55 62 #endif 56 int m_fileDescriptor { 0 };57 63 }; 58 64 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelCocoa.mm
r181424 r181700 40 40 namespace NetworkCache { 41 41 42 IOChannel::IOChannel(int fd) 43 : m_fileDescriptor(fd) 44 { 45 m_dispatchIO = adoptDispatch(dispatch_io_create(DISPATCH_IO_RANDOM, fd, dispatch_get_main_queue(), [fd](int) { 46 close(fd); 47 })); 48 ASSERT(m_dispatchIO.get()); 49 // This makes the channel read/write all data before invoking the handlers. 50 dispatch_io_set_low_water(m_dispatchIO.get(), std::numeric_limits<size_t>::max()); 51 } 52 53 Ref<IOChannel> IOChannel::open(const String& filePath, IOChannel::Type type) 42 IOChannel::IOChannel(const String& filePath, Type type) 43 : m_path(filePath) 44 , m_type(type) 54 45 { 55 46 int oflag; 56 47 mode_t mode; 57 48 58 switch ( type) {49 switch (m_type) { 59 50 case Type::Create: 60 51 oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK; … … 72 63 CString path = WebCore::fileSystemRepresentation(filePath); 73 64 int fd = ::open(path.data(), oflag, mode); 65 m_fileDescriptor = fd; 74 66 75 return adoptRef(*new IOChannel(fd)); 67 m_dispatchIO = adoptDispatch(dispatch_io_create(DISPATCH_IO_RANDOM, fd, dispatch_get_main_queue(), [fd](int) { 68 close(fd); 69 })); 70 ASSERT(m_dispatchIO.get()); 71 // This makes the channel read/write all data before invoking the handlers. 72 dispatch_io_set_low_water(m_dispatchIO.get(), std::numeric_limits<size_t>::max()); 73 } 74 75 Ref<IOChannel> IOChannel::open(const String& filePath, IOChannel::Type type) 76 { 77 return adoptRef(*new IOChannel(filePath, type)); 76 78 } 77 79 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.cpp
r181424 r181700 66 66 , m_ioQueue(WorkQueue::create("com.apple.WebKit.Cache.Storage", WorkQueue::Type::Concurrent)) 67 67 , m_backgroundIOQueue(WorkQueue::create("com.apple.WebKit.Cache.Storage.background", WorkQueue::Type::Concurrent, WorkQueue::QOS::Background)) 68 , m_ deleteQueue(WorkQueue::create("com.apple.WebKit.Cache.Storage.delete", WorkQueue::Type::Serial, WorkQueue::QOS::Background))68 , m_serialBackgroundIOQueue(WorkQueue::create("com.apple.WebKit.Cache.Storage.serialBackground", WorkQueue::Type::Serial, WorkQueue::QOS::Background)) 69 69 { 70 70 deleteOldVersions(); … … 283 283 284 284 StringCapture filePathCapture(filePathForKey(key, m_directoryPath)); 285 deleteQueue().dispatch([this, filePathCapture] {285 serialBackgroundIOQueue().dispatch([this, filePathCapture] { 286 286 WebCore::deleteFile(filePathCapture.string()); 287 }); 288 } 289 290 void Storage::updateFileAccessTime(IOChannel& channel) 291 { 292 StringCapture filePathCapture(channel.path()); 293 serialBackgroundIOQueue().dispatch([filePathCapture] { 294 updateFileAccessTimeIfNeeded(filePathCapture.string()); 287 295 }); 288 296 } … … 295 303 StringCapture cachePathCapture(m_directoryPath); 296 304 ioQueue().dispatch([this, &read, cachePathCapture] { 297 auto channel = openFileForKey(read.key, IOChannel::Type::Read, cachePathCapture.string()); 298 int fd = channel->fileDescriptor(); 299 channel->read(0, std::numeric_limits<size_t>::max(), [this, &read, fd](Data& fileData, int error) { 305 RefPtr<IOChannel> channel = openFileForKey(read.key, IOChannel::Type::Read, cachePathCapture.string()); 306 channel->read(0, std::numeric_limits<size_t>::max(), [this, channel, &read](Data& fileData, int error) { 300 307 if (error) { 301 308 remove(read.key); 302 309 read.completionHandler(nullptr); 303 310 } else { 304 auto entry = decodeEntry(fileData, fd, read.key);311 auto entry = decodeEntry(fileData, channel->fileDescriptor(), read.key); 305 312 bool success = read.completionHandler(WTF::move(entry)); 306 if (!success) 313 if (success) 314 updateFileAccessTime(*channel); 315 else 307 316 remove(read.key); 308 317 } … … 570 579 } 571 580 581 static double deletionProbability(FileTimes times) 582 { 583 static const double maximumProbability { 0.33 }; 584 585 using namespace std::chrono; 586 auto age = system_clock::now() - times.creation; 587 auto accessAge = times.access - times.creation; 588 589 // For sanity. 590 if (age <= seconds::zero() || accessAge < seconds::zero() || accessAge > age) 591 return maximumProbability; 592 593 // We like old entries that have been accessed recently. 594 auto relativeValue = duration<double>(accessAge) / age; 595 596 // Adjust a bit so the most valuable entries don't get deleted at all. 597 auto effectiveValue = std::min(1.1 * relativeValue, 1.); 598 599 return (1 - effectiveValue) * maximumProbability; 600 } 601 572 602 void Storage::shrinkIfNeeded() 573 603 { 574 604 ASSERT(RunLoop::isMain()); 575 576 static const double deletionProbability { 0.25 };577 605 578 606 if (m_approximateSize <= m_maximumSize) … … 592 620 auto filePath = WebCore::pathByAppendingComponent(partitionPath, fileName); 593 621 594 bool shouldDelete = randomNumber() < deletionProbability; 622 auto times = fileTimes(filePath); 623 auto probability = deletionProbability(times); 624 bool shouldDelete = randomNumber() < probability; 625 626 LOG(NetworkCacheStorage, "Deletion probability=%f shouldDelete=%d", probability, shouldDelete); 627 595 628 if (!shouldDelete) { 596 629 long long fileSize = 0; -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h
r181364 r181700 40 40 namespace WebKit { 41 41 namespace NetworkCache { 42 43 class IOChannel; 42 44 43 45 class Storage { … … 96 98 void dispatchPendingWriteOperations(); 97 99 100 void updateFileAccessTime(IOChannel&); 101 98 102 WorkQueue& ioQueue() { return m_ioQueue.get(); } 99 103 WorkQueue& backgroundIOQueue() { return m_backgroundIOQueue.get(); } 100 WorkQueue& deleteQueue() { return m_deleteQueue.get(); }104 WorkQueue& serialBackgroundIOQueue() { return m_serialBackgroundIOQueue.get(); } 101 105 102 106 const String m_baseDirectoryPath; … … 118 122 Ref<WorkQueue> m_ioQueue; 119 123 Ref<WorkQueue> m_backgroundIOQueue; 120 Ref<WorkQueue> m_ deleteQueue;124 Ref<WorkQueue> m_serialBackgroundIOQueue; 121 125 }; 122 126
Note:
See TracChangeset
for help on using the changeset viewer.