Commit 525954c0 authored by Sigurdur Asgeirsson's avatar Sigurdur Asgeirsson Committed by Commit Bot

RC: Implement the GetDatabaseSize interface.

A subsequent CL will plumb this out to the chrome://discards page.

Bug: 874968
Change-Id: I18496f73a4a76cfe05151b67fb7cce4d9e256064
Reviewed-on: https://chromium-review.googlesource.com/1239002
Commit-Queue: Sigurður Ásgeirsson <siggi@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593607}
parent 68007209
......@@ -15,6 +15,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/task_runner_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "build/build_config.h"
#include "chrome/browser/resource_coordinator/utils.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
......@@ -84,6 +85,11 @@ bool ShouldAttemptDbRepair(const leveldb::Status& status) {
return false;
}
struct DatabaseSizeResult {
base::Optional<int64_t> num_rows;
base::Optional<int64_t> on_disk_size_kb;
};
} // namespace
// Version history:
......@@ -135,6 +141,8 @@ class LevelDBSiteCharacteristicsDatabase::AsyncHelper {
void RemoveSiteCharacteristicsFromDB(
const std::vector<url::Origin>& site_origin);
void ClearDatabase();
// Returns a struct with unset fields on failure.
DatabaseSizeResult GetDatabaseSize();
bool DBIsInitialized() { return db_ != nullptr; }
......@@ -295,6 +303,40 @@ void LevelDBSiteCharacteristicsDatabase::AsyncHelper::ClearDatabase() {
}
}
DatabaseSizeResult
LevelDBSiteCharacteristicsDatabase::AsyncHelper::GetDatabaseSize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!db_)
return DatabaseSizeResult();
base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
DatabaseSizeResult ret;
#if defined(OS_WIN)
// Windows has an annoying mis-feature that the size of an open file is not
// written to the parent directory until the file is closed. Since this is a
// diagnostic interface that should be rarely called, go to the trouble of
// closing and re-opening the database in order to get an up-to date size to
// report.
db_.reset();
#endif
ret.on_disk_size_kb = base::ComputeDirectorySize(db_path_) / 1024;
#if defined(OS_WIN)
OpenOrCreateDatabase();
if (!db_)
return DatabaseSizeResult();
#endif
// Default read options will fill the cache as we go.
std::unique_ptr<leveldb::Iterator> iterator(
db_->NewIterator(leveldb::ReadOptions()));
int64_t num_rows = 0;
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next())
++num_rows;
ret.num_rows = num_rows;
return ret;
}
LevelDBSiteCharacteristicsDatabase::AsyncHelper::OpeningType
LevelDBSiteCharacteristicsDatabase::AsyncHelper::OpenOrCreateDatabaseImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -408,6 +450,25 @@ void LevelDBSiteCharacteristicsDatabase::ClearDatabase() {
base::Unretained(async_helper_.get())));
}
void LevelDBSiteCharacteristicsDatabase::GetDatabaseSize(
GetDatabaseSizeCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Adapt the callback with a lambda to allow using PostTaskAndReplyWithResult.
auto reply_callback = base::BindOnce(
[](GetDatabaseSizeCallback callback, const DatabaseSizeResult& result) {
std::move(callback).Run(result.num_rows, result.on_disk_size_kb);
},
std::move(callback));
base::PostTaskAndReplyWithResult(
blocking_task_runner_.get(), FROM_HERE,
base::BindOnce(
&LevelDBSiteCharacteristicsDatabase::AsyncHelper::GetDatabaseSize,
base::Unretained(async_helper_.get())),
std::move(reply_callback));
}
bool LevelDBSiteCharacteristicsDatabase::DatabaseIsInitializedForTesting() {
return async_helper_->DBIsInitialized();
}
......
......@@ -42,6 +42,7 @@ class LevelDBSiteCharacteristicsDatabase
void RemoveSiteCharacteristicsFromDB(
const std::vector<url::Origin>& site_origins) override;
void ClearDatabase() override;
void GetDatabaseSize(GetDatabaseSizeCallback callback) override;
bool DatabaseIsInitializedForTesting();
......
......@@ -11,6 +11,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/test_file_util.h"
......@@ -122,10 +123,9 @@ class LevelDBSiteCharacteristicsDatabaseTest : public ::testing::Test {
}
// Add some entries to the database and returns a vector with their origins.
std::vector<url::Origin> AddDummyEntriesToDB() {
const size_t kEntryCount = 10;
std::vector<url::Origin> AddDummyEntriesToDB(size_t num_entries) {
std::vector<url::Origin> site_origins;
for (size_t i = 0; i < kEntryCount; ++i) {
for (size_t i = 0; i < num_entries; ++i) {
SiteCharacteristicsProto proto_temp;
std::string origin_str = base::StringPrintf("http://%zu.com", i);
InitSiteCharacteristicProto(&proto_temp,
......@@ -166,7 +166,7 @@ TEST_F(LevelDBSiteCharacteristicsDatabaseTest, InitAndStoreSiteCharacteristic) {
}
TEST_F(LevelDBSiteCharacteristicsDatabaseTest, RemoveEntries) {
std::vector<url::Origin> site_origins = AddDummyEntriesToDB();
std::vector<url::Origin> site_origins = AddDummyEntriesToDB(10);
// Remove half the origins from the database.
std::vector<url::Origin> site_origins_to_remove(
......@@ -195,8 +195,33 @@ TEST_F(LevelDBSiteCharacteristicsDatabaseTest, RemoveEntries) {
EXPECT_FALSE(ReadFromDB(iter, &proto_temp));
}
TEST_F(LevelDBSiteCharacteristicsDatabaseTest, GetDatabaseSize) {
std::vector<url::Origin> site_origins = AddDummyEntriesToDB(200);
auto size_callback =
base::BindLambdaForTesting([&](base::Optional<int64_t> num_rows,
base::Optional<int64_t> on_disk_size_kb) {
EXPECT_TRUE(num_rows);
// The DB contains an extra row for metadata.
int64_t expected_rows = site_origins.size() + 1;
EXPECT_EQ(expected_rows, num_rows.value());
EXPECT_TRUE(on_disk_size_kb);
EXPECT_LT(0, on_disk_size_kb.value());
});
db_->GetDatabaseSize(std::move(size_callback));
WaitForAsyncOperationsToComplete();
// Verify that the DB is still operational (see implementation detail
// for Windows).
SiteCharacteristicsProto read_proto;
EXPECT_TRUE(ReadFromDB(site_origins[0], &read_proto));
}
TEST_F(LevelDBSiteCharacteristicsDatabaseTest, DatabaseRecoveryTest) {
std::vector<url::Origin> site_origins = AddDummyEntriesToDB();
std::vector<url::Origin> site_origins = AddDummyEntriesToDB(10);
db_.reset();
......
......@@ -82,6 +82,11 @@ void NoopLocalSiteCharacteristicsDatabase::RemoveSiteCharacteristicsFromDB(
void NoopLocalSiteCharacteristicsDatabase::ClearDatabase() {}
void NoopLocalSiteCharacteristicsDatabase::GetDatabaseSize(
GetDatabaseSizeCallback callback) {
std::move(callback).Run(base::nullopt, base::nullopt);
}
ChromeTestHarnessWithLocalDB::ChromeTestHarnessWithLocalDB() {
scoped_feature_list_.InitAndEnableFeature(
features::kSiteCharacteristicsDatabase);
......
......@@ -72,6 +72,7 @@ class NoopLocalSiteCharacteristicsDatabase
void RemoveSiteCharacteristicsFromDB(
const std::vector<url::Origin>& site_origins) override;
void ClearDatabase() override;
void GetDatabaseSize(GetDatabaseSizeCallback callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(NoopLocalSiteCharacteristicsDatabase);
......
......@@ -25,6 +25,9 @@ class LocalSiteCharacteristicsDatabase {
// initialization has failed.
using ReadSiteCharacteristicsFromDBCallback = base::OnceCallback<void(
base::Optional<SiteCharacteristicsProto> site_characteristic_proto)>;
using GetDatabaseSizeCallback =
base::OnceCallback<void(base::Optional<int64_t> num_rows,
base::Optional<int64_t> on_disk_size_kb)>;
LocalSiteCharacteristicsDatabase() = default;
virtual ~LocalSiteCharacteristicsDatabase() {}
......@@ -48,6 +51,9 @@ class LocalSiteCharacteristicsDatabase {
// Clear the database, removes every entries that it contains.
virtual void ClearDatabase() = 0;
// Retrieve the size of the database.
virtual void GetDatabaseSize(GetDatabaseSizeCallback callback) = 0;
};
} // namespace resource_coordinator
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment