<!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>