Skip to content

Commit

Permalink
LibWebView: Reduce overhead of updating a cookie's last access time
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
trflynn89 authored and awesomekling committed Feb 26, 2024
1 parent a346f14 commit f1d6693
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
25 changes: 24 additions & 1 deletion Userland/Libraries/LibWebView/CookieJar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions Userland/Libraries/LibWebView/CookieJar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -76,6 +77,7 @@ class CookieJar {

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)>;
Expand Down

0 comments on commit f1d6693

Please sign in to comment.