1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 06:14:58 +00:00

LibWebView: Reduce overhead of updating a cookie's last access time

Getting a document's cookie value currently involves:

1. Doing a large SELECT statement and filtering the results to match
   the document and some query parameters based on the cookie RFC.
2. For every cookie selected this way, doing an UPDATE to set its last
   access time.
3. For every UPDATE, do a DELETE to remove all expired cookies.

There's no need to perform cookie expiration for every UPDATE. Instead,
we can do the expiration once after all the UPDATEs are complete.

This reduces time spent waiting for cookies on https://twinings.co.uk
from ~1.9s to ~1.3s on my machine.
This commit is contained in:
Timothy Flynn 2024-02-26 10:28:28 -05:00 committed by Andreas Kling
parent a346f14fb4
commit f1d6693990
2 changed files with 26 additions and 1 deletions

View file

@ -55,6 +55,10 @@ ErrorOr<CookieJar> CookieJar::create(Database& database)
persistent=?
WHERE ((name = ?) AND (domain = ?) AND (path = ?));)#"sv));
statements.update_cookie_last_access_time = TRY(database.prepare_statement(R"#(
UPDATE Cookies SET last_access_time=?
WHERE ((name = ?) AND (domain = ?) AND (path = ?));)#"sv));
statements.insert_cookie = TRY(database.prepare_statement("INSERT INTO Cookies VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"sv));
statements.expire_cookie = TRY(database.prepare_statement("DELETE FROM Cookies WHERE (expiry_time < ?);"sv));
statements.select_cookie = TRY(database.prepare_statement("SELECT * FROM Cookies WHERE ((name = ?) AND (domain = ?) AND (path = ?));"sv));
@ -447,9 +451,10 @@ Vector<Web::Cookie::Cookie> CookieJar::get_matching_cookies(const URL& url, Stri
for (auto& cookie : cookie_list) {
cookie.last_access_time = now;
update_cookie_in_database(cookie);
update_cookie_last_access_time_in_database(cookie);
}
purge_expired_cookies();
return cookie_list;
}
@ -567,6 +572,24 @@ void CookieJar::update_cookie_in_database(Web::Cookie::Cookie const& cookie)
});
}
void CookieJar::update_cookie_last_access_time_in_database(Web::Cookie::Cookie const& cookie)
{
m_storage.visit(
[&](PersistedStorage& storage) {
storage.database.execute_statement(
storage.statements.update_cookie_last_access_time,
{}, {}, {},
cookie.last_access_time,
cookie.name,
cookie.domain,
cookie.path);
},
[&](TransientStorage& storage) {
CookieStorageKey key { cookie.name, cookie.domain, cookie.path };
storage.set(key, cookie);
});
}
struct WrappedCookie : public RefCounted<WrappedCookie> {
explicit WrappedCookie(Web::Cookie::Cookie cookie_)
: RefCounted()

View file

@ -33,6 +33,7 @@ class CookieJar {
SQL::StatementID create_table { 0 };
SQL::StatementID insert_cookie { 0 };
SQL::StatementID update_cookie { 0 };
SQL::StatementID update_cookie_last_access_time { 0 };
SQL::StatementID expire_cookie { 0 };
SQL::StatementID select_cookie { 0 };
SQL::StatementID select_all_cookies { 0 };
@ -76,6 +77,7 @@ private:
void insert_cookie_into_database(Web::Cookie::Cookie const& cookie);
void update_cookie_in_database(Web::Cookie::Cookie const& cookie);
void update_cookie_last_access_time_in_database(Web::Cookie::Cookie const& cookie);
using OnCookieFound = Function<void(Web::Cookie::Cookie&, Web::Cookie::Cookie)>;
using OnCookieNotFound = Function<void(Web::Cookie::Cookie)>;