<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[278916] trunk/Source/WebKit</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/278916">278916</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2021-06-15 17:56:03 -0700 (Tue, 15 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Use more SQL transactions in ResourceLoadStatisticsDatabaseStore
https://bugs.webkit.org/show_bug.cgi?id=227034

Reviewed by Kate Cheney.

Use more SQL transactions in ResourceLoadStatisticsDatabaseStore, for performance.

I updated the code so that we start a SQL transaction whenever we do more than one
consecutive "write" statement.

* NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
(WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable):
(WebKit::ResourceLoadStatisticsDatabaseStore::addMissingTablesIfNecessary):
(WebKit::ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore):
(WebKit::ResourceLoadStatisticsDatabaseStore::mergeStatistics):
(WebKit::ResourceLoadStatisticsDatabaseStore::reclassifyResources):
(WebKit::ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains):
(WebKit::ResourceLoadStatisticsDatabaseStore::insertExpiredStatisticForTesting):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp</a></li>
<li><a href="#trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh">trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (278915 => 278916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-06-16 00:46:26 UTC (rev 278915)
+++ trunk/Source/WebKit/ChangeLog       2021-06-16 00:56:03 UTC (rev 278916)
</span><span class="lines">@@ -1,5 +1,26 @@
</span><span class="cx"> 2021-06-15  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><ins>+        Use more SQL transactions in ResourceLoadStatisticsDatabaseStore
+        https://bugs.webkit.org/show_bug.cgi?id=227034
+
+        Reviewed by Kate Cheney.
+
+        Use more SQL transactions in ResourceLoadStatisticsDatabaseStore, for performance.
+
+        I updated the code so that we start a SQL transaction whenever we do more than one
+        consecutive "write" statement.
+
+        * NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp:
+        (WebKit::ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::addMissingTablesIfNecessary):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::mergeStatistics):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::reclassifyResources):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains):
+        (WebKit::ResourceLoadStatisticsDatabaseStore::insertExpiredStatisticForTesting):
+
+2021-06-15  Chris Dumez  <cdumez@apple.com>
+
</ins><span class="cx">         Reloading the view should be able to recover if the GPUProcess or NetworkProcess are hung
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=227051
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp (278915 => 278916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp    2021-06-16 00:46:26 UTC (rev 278915)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.cpp       2021-06-16 00:56:03 UTC (rev 278916)
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx"> #include <wtf/DateMath.h>
</span><span class="cx"> #include <wtf/MathExtras.h>
</span><span class="cx"> #include <wtf/RobinHoodHashMap.h>
</span><ins>+#include <wtf/Scope.h>
</ins><span class="cx"> #include <wtf/StdSet.h>
</span><span class="cx"> #include <wtf/text/StringBuilder.h>
</span><span class="cx"> 
</span><span class="lines">@@ -627,10 +628,14 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(existingColumns.size() <= expectedColumns.size());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
</ins><span class="cx">     for (auto& column : expectedColumns) {
</span><span class="cx">         if (existingColumns.contains(column))
</span><span class="cx">             continue;
</span><span class="cx">         
</span><ins>+        if (!transaction.inProgress())
+            transaction.begin();
+
</ins><span class="cx">         auto statement = m_database.prepareStatementSlow(makeString("ALTER TABLE ", tableName, " ADD COLUMN ", column));
</span><span class="cx">         if (!statement) {
</span><span class="cx">             RELEASE_LOG_ERROR(Network, "%p - ResourceLoadStatisticsDatabaseStore::addMissingColumnsToTable Unable to prepare statement to add missing columns to table, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="lines">@@ -644,6 +649,7 @@
</span><span class="cx">         }
</span><span class="cx">         statement->reset();
</span><span class="cx">     }
</span><ins>+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::addMissingColumnsIfNecessary()
</span><span class="lines">@@ -700,6 +706,8 @@
</span><span class="cx">     if (!missingTables)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
</ins><span class="cx">     for (auto& table : *missingTables) {
</span><span class="cx">         auto createTableQuery = expectedTableAndIndexQueries().get(table).first;
</span><span class="cx">         if (!m_database.executeCommandSlow(createTableQuery))
</span><span class="lines">@@ -711,6 +719,7 @@
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::openAndUpdateSchemaIfNecessary()
</span><span class="lines">@@ -1027,8 +1036,10 @@
</span><span class="cx">     return scopedStatement->columnInt(0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String ResourceLoadStatisticsDatabaseStore::ensureAndMakeDomainList(const HashSet<RegistrableDomain>& domainList)
</del><ins>+String ResourceLoadStatisticsDatabaseStore::ensureAndMakeDomainList(const SQLiteTransaction&, const HashSet<RegistrableDomain>& domainList)
</ins><span class="cx"> {
</span><ins>+    ASSERT(m_database.transactionInProgress());
+
</ins><span class="cx">     StringBuilder builder;
</span><span class="cx">     for (auto& topFrameResource : domainList) {
</span><span class="cx">         // Insert query will fail if top frame domain is not already in the database
</span><span class="lines">@@ -1038,9 +1049,9 @@
</span><span class="cx">     return builder.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::insertDomainRelationshipList(const String& statement, const HashSet<RegistrableDomain>& domainList, unsigned domainID)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::insertDomainRelationshipList(const SQLiteTransaction& transaction, const String& statement, const HashSet<RegistrableDomain>& domainList, unsigned domainID)
</ins><span class="cx"> {
</span><del>-    auto insertRelationshipStatement = m_database.prepareStatementSlow(makeString(statement, ensureAndMakeDomainList(domainList), " );"));
</del><ins>+    auto insertRelationshipStatement = m_database.prepareStatementSlow(makeString(statement, ensureAndMakeDomainList(transaction, domainList), " );"));
</ins><span class="cx">     
</span><span class="cx">     if (!insertRelationshipStatement
</span><span class="cx">         || insertRelationshipStatement->bindInt(1, domainID) != SQLITE_OK) {
</span><span class="lines">@@ -1063,24 +1074,26 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::insertDomainRelationships(const ResourceLoadStatistics& loadStatistics)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::insertDomainRelationships(const SQLiteTransaction& transaction, const ResourceLoadStatistics& loadStatistics)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
+
</ins><span class="cx">     auto registrableDomainID = domainID(loadStatistics.registrableDomain);
</span><span class="cx">     
</span><span class="cx">     if (!registrableDomainID)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    insertDomainRelationshipList(storageAccessUnderTopFrameDomainsQuery, loadStatistics.storageAccessUnderTopFrameDomains, registrableDomainID.value());
-    insertDomainRelationshipList(topFrameUniqueRedirectsToQuery, loadStatistics.topFrameUniqueRedirectsTo, registrableDomainID.value());
-    insertDomainRelationshipList(topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, loadStatistics.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement, registrableDomainID.value());
-    insertDomainRelationshipList(topFrameUniqueRedirectsFromQuery, loadStatistics.topFrameUniqueRedirectsFrom, registrableDomainID.value());
-    insertDomainRelationshipList(subframeUnderTopFrameDomainsQuery, loadStatistics.subframeUnderTopFrameDomains, registrableDomainID.value());
-    insertDomainRelationshipList(subresourceUnderTopFrameDomainsQuery, loadStatistics.subresourceUnderTopFrameDomains, registrableDomainID.value());
-    insertDomainRelationshipList(subresourceUniqueRedirectsToQuery, loadStatistics.subresourceUniqueRedirectsTo, registrableDomainID.value());
-    insertDomainRelationshipList(subresourceUniqueRedirectsFromQuery, loadStatistics.subresourceUniqueRedirectsFrom, registrableDomainID.value());
-    insertDomainRelationshipList(topFrameLinkDecorationsFromQuery, loadStatistics.topFrameLinkDecorationsFrom, registrableDomainID.value());
-    insertDomainRelationshipList(topFrameLoadedThirdPartyScriptsQuery, loadStatistics.topFrameLoadedThirdPartyScripts, registrableDomainID.value());
</del><ins>+    insertDomainRelationshipList(transaction, storageAccessUnderTopFrameDomainsQuery, loadStatistics.storageAccessUnderTopFrameDomains, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToQuery, loadStatistics.topFrameUniqueRedirectsTo, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, loadStatistics.topFrameUniqueRedirectsToSinceSameSiteStrictEnforcement, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsFromQuery, loadStatistics.topFrameUniqueRedirectsFrom, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, subframeUnderTopFrameDomainsQuery, loadStatistics.subframeUnderTopFrameDomains, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, subresourceUnderTopFrameDomainsQuery, loadStatistics.subresourceUnderTopFrameDomains, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, subresourceUniqueRedirectsToQuery, loadStatistics.subresourceUniqueRedirectsTo, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, subresourceUniqueRedirectsFromQuery, loadStatistics.subresourceUniqueRedirectsFrom, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, topFrameLinkDecorationsFromQuery, loadStatistics.topFrameLinkDecorationsFrom, registrableDomainID.value());
+    insertDomainRelationshipList(transaction, topFrameLoadedThirdPartyScriptsQuery, loadStatistics.topFrameLoadedThirdPartyScripts, registrableDomainID.value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::populateFromMemoryStore(const ResourceLoadStatisticsMemoryStore& memoryStore)
</span><span class="lines">@@ -1090,6 +1103,9 @@
</span><span class="cx">     if (!isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto& statisticsMap = memoryStore.data();
</span><span class="cx">     for (const auto& statistic : statisticsMap.values()) {
</span><span class="cx">         auto result = insertObservedDomain(statistic);
</span><span class="lines">@@ -1103,12 +1119,15 @@
</span><span class="cx">     // Make a separate pass for inter-domain relationships so we
</span><span class="cx">     // can refer to the ObservedDomain table entries
</span><span class="cx">     for (auto& statistic : statisticsMap.values())
</span><del>-        insertDomainRelationships(statistic);
</del><ins>+        insertDomainRelationships(transaction, statistic);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::merge(WebCore::SQLiteStatement* current, const ResourceLoadStatistics& other)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::merge(const SQLiteTransaction& transaction, WebCore::SQLiteStatement* current, const ResourceLoadStatistics& other)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
</ins><span class="cx"> 
</span><span class="cx">     auto currentRegistrableDomain = current->columnText(RegistrableDomainIndex);
</span><span class="cx">     auto currentLastSeen = current->columnDouble(LastSeenIndex);
</span><span class="lines">@@ -1132,18 +1151,18 @@
</span><span class="cx">         setUserInteraction(other.registrableDomain, true, std::max(WallTime::fromRawSeconds(currentMostRecentUserInteraction), other.mostRecentUserInteractionTime));
</span><span class="cx"> 
</span><span class="cx">     if (other.grandfathered && !currentGrandfathered)
</span><del>-        setGrandfathered(other.registrableDomain, true);
</del><ins>+        setGrandfathered(transaction, other.registrableDomain, true);
</ins><span class="cx">     if (other.isPrevalentResource && !currentIsPrevalent)
</span><del>-        setPrevalentResource(other.registrableDomain);
</del><ins>+        setPrevalentResource(transaction, other.registrableDomain);
</ins><span class="cx">     if (other.isVeryPrevalentResource && !currentIsVeryPrevalent)
</span><del>-        setVeryPrevalentResource(other.registrableDomain);
</del><ins>+        setVeryPrevalentResource(transaction, other.registrableDomain);
</ins><span class="cx">     if (other.dataRecordsRemoved > currentDataRecordsRemoved)
</span><span class="cx">         updateDataRecordsRemoved(other.registrableDomain, other.dataRecordsRemoved);
</span><span class="cx">     if (other.gotLinkDecorationFromPrevalentResource && !currentIsScheduledForAllButCookieDataRemoval)
</span><del>-        setIsScheduledForAllButCookieDataRemoval(other.registrableDomain, true);
</del><ins>+        setIsScheduledForAllButCookieDataRemoval(transaction, other.registrableDomain, true);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::mergeStatistic(const ResourceLoadStatistics& statistic)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::mergeStatistic(const SQLiteTransaction& transaction, const ResourceLoadStatistics& statistic)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><span class="lines">@@ -1156,13 +1175,18 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    merge(scopedStatement.get(), statistic);
</del><ins>+    merge(transaction, scopedStatement.get(), statistic);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::mergeStatistics(Vector<ResourceLoadStatistics>&& statistics)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    if (statistics.isEmpty())
+        return;
</ins><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     for (auto& statistic : statistics) {
</span><span class="cx">         if (!domainID(statistic.registrableDomain)) {
</span><span class="cx">             auto result = insertObservedDomain(statistic);
</span><span class="lines">@@ -1172,13 +1196,15 @@
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><span class="cx">         } else
</span><del>-            mergeStatistic(statistic);
</del><ins>+            mergeStatistic(transaction, statistic);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Make a separate pass for inter-domain relationships so we
</span><span class="cx">     // can refer to the ObservedDomain table entries.
</span><span class="cx">     for (auto& statistic : statistics)
</span><del>-        insertDomainRelationships(statistic);
</del><ins>+        insertDomainRelationships(transaction, statistic);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static ASCIILiteral joinSubStatisticsForSorting()
</span><span class="lines">@@ -1419,15 +1445,22 @@
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><span class="cx">     auto notVeryPrevalentResources = findNotVeryPrevalentResources();
</span><ins>+    if (notVeryPrevalentResources.isEmpty())
+        return;
</ins><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
</ins><span class="cx">     for (auto& resourceStatistic : notVeryPrevalentResources.values()) {
</span><span class="cx">         if (shouldSkip(resourceStatistic.registrableDomain))
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         auto newPrevalence = classifier().calculateResourcePrevalence(resourceStatistic.subresourceUnderTopFrameDomainsCount, resourceStatistic.subresourceUniqueRedirectsToCount, resourceStatistic.subframeUnderTopFrameDomainsCount, resourceStatistic.topFrameUniqueRedirectsToCount, resourceStatistic.prevalence);
</span><del>-        if (newPrevalence != resourceStatistic.prevalence)
-            setPrevalentResource(resourceStatistic.registrableDomain, newPrevalence);
</del><ins>+        if (newPrevalence != resourceStatistic.prevalence) {
+            if (!transaction.inProgress())
+                transaction.begin();
+            setPrevalentResource(transaction, resourceStatistic.registrableDomain, newPrevalence);
+        }
</ins><span class="cx">     }
</span><ins>+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::classifyPrevalentResources()
</span><span class="lines">@@ -1534,6 +1567,9 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto incrementStorageAccess = m_database.prepareStatement("UPDATE ObservedDomains SET timesAccessedAsFirstPartyDueToStorageAccessAPI = timesAccessedAsFirstPartyDueToStorageAccessAPI + 1 WHERE domainID = ?"_s);
</span><span class="cx">     if (!incrementStorageAccess
</span><span class="cx">         || incrementStorageAccess->bindInt(1, *subFrameStatus.second) != SQLITE_OK
</span><span class="lines">@@ -1543,9 +1579,11 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    grantStorageAccessInternal(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, userWasPromptedEarlier, scope, [completionHandler = WTFMove(completionHandler)] (StorageAccessWasGranted wasGranted) mutable {
</del><ins>+    grantStorageAccessInternal(transaction, WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, userWasPromptedEarlier, scope, [completionHandler = WTFMove(completionHandler)] (StorageAccessWasGranted wasGranted) mutable {
</ins><span class="cx">         completionHandler(wasGranted == StorageAccessWasGranted::Yes ? StorageAccessStatus::HasAccess : StorageAccessStatus::CannotRequestAccess);
</span><span class="cx">     });
</span><ins>+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::requestStorageAccessUnderOpener(DomainInNeedOfStorageAccess&& domainInNeedOfStorageAccess, PageIdentifier openerPageID, OpenerDomain&& openerDomain)
</span><span class="lines">@@ -1561,7 +1599,10 @@
</span><span class="cx">         debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("[ITP] Storage access was granted for '"_s, domainInNeedOfStorageAccess.string(), "' under opener page from '"_s, openerDomain.string(), "', with user interaction in the opened window."_s));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    grantStorageAccessInternal(WTFMove(domainInNeedOfStorageAccess), WTFMove(openerDomain), std::nullopt, openerPageID, StorageAccessPromptWasShown::No, StorageAccessScope::PerPage, [](StorageAccessWasGranted) { });
</del><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+    grantStorageAccessInternal(transaction, WTFMove(domainInNeedOfStorageAccess), WTFMove(openerDomain), std::nullopt, openerPageID, StorageAccessPromptWasShown::No, StorageAccessScope::PerPage, [](StorageAccessWasGranted) { });
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::grantStorageAccess(SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, FrameIdentifier frameID, PageIdentifier pageID, StorageAccessPromptWasShown promptWasShown, StorageAccessScope scope, CompletionHandler<void(StorageAccessWasGranted)>&& completionHandler)
</span><span class="lines">@@ -1568,6 +1609,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     if (promptWasShown == StorageAccessPromptWasShown::Yes) {
</span><span class="cx">         auto subFrameStatus = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
</span><span class="cx">         if (!subFrameStatus.second) {
</span><span class="lines">@@ -1579,15 +1623,18 @@
</span><span class="cx">         if (!NetworkStorageSession::canRequestStorageAccessForLoginOrCompatibilityPurposesWithoutPriorUserInteraction(subFrameDomain, topFrameDomain))
</span><span class="cx">             ASSERT(hasHadUserInteraction(subFrameDomain, OperatingDatesWindow::Long));
</span><span class="cx"> #endif
</span><del>-        insertDomainRelationshipList(storageAccessUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *subFrameStatus.second);
</del><ins>+        insertDomainRelationshipList(transaction, storageAccessUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *subFrameStatus.second);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    grantStorageAccessInternal(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, promptWasShown, scope, WTFMove(completionHandler));
</del><ins>+    grantStorageAccessInternal(transaction, WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, promptWasShown, scope, WTFMove(completionHandler));
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::grantStorageAccessInternal(SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, std::optional<FrameIdentifier> frameID, PageIdentifier pageID, StorageAccessPromptWasShown promptWasShownNowOrEarlier, StorageAccessScope scope, CompletionHandler<void(StorageAccessWasGranted)>&& completionHandler)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::grantStorageAccessInternal(const SQLiteTransaction& transaction, SubFrameDomain&& subFrameDomain, TopFrameDomain&& topFrameDomain, std::optional<FrameIdentifier> frameID, PageIdentifier pageID, StorageAccessPromptWasShown promptWasShownNowOrEarlier, StorageAccessScope scope, CompletionHandler<void(StorageAccessWasGranted)>&& completionHandler)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
</ins><span class="cx"> 
</span><span class="cx">     if (subFrameDomain == topFrameDomain) {
</span><span class="cx">         completionHandler(StorageAccessWasGranted::Yes);
</span><span class="lines">@@ -1624,7 +1671,11 @@
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains(const HashSet<RegistrableDomain>& domains)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    if (domains.isEmpty())
+        return;
</ins><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
</ins><span class="cx">     for (auto& registrableDomain : domains) {
</span><span class="cx">         auto result = ensureResourceStatisticsForRegistrableDomain(registrableDomain);
</span><span class="cx">         if (!result.second)
</span><span class="lines">@@ -1636,6 +1687,7 @@
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::grandfatherDataForDomains failed, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><ins>+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Vector<RegistrableDomain> ResourceLoadStatisticsDatabaseStore::ensurePrevalentResourcesForDebugMode()
</span><span class="lines">@@ -1648,6 +1700,9 @@
</span><span class="cx">     Vector<RegistrableDomain> primaryDomainsToBlock;
</span><span class="cx">     primaryDomainsToBlock.reserveInitialCapacity(2);
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(debugStaticPrevalentResource());
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::ensurePrevalentResourcesForDebugMode was not completed due to failed insert attempt for debugStaticPrevalentResource", this);
</span><span class="lines">@@ -1654,7 +1709,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    setPrevalentResource(debugStaticPrevalentResource(), ResourceLoadPrevalence::High);
</del><ins>+    setPrevalentResource(transaction, debugStaticPrevalentResource(), ResourceLoadPrevalence::High);
</ins><span class="cx">     primaryDomainsToBlock.uncheckedAppend(debugStaticPrevalentResource());
</span><span class="cx"> 
</span><span class="cx">     if (!debugManualPrevalentResource().isEmpty()) {
</span><span class="lines">@@ -1663,7 +1718,7 @@
</span><span class="cx">             RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::ensurePrevalentResourcesForDebugMode was not completed due to failed insert attempt for debugManualPrevalentResource", this);
</span><span class="cx">             return { };
</span><span class="cx">         }
</span><del>-        setPrevalentResource(debugManualPrevalentResource(), ResourceLoadPrevalence::High);
</del><ins>+        setPrevalentResource(transaction, debugManualPrevalentResource(), ResourceLoadPrevalence::High);
</ins><span class="cx">         primaryDomainsToBlock.uncheckedAppend(debugManualPrevalentResource());
</span><span class="cx"> 
</span><span class="cx">         if (debugLoggingEnabled()) {
</span><span class="lines">@@ -1672,6 +1727,8 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    transaction.commit();
+
</ins><span class="cx">     return primaryDomainsToBlock;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1682,8 +1739,13 @@
</span><span class="cx">     bool areTargetAndTopFrameDomainsSameSite = targetDomain == topFrameDomain;
</span><span class="cx">     bool areTargetAndSourceDomainsSameSite = targetDomain == sourceDomain;
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+
</ins><span class="cx">     bool statisticsWereUpdated = false;
</span><span class="cx">     if (!isMainFrame && !(areTargetAndTopFrameDomainsSameSite || areTargetAndSourceDomainsSameSite)) {
</span><ins>+        if (!transaction.inProgress())
+            transaction.begin();
+
</ins><span class="cx">         auto targetResult = ensureResourceStatisticsForRegistrableDomain(targetDomain);
</span><span class="cx">         if (!targetResult.second) {
</span><span class="cx">             RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::logFrameNavigation was not completed due to failed insert attempt of target domain", this);
</span><span class="lines">@@ -1690,7 +1752,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         updateLastSeen(targetDomain, ResourceLoadStatistics::reduceTimeResolution(WallTime::now()));
</span><del>-        insertDomainRelationshipList(subframeUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *targetResult.second);
</del><ins>+        insertDomainRelationshipList(transaction, subframeUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *targetResult.second);
</ins><span class="cx">         statisticsWereUpdated = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1698,6 +1760,9 @@
</span><span class="cx">         if (isMainFrame) {
</span><span class="cx">             bool wasNavigatedAfterShortDelayWithoutUserInteraction = !wasPotentiallyInitiatedByUser && delayAfterMainFrameDocumentLoad < parameters().minDelayAfterMainFrameDocumentLoadToNotBeARedirect;
</span><span class="cx">             if (isRedirect || wasNavigatedAfterShortDelayWithoutUserInteraction) {
</span><ins>+                if (!transaction.inProgress())
+                    transaction.begin();
+
</ins><span class="cx">                 auto redirectingDomainResult = ensureResourceStatisticsForRegistrableDomain(sourceDomain);
</span><span class="cx">                 auto targetResult = ensureResourceStatisticsForRegistrableDomain(targetDomain);
</span><span class="cx">                 if (!targetResult.second || !redirectingDomainResult.second) {
</span><span class="lines">@@ -1704,9 +1769,9 @@
</span><span class="cx">                     RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::logFrameNavigation was not completed due to failed insert attempt of target or redirecting domain (isMainFrame)", this);
</span><span class="cx">                     return;
</span><span class="cx">                 }
</span><del>-                insertDomainRelationshipList(topFrameUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
</del><ins>+                insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
</ins><span class="cx">                 if (isRedirect) {
</span><del>-                    insertDomainRelationshipList(topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
</del><ins>+                    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
</ins><span class="cx"> 
</span><span class="cx">                     if (UNLIKELY(debugLoggingEnabled())) {
</span><span class="cx">                         RELEASE_LOG_INFO(ITPDebug, "Did set %" PUBLIC_LOG_STRING " as making a top frame redirect to %" PUBLIC_LOG_STRING ".", sourceDomain.string().utf8().data(), targetDomain.string().utf8().data());
</span><span class="lines">@@ -1713,10 +1778,13 @@
</span><span class="cx">                         debugBroadcastConsoleMessage(MessageSource::ITPDebug, MessageLevel::Info, makeString("Did set '", sourceDomain.string(), "' as making a top frame redirect to '", targetDomain.string(), "'."));
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><del>-                insertDomainRelationshipList(topFrameUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ sourceDomain }), *targetResult.second);
</del><ins>+                insertDomainRelationshipList(transaction, topFrameUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ sourceDomain }), *targetResult.second);
</ins><span class="cx">                 statisticsWereUpdated = true;
</span><span class="cx">             }
</span><span class="cx">         } else if (isRedirect) {
</span><ins>+            if (!transaction.inProgress())
+                transaction.begin();
+
</ins><span class="cx">             auto redirectingDomainResult = ensureResourceStatisticsForRegistrableDomain(sourceDomain);
</span><span class="cx">             auto targetResult = ensureResourceStatisticsForRegistrableDomain(targetDomain);
</span><span class="cx">             if (!targetResult.second || !redirectingDomainResult.second) {
</span><span class="lines">@@ -1723,11 +1791,12 @@
</span><span class="cx">                 RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::logFrameNavigation was not completed due to failed insert attempt of target or redirecting domain (isRedirect)", this);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            insertDomainRelationshipList(subresourceUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
-            insertDomainRelationshipList(subresourceUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ sourceDomain }), *targetResult.second);
</del><ins>+            insertDomainRelationshipList(transaction, subresourceUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ targetDomain }), *redirectingDomainResult.second);
+            insertDomainRelationshipList(transaction, subresourceUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ sourceDomain }), *targetResult.second);
</ins><span class="cx">             statisticsWereUpdated = true;
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    transaction.commit();
</ins><span class="cx"> 
</span><span class="cx">     if (statisticsWereUpdated)
</span><span class="cx">         scheduleStatisticsProcessingRequestIfNecessary();
</span><span class="lines">@@ -1738,15 +1807,20 @@
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx">     ASSERT(fromDomain != toDomain);
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto toDomainResult = ensureResourceStatisticsForRegistrableDomain(toDomain);
</span><span class="cx">     if (!toDomainResult.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::logCrossSiteLoadWithLinkDecoration was not completed due to failed insert attempt", this);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    insertDomainRelationshipList(topFrameLinkDecorationsFromQuery, HashSet<RegistrableDomain>({ fromDomain }), *toDomainResult.second);
</del><ins>+    insertDomainRelationshipList(transaction, topFrameLinkDecorationsFromQuery, HashSet<RegistrableDomain>({ fromDomain }), *toDomainResult.second);
</ins><span class="cx">     
</span><span class="cx">     if (isPrevalentResource(fromDomain))
</span><del>-        setIsScheduledForAllButCookieDataRemoval(toDomain, true);
</del><ins>+        setIsScheduledForAllButCookieDataRemoval(transaction, toDomain, true);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::clearTopFrameUniqueRedirectsToSinceSameSiteStrictEnforcement(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
</span><span class="lines">@@ -1753,6 +1827,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto targetResult = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!targetResult.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearTopFrameUniqueRedirectsToSinceSameSiteStrictEnforcement was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -1767,6 +1844,8 @@
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearTopFrameUniqueRedirectsToSinceSameSiteStrictEnforcement failed to bind, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><ins>+
+    transaction.commit();
</ins><span class="cx">     
</span><span class="cx">     completionHandler();
</span><span class="cx"> }
</span><span class="lines">@@ -1791,6 +1870,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::logUserInteraction was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -1798,6 +1880,9 @@
</span><span class="cx">     }
</span><span class="cx">     bool didHavePreviousUserInteraction = hasHadUserInteraction(domain, OperatingDatesWindow::Long);
</span><span class="cx">     setUserInteraction(domain, true, WallTime::now());
</span><ins>+
+    transaction.commit();
+
</ins><span class="cx">     if (didHavePreviousUserInteraction) {
</span><span class="cx">         completionHandler();
</span><span class="cx">         return;
</span><span class="lines">@@ -1809,6 +1894,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto targetResult = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!targetResult.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearUserInteraction was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -1824,6 +1912,8 @@
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    transaction.commit();
+
</ins><span class="cx">     // Update cookie blocking unconditionally since a call to hasHadUserInteraction()
</span><span class="cx">     // to check the previous user interaction status could call clearUserInteraction(),
</span><span class="cx">     // blowing the call stack.
</span><span class="lines">@@ -1858,9 +1948,11 @@
</span><span class="cx">     return hadUserInteraction;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::setPrevalentResource(const RegistrableDomain& domain, ResourceLoadPrevalence newPrevalence)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::setPrevalentResource(const SQLiteTransaction&, const RegistrableDomain& domain, ResourceLoadPrevalence newPrevalence)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
+
</ins><span class="cx">     if (shouldSkip(domain))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -2006,6 +2098,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearPrevalentResource was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2021,11 +2116,24 @@
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setGrandfathered(const RegistrableDomain& domain, bool value)
</span><span class="cx"> {
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
+    setGrandfathered(transaction, domain, value);
+
+    transaction.commit();
+}
+
+void ResourceLoadStatisticsDatabaseStore::setGrandfathered(const WebCore::SQLiteTransaction&, const RegistrableDomain& domain, bool value)
+{
</ins><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
</ins><span class="cx"> 
</span><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="lines">@@ -2043,9 +2151,10 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatisticsDatabaseStore::setIsScheduledForAllButCookieDataRemoval(const RegistrableDomain& domain, bool value)
</del><ins>+void ResourceLoadStatisticsDatabaseStore::setIsScheduledForAllButCookieDataRemoval(const SQLiteTransaction&, const RegistrableDomain& domain, bool value)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><ins>+    ASSERT(m_database.transactionInProgress());
</ins><span class="cx"> 
</span><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="lines">@@ -2105,6 +2214,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(subFrameDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setSubframeUnderTopFrameDomain was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2111,7 +2223,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // For consistency, make sure we also have a statistics entry for the top frame domain.
</span><del>-    insertDomainRelationshipList(subframeUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, subframeUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setSubresourceUnderTopFrameDomain(const SubResourceDomain& subresourceDomain, const TopFrameDomain& topFrameDomain)
</span><span class="lines">@@ -2118,6 +2232,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setSubresourceUnderTopFrameDomain was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2124,7 +2241,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // For consistency, make sure we also have a statistics entry for the top frame domain.
</span><del>-    insertDomainRelationshipList(subresourceUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, subresourceUnderTopFrameDomainsQuery, HashSet<RegistrableDomain>({ topFrameDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setSubresourceUniqueRedirectTo(const SubResourceDomain& subresourceDomain, const RedirectDomain& redirectDomain)
</span><span class="lines">@@ -2131,6 +2250,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setSubresourceUniqueRedirectTo was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2137,7 +2259,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // For consistency, make sure we also have a statistics entry for the redirect domain.
</span><del>-    insertDomainRelationshipList(subresourceUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, subresourceUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setSubresourceUniqueRedirectFrom(const SubResourceDomain& subresourceDomain, const RedirectDomain& redirectDomain)
</span><span class="lines">@@ -2144,6 +2268,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(subresourceDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setSubresourceUniqueRedirectFrom was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2150,7 +2277,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // For consistency, make sure we also have a statistics entry for the redirect domain.
</span><del>-    insertDomainRelationshipList(subresourceUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, subresourceUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setTopFrameUniqueRedirectTo(const TopFrameDomain& topFrameDomain, const RedirectDomain& redirectDomain)
</span><span class="lines">@@ -2157,6 +2286,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setTopFrameUniqueRedirectTo was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2163,8 +2295,10 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    insertDomainRelationshipList(topFrameUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
-    insertDomainRelationshipList(topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsToSinceSameSiteStrictEnforcementQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setTopFrameUniqueRedirectFrom(const TopFrameDomain& topFrameDomain, const RedirectDomain& redirectDomain)
</span><span class="lines">@@ -2171,6 +2305,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(topFrameDomain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setTopFrameUniqueRedirectFrom was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2177,7 +2314,9 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     // For consistency, make sure we also have a statistics entry for the redirect domain.
</span><del>-    insertDomainRelationshipList(topFrameUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
</del><ins>+    insertDomainRelationshipList(transaction, topFrameUniqueRedirectsFromQuery, HashSet<RegistrableDomain>({ redirectDomain }), *result.second);
+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> std::pair<ResourceLoadStatisticsDatabaseStore::AddedRecord, std::optional<unsigned>> ResourceLoadStatisticsDatabaseStore::ensureResourceStatisticsForRegistrableDomain(const RegistrableDomain& domain)
</span><span class="lines">@@ -2538,6 +2677,8 @@
</span><span class="cx">     auto oldestUserInteraction = now;
</span><span class="cx">     RegistrableDomainsToDeleteOrRestrictWebsiteDataFor toDeleteOrRestrictFor;
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+
</ins><span class="cx">     Vector<DomainData> domains = this->domains();
</span><span class="cx">     Vector<unsigned> domainIDsToClearGrandfathering;
</span><span class="cx">     for (auto& statistic : domains) {
</span><span class="lines">@@ -2551,7 +2692,9 @@
</span><span class="cx">         } else {
</span><span class="cx">             if (shouldRemoveAllButCookiesFor(statistic, shouldCheckForGrandfathering)) {
</span><span class="cx">                 toDeleteOrRestrictFor.domainsToDeleteAllNonCookieWebsiteDataFor.append(statistic.registrableDomain);
</span><del>-                setIsScheduledForAllButCookieDataRemoval(statistic.registrableDomain, false);
</del><ins>+                if (!transaction.inProgress())
+                    transaction.begin();
+                setIsScheduledForAllButCookieDataRemoval(transaction, statistic.registrableDomain, false);
</ins><span class="cx">             }
</span><span class="cx">             if (shouldEnforceSameSiteStrictFor(statistic, shouldCheckForGrandfathering)) {
</span><span class="cx">                 toDeleteOrRestrictFor.domainsToEnforceSameSiteStrictFor.append(statistic.registrableDomain);
</span><span class="lines">@@ -2571,6 +2714,8 @@
</span><span class="cx">         toDeleteOrRestrictFor.domainsToDeleteAllNonCookieWebsiteDataFor.clear();
</span><span class="cx"> 
</span><span class="cx">     clearGrandfathering(WTFMove(domainIDsToClearGrandfathering));
</span><ins>+
+    transaction.commit();
</ins><span class="cx">     
</span><span class="cx">     return toDeleteOrRestrictFor;
</span><span class="cx"> }
</span><span class="lines">@@ -2635,6 +2780,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!RunLoop::isMain());
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setLastSeen was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2642,6 +2790,8 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     updateLastSeen(domain, WallTime::fromRawSeconds(seconds.seconds()));
</span><ins>+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setPrevalentResource(const RegistrableDomain& domain)
</span><span class="lines">@@ -2650,7 +2800,21 @@
</span><span class="cx"> 
</span><span class="cx">     if (shouldSkip(domain))
</span><span class="cx">         return;
</span><del>-    
</del><ins>+
+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+    setPrevalentResource(transaction, domain);
+    transaction.commit();
+}
+
+void ResourceLoadStatisticsDatabaseStore::setPrevalentResource(const SQLiteTransaction& transaction, const RegistrableDomain& domain)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(m_database.transactionInProgress());
+
+    if (shouldSkip(domain))
+        return;
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setPrevalentResource was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2657,7 +2821,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    setPrevalentResource(domain, ResourceLoadPrevalence::High);
</del><ins>+    setPrevalentResource(transaction, domain, ResourceLoadPrevalence::High);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::setVeryPrevalentResource(const RegistrableDomain& domain)
</span><span class="lines">@@ -2666,7 +2830,23 @@
</span><span class="cx"> 
</span><span class="cx">     if (shouldSkip(domain))
</span><span class="cx">         return;
</span><del>-    
</del><ins>+
+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
+    setVeryPrevalentResource(transaction, domain);
+
+    transaction.commit();
+}
+
+void ResourceLoadStatisticsDatabaseStore::setVeryPrevalentResource(const SQLiteTransaction& transaction, const RegistrableDomain& domain)
+{
+    ASSERT(!RunLoop::isMain());
+    ASSERT(m_database.transactionInProgress());
+
+    if (shouldSkip(domain))
+        return;
+
</ins><span class="cx">     auto result = ensureResourceStatisticsForRegistrableDomain(domain);
</span><span class="cx">     if (!result.second) {
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::setVeryPrevalentResource was not completed due to failed insert attempt", this);
</span><span class="lines">@@ -2673,7 +2853,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    setPrevalentResource(domain, ResourceLoadPrevalence::VeryHigh);
</del><ins>+    setPrevalentResource(transaction, domain, ResourceLoadPrevalence::VeryHigh);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::updateDataRecordsRemoved(const RegistrableDomain& domain, int value)
</span><span class="lines">@@ -2971,6 +3151,9 @@
</span><span class="cx">             return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     int rowsToPrune = m_operatingDatesSize - operatingDatesWindowLong + 1;
</span><span class="cx">     if (rowsToPrune > 0) {
</span><span class="cx">         auto deleteLeastRecentOperatingDateStatement = m_database.prepareStatement("DELETE FROM OperatingDates ORDER BY year, month, monthDay LIMIT ?;"_s);
</span><span class="lines">@@ -2993,6 +3176,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     updateOperatingDatesParameters();
</span><ins>+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ResourceLoadStatisticsDatabaseStore::hasStatisticsExpired(WallTime mostRecentUserInteractionTime, OperatingDatesWindow operatingDatesWindow) const
</span><span class="lines">@@ -3026,6 +3211,10 @@
</span><span class="cx"> {
</span><span class="cx">     // Populate the Operating Dates table with enough days to require pruning.
</span><span class="cx">     double daysAgoInSeconds = 0;
</span><ins>+
+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     for (unsigned i = 1; i <= numberOfOperatingDaysPassed; i++) {
</span><span class="cx">         double daysToSubtract = Seconds::fromHours(24 * i).value();
</span><span class="cx">         daysAgoInSeconds = WallTime::now().secondsSinceEpoch().value() - daysToSubtract;
</span><span class="lines">@@ -3045,6 +3234,8 @@
</span><span class="cx"> 
</span><span class="cx">     updateOperatingDatesParameters();
</span><span class="cx"> 
</span><ins>+    transaction.commit();
+
</ins><span class="cx">     // Make sure mostRecentUserInteractionTime is the least recent of all entries.
</span><span class="cx">     daysAgoInSeconds -= Seconds::fromHours(24).value();
</span><span class="cx">     auto scopedInsertObservedDomainStatement = this->scopedStatement(m_insertObservedDomainStatement, insertObservedDomainQuery, "insertExpiredStatisticForTesting"_s);
</span><span class="lines">@@ -3147,6 +3338,10 @@
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::insertPrivateClickMeasurement(PrivateClickMeasurement&& attribution, PrivateClickMeasurementAttributionType attributionType)
</span><span class="cx"> {
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+    auto commitTransaction = makeScopeExit([&transaction] { transaction.commit(); });
+
</ins><span class="cx">     auto sourceData = ensureResourceStatisticsForRegistrableDomain(attribution.sourceSite().registrableDomain);
</span><span class="cx">     auto attributionDestinationData = ensureResourceStatisticsForRegistrableDomain(attribution.destinationSite().registrableDomain);
</span><span class="cx"> 
</span><span class="lines">@@ -3330,6 +3525,9 @@
</span><span class="cx">         bindParameter = String::number(*domainIDToMatch);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto clearUnattributedScopedStatement = this->scopedStatement(m_clearUnattributedPrivateClickMeasurementStatement, clearUnattributedPrivateClickMeasurementQuery, "clearPrivateClickMeasurement"_s);
</span><span class="cx"> 
</span><span class="cx">     if (!clearUnattributedScopedStatement
</span><span class="lines">@@ -3349,6 +3547,8 @@
</span><span class="cx">         RELEASE_LOG_ERROR_IF_ALLOWED(m_sessionID, "%p - ResourceLoadStatisticsDatabaseStore::clearPrivateClickMeasurement clearAttributedScopedStatement, error message: %" PRIVATE_LOG_STRING, this, m_database.lastErrorMsg());
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><ins>+
+    transaction.commit();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceLoadStatisticsDatabaseStore::clearExpiredPrivateClickMeasurement()
</span><span class="lines">@@ -3544,6 +3744,9 @@
</span><span class="cx"> {
</span><span class="cx">     auto expiredTimeToSend = WallTime::now() - 1_h;
</span><span class="cx"> 
</span><ins>+    SQLiteTransaction transaction(m_database);
+    transaction.begin();
+
</ins><span class="cx">     auto earliestTimeToSendToSourceStatement = m_database.prepareStatement("UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToSource = ?"_s);
</span><span class="cx">     auto earliestTimeToSendToDestinationStatement = m_database.prepareStatement("UPDATE AttributedPrivateClickMeasurement SET earliestTimeToSendToDestination = null"_s);
</span><span class="cx"> 
</span><span class="lines">@@ -3559,6 +3762,8 @@
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    transaction.commit();
+
</ins><span class="cx">     return;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitNetworkProcessClassifierResourceLoadStatisticsDatabaseStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h (278915 => 278916)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h      2021-06-16 00:46:26 UTC (rev 278915)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsDatabaseStore.h 2021-06-16 00:56:03 UTC (rev 278916)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">     void setGrandfathered(const RegistrableDomain&, bool value) override;
</span><span class="cx">     bool isGrandfathered(const RegistrableDomain&) const override;
</span><span class="cx"> 
</span><del>-    void setIsScheduledForAllButCookieDataRemoval(const RegistrableDomain&, bool value);
</del><ins>+    void setIsScheduledForAllButCookieDataRemoval(const WebCore::SQLiteTransaction&, const RegistrableDomain&, bool value);
</ins><span class="cx">     void setSubframeUnderTopFrameDomain(const SubFrameDomain&, const TopFrameDomain&) override;
</span><span class="cx">     void setSubresourceUnderTopFrameDomain(const SubResourceDomain&, const TopFrameDomain&) override;
</span><span class="cx">     void setSubresourceUniqueRedirectTo(const SubResourceDomain&, const RedirectDomain&) override;
</span><span class="lines">@@ -177,6 +177,9 @@
</span><span class="cx">     void destroyStatements();
</span><span class="cx">     WebCore::SQLiteStatementAutoResetScope scopedStatement(std::unique_ptr<WebCore::SQLiteStatement>&, ASCIILiteral, const String&) const;
</span><span class="cx"> 
</span><ins>+    void setPrevalentResource(const WebCore::SQLiteTransaction&, const RegistrableDomain&);
+    void setVeryPrevalentResource(const WebCore::SQLiteTransaction&, const RegistrableDomain&);
+    void setGrandfathered(const WebCore::SQLiteTransaction&, const RegistrableDomain&, bool value);
</ins><span class="cx">     bool hasStorageAccess(const TopFrameDomain&, const SubFrameDomain&) const;
</span><span class="cx">     Vector<WebResourceLoadStatisticsStore::ThirdPartyDataForSpecificFirstParty> getThirdPartyDataForSpecificFirstPartyDomains(unsigned, const RegistrableDomain&) const;
</span><span class="cx">     void openAndUpdateSchemaIfNecessary();
</span><span class="lines">@@ -183,12 +186,12 @@
</span><span class="cx">     String getDomainStringFromDomainID(unsigned) const;
</span><span class="cx">     ASCIILiteral getSubStatisticStatement(const String&) const;
</span><span class="cx">     void appendSubStatisticList(StringBuilder&, const String& tableName, const String& domain) const;
</span><del>-    void mergeStatistic(const ResourceLoadStatistics&);
-    void merge(WebCore::SQLiteStatement*, const ResourceLoadStatistics&);
</del><ins>+    void mergeStatistic(const WebCore::SQLiteTransaction&, const ResourceLoadStatistics&);
+    void merge(const WebCore::SQLiteTransaction&, WebCore::SQLiteStatement*, const ResourceLoadStatistics&);
</ins><span class="cx">     void clearDatabaseContents();
</span><span class="cx">     bool insertObservedDomain(const ResourceLoadStatistics&) WARN_UNUSED_RETURN;
</span><del>-    void insertDomainRelationships(const ResourceLoadStatistics&);
-    void insertDomainRelationshipList(const String&, const HashSet<RegistrableDomain>&, unsigned);
</del><ins>+    void insertDomainRelationships(const WebCore::SQLiteTransaction&, const ResourceLoadStatistics&);
+    void insertDomainRelationshipList(const WebCore::SQLiteTransaction&, const String&, const HashSet<RegistrableDomain>&, unsigned);
</ins><span class="cx">     bool relationshipExists(WebCore::SQLiteStatementAutoResetScope&, std::optional<unsigned> firstDomainID, const RegistrableDomain& secondDomain) const;
</span><span class="cx">     std::optional<unsigned> domainID(const RegistrableDomain&) const;
</span><span class="cx">     bool domainExists(const RegistrableDomain&) const;
</span><span class="lines">@@ -235,10 +238,10 @@
</span><span class="cx">     bool areAllThirdPartyCookiesBlockedUnder(const TopFrameDomain&) override;
</span><span class="cx">     CookieAccess cookieAccess(const SubResourceDomain&, const TopFrameDomain&);
</span><span class="cx"> 
</span><del>-    void setPrevalentResource(const RegistrableDomain&, ResourceLoadPrevalence);
</del><ins>+    void setPrevalentResource(const WebCore::SQLiteTransaction&, const RegistrableDomain&, ResourceLoadPrevalence);
</ins><span class="cx">     unsigned recursivelyFindNonPrevalentDomainsThatRedirectedToThisDomain(unsigned primaryDomainID, StdSet<unsigned>& nonPrevalentRedirectionSources, unsigned numberOfRecursiveCalls);
</span><span class="cx">     void setDomainsAsPrevalent(StdSet<unsigned>&&);
</span><del>-    void grantStorageAccessInternal(SubFrameDomain&&, TopFrameDomain&&, std::optional<WebCore::FrameIdentifier>, WebCore::PageIdentifier, WebCore::StorageAccessPromptWasShown, WebCore::StorageAccessScope, CompletionHandler<void(WebCore::StorageAccessWasGranted)>&&);
</del><ins>+    void grantStorageAccessInternal(const WebCore::SQLiteTransaction&, SubFrameDomain&&, TopFrameDomain&&, std::optional<WebCore::FrameIdentifier>, WebCore::PageIdentifier, WebCore::StorageAccessPromptWasShown, WebCore::StorageAccessScope, CompletionHandler<void(WebCore::StorageAccessWasGranted)>&&);
</ins><span class="cx">     void markAsPrevalentIfHasRedirectedToPrevalent();
</span><span class="cx">     Vector<RegistrableDomain> ensurePrevalentResourcesForDebugMode() override;
</span><span class="cx">     void removeDataRecords(CompletionHandler<void()>&&);
</span><span class="lines">@@ -253,7 +256,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool createUniqueIndices();
</span><span class="cx">     bool createSchema();
</span><del>-    String ensureAndMakeDomainList(const HashSet<RegistrableDomain>&);
</del><ins>+    String ensureAndMakeDomainList(const WebCore::SQLiteTransaction&, const HashSet<RegistrableDomain>&);
</ins><span class="cx">     std::optional<WallTime> mostRecentUserInteractionTime(const DomainData&);
</span><span class="cx">     
</span><span class="cx">     void removeUnattributed(WebCore::PrivateClickMeasurement&);
</span></span></pre>
</div>
</div>

</body>
</html>