Skip to content

Commit

Permalink
Revert 0297f12. rdar://problem/101927216
Browse files Browse the repository at this point in the history
  • Loading branch information
alancoon committed Nov 12, 2022
1 parent 082f404 commit 3c74389
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 99 deletions.
135 changes: 43 additions & 92 deletions Source/WebKit/NetworkProcess/storage/SQLiteStorageArea.cpp
Expand Up @@ -97,7 +97,7 @@ bool SQLiteStorageArea::isEmpty()
ASSERT(!isMainRunLoop());

if (m_cache)
return m_cache->items.isEmpty();
return m_cache->isEmpty();

if (!prepareDatabase(ShouldCreateIfNotExists::No))
return true;
Expand Down Expand Up @@ -175,13 +175,14 @@ bool SQLiteStorageArea::prepareDatabase(ShouldCreateIfNotExists shouldCreateIfNo
return false;
}

if (quota() != WebCore::StorageMap::noQuota)
m_database->setMaximumSize(quota());

return true;
}

void SQLiteStorageArea::startTransactionIfNecessary()
{
ASSERT(m_database);

if (!m_transaction)
m_transaction = makeUnique<WebCore::SQLiteTransaction>(*m_database);

Expand Down Expand Up @@ -212,8 +213,8 @@ WebCore::SQLiteStatementAutoResetScope SQLiteStorageArea::cachedStatement(Statem
Expected<String, StorageError> SQLiteStorageArea::getItem(const String& key)
{
if (m_cache) {
auto iterator = m_cache->items.find(key);
if (iterator == m_cache->items.end())
auto iterator = m_cache->find(key);
if (iterator == m_cache->end())
return String();

if (!iterator->value.isNull())
Expand Down Expand Up @@ -248,126 +249,84 @@ Expected<String, StorageError> SQLiteStorageArea::getItemFromDatabase(const Stri
return makeUnexpected(StorageError::ItemNotFound);
}

Expected<HashMap<String, String>, StorageError> SQLiteStorageArea::getAllItemsFromDatabase()
HashMap<String, String> SQLiteStorageArea::allItems()
{
if (!prepareDatabase(ShouldCreateIfNotExists::No))
return makeUnexpected(StorageError::Database);
ASSERT(!isMainRunLoop());

if (!m_database)
if (!prepareDatabase(ShouldCreateIfNotExists::No) || !m_database)
return HashMap<String, String> { };

HashMap<String, String> items;
if (m_cache) {
items.reserveInitialCapacity(m_cache->size());
for (auto& [key, value] : *m_cache) {
if (!value.isNull()) {
items.add(key, value);
continue;
}

if (auto result = getItemFromDatabase(key))
items.add(key, result.value());
}
return items;
}

// Import from database.
auto statement = cachedStatement(StatementType::GetAllItems);
if (!statement) {
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::getAllItemsFromDatabase failed on creating statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return makeUnexpected(StorageError::Database);
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::getAllItems failed on creating statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return { };
}

HashMap<String, String> items;
m_cache = HashMap<String, String> { };
int result = statement->step();
while (result == SQLITE_ROW) {
String key = statement->columnText(0);
String value = statement->columnBlobAsString(1);
if (!key.isNull() && !value.isNull())
if (!key.isNull() && !value.isNull()) {
m_cache->add(key, value.sizeInBytes() > maximumSizeForValuesKeptInMemory ? String() : value);
items.add(WTFMove(key), WTFMove(value));
}

result = statement->step();
}

if (result != SQLITE_DONE) {
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::getAllItemsFromDatabase failed on executing statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return makeUnexpected(StorageError::Database);
}
if (result != SQLITE_DONE)
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::getAllItems failed on executing statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());

return items;
}

void SQLiteStorageArea::initializeCache(const HashMap<String, String>& items)
{
if (m_cache)
return;

m_cache = Cache { };
for (auto& [key, value] : items) {
ASSERT(!key.isNull() && !value.isNull());
CheckedUint64 newSize = m_cache->size;
newSize += key.sizeInBytes();
newSize += value.sizeInBytes();
m_cache->size = newSize;
m_cache->items.add(key, value.sizeInBytes() > maximumSizeForValuesKeptInMemory ? String() : value);
}
}

HashMap<String, String> SQLiteStorageArea::allItems()
{
ASSERT(!isMainRunLoop());

if (m_cache) {
HashMap<String, String> items;
items.reserveInitialCapacity(m_cache->items.size());
for (auto& [key, value] : m_cache->items) {
if (!value.isNull()) {
items.add(key, value);
continue;
}

if (auto result = getItemFromDatabase(key))
items.add(key, result.value());
}
return items;
}

auto result = getAllItemsFromDatabase();
if (!result)
return HashMap<String, String> { };

initializeCache(result.value());
return result.value();
}

Expected<void, StorageError> SQLiteStorageArea::setItem(IPC::Connection::UniqueID connection, StorageAreaImplIdentifier storageAreaImplID, String&& key, String&& value, const String& urlString)
{
ASSERT(!isMainRunLoop());

if (!prepareDatabase(ShouldCreateIfNotExists::Yes))
return makeUnexpected(StorageError::Database);

if (!m_cache) {
auto result = getAllItemsFromDatabase();
if (!result)
return makeUnexpected(result.error());
initializeCache(result.value());
}

CheckedUint64 newSize = m_cache->size;
bool keyExists = m_cache->items.contains(key);
startTransactionIfNecessary();
String oldValue;
if (auto valueOrError = getItem(key))
oldValue = valueOrError.value();

if (keyExists)
newSize -= oldValue.sizeInBytes();
else
newSize += key.sizeInBytes();
newSize += value.sizeInBytes();
if (newSize.hasOverflowed() || newSize > quota())
return makeUnexpected(StorageError::QuotaExceeded);

auto statement = cachedStatement(StatementType::SetItem);
if (!statement || statement->bindText(1, key) || statement->bindBlob(2, value)) {
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::setItem failed on creating statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return makeUnexpected(StorageError::Database);
}

int result = statement->step();
if (result == SQLITE_FULL)
return makeUnexpected(StorageError::QuotaExceeded);
if (result != SQLITE_DONE) {
RELEASE_LOG_ERROR(Storage, "SQLiteStorageArea::setItem failed on stepping statement (%d) - %s", m_database->lastError(), m_database->lastErrorMsg());
return makeUnexpected(StorageError::Database);
}

dispatchEvents(connection, storageAreaImplID, key, oldValue, value, urlString);
m_cache->items.set(WTFMove(key), value.sizeInBytes() > maximumSizeForValuesKeptInMemory ? String() : WTFMove(value));
m_cache->size = newSize;

if (m_cache)
m_cache->set(WTFMove(key), value.sizeInBytes() > maximumSizeForValuesKeptInMemory ? String() : WTFMove(value));

return { };
}
Expand Down Expand Up @@ -397,14 +356,8 @@ Expected<void, StorageError> SQLiteStorageArea::removeItem(IPC::Connection::Uniq

dispatchEvents(connection, storageAreaImplID, key, oldValue, String(), urlString);

if (m_cache) {
if (m_cache->items.remove(key)) {
CheckedUint64 newSize = m_cache->size;
newSize -= key.sizeInBytes();
newSize -= oldValue.sizeInBytes();
m_cache->size = newSize;
}
}
if (m_cache)
m_cache->remove(key);

return { };
}
Expand All @@ -416,13 +369,11 @@ Expected<void, StorageError> SQLiteStorageArea::clear(IPC::Connection::UniqueID
if (!prepareDatabase(ShouldCreateIfNotExists::No))
return makeUnexpected(StorageError::Database);

if (m_cache && m_cache->items.isEmpty())
if (m_cache && m_cache->isEmpty())
return makeUnexpected(StorageError::ItemNotFound);

if (m_cache) {
m_cache->items.clear();
m_cache->size = 0;
}
if (m_cache)
m_cache->clear();

if (!m_database)
return makeUnexpected(StorageError::ItemNotFound);
Expand Down
8 changes: 1 addition & 7 deletions Source/WebKit/NetworkProcess/storage/SQLiteStorageArea.h
Expand Up @@ -69,19 +69,13 @@ class SQLiteStorageArea final : public StorageAreaBase {
WebCore::SQLiteStatementAutoResetScope cachedStatement(StatementType);
Expected<String, StorageError> getItem(const String& key);
Expected<String, StorageError> getItemFromDatabase(const String& key);
Expected<HashMap<String, String>, StorageError> getAllItemsFromDatabase();
void initializeCache(const HashMap<String, String>&);

String m_path;
Ref<WorkQueue> m_queue;
std::unique_ptr<WebCore::SQLiteDatabase> m_database;
std::unique_ptr<WebCore::SQLiteTransaction> m_transaction;
Vector<std::unique_ptr<WebCore::SQLiteStatement>> m_cachedStatements;
struct Cache {
HashMap<String, String> items;
uint64_t size { 0 };
};
std::optional<Cache> m_cache;
std::optional<HashMap<String, String>> m_cache;
};

} // namespace WebKit
Expand Down

0 comments on commit 3c74389

Please sign in to comment.