Commit d51c84ce authored by mek's avatar mek Committed by Commit bot

Start adding tests for LevelDBWrapper, and fix a bunch of bugs.

In particular this fixes:
- loading data from leveldb should strip the prefix from the keys
- writing data to leveldb should preprend the prefix to the keys
- CommitChanges should actually commit changes

BUG=586194

Review-Url: https://codereview.chromium.org/2583253002
Cr-Commit-Position: refs/heads/master@{#439849}
parent 52560eca
...@@ -124,9 +124,6 @@ class DOMStorageContextWrapper::MojoState { ...@@ -124,9 +124,6 @@ class DOMStorageContextWrapper::MojoState {
mojom::LevelDBObserverPtr observer, mojom::LevelDBObserverPtr observer,
mojom::LevelDBWrapperRequest request); mojom::LevelDBWrapperRequest request);
// Maps between an origin and its prefixed LevelDB view.
std::map<url::Origin, std::unique_ptr<LevelDBWrapperImpl>> level_db_wrappers_;
service_manager::Connector* const connector_; service_manager::Connector* const connector_;
const base::FilePath subdirectory_; const base::FilePath subdirectory_;
...@@ -146,6 +143,9 @@ class DOMStorageContextWrapper::MojoState { ...@@ -146,6 +143,9 @@ class DOMStorageContextWrapper::MojoState {
std::vector<base::Closure> on_database_opened_callbacks_; std::vector<base::Closure> on_database_opened_callbacks_;
// Maps between an origin and its prefixed LevelDB view.
std::map<url::Origin, std::unique_ptr<LevelDBWrapperImpl>> level_db_wrappers_;
base::WeakPtrFactory<MojoState> weak_ptr_factory_; base::WeakPtrFactory<MojoState> weak_ptr_factory_;
}; };
......
...@@ -55,7 +55,7 @@ LevelDBWrapperImpl::LevelDBWrapperImpl( ...@@ -55,7 +55,7 @@ LevelDBWrapperImpl::LevelDBWrapperImpl(
int max_bytes_per_hour, int max_bytes_per_hour,
int max_commits_per_hour, int max_commits_per_hour,
const base::Closure& no_bindings_callback) const base::Closure& no_bindings_callback)
: prefix_(prefix), : prefix_(leveldb::StdStringToUint8Vector(prefix)),
no_bindings_callback_(no_bindings_callback), no_bindings_callback_(no_bindings_callback),
database_(database), database_(database),
bytes_used_(0), bytes_used_(0),
...@@ -249,7 +249,7 @@ void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) { ...@@ -249,7 +249,7 @@ void LevelDBWrapperImpl::LoadMap(const base::Closure& completion_callback) {
return; return;
// TODO(michaeln): Import from sqlite localstorage db. // TODO(michaeln): Import from sqlite localstorage db.
database_->GetPrefixed(leveldb::StdStringToUint8Vector(prefix_), database_->GetPrefixed(prefix_,
base::Bind(&LevelDBWrapperImpl::OnLoadComplete, base::Bind(&LevelDBWrapperImpl::OnLoadComplete,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
...@@ -259,8 +259,11 @@ void LevelDBWrapperImpl::OnLoadComplete( ...@@ -259,8 +259,11 @@ void LevelDBWrapperImpl::OnLoadComplete(
std::vector<leveldb::mojom::KeyValuePtr> data) { std::vector<leveldb::mojom::KeyValuePtr> data) {
DCHECK(!map_); DCHECK(!map_);
map_.reset(new ValueMap); map_.reset(new ValueMap);
for (auto& it : data) for (auto& it : data) {
(*map_)[it->key] = it->value; DCHECK_GE(it->key.size(), prefix_.size());
(*map_)[std::vector<uint8_t>(it->key.begin() + prefix_.size(),
it->key.end())] = it->value;
}
// We proceed without using a backing store, nothing will be persisted but the // We proceed without using a backing store, nothing will be persisted but the
// class is functional for the lifetime of the object. // class is functional for the lifetime of the object.
...@@ -316,7 +319,7 @@ base::TimeDelta LevelDBWrapperImpl::ComputeCommitDelay() const { ...@@ -316,7 +319,7 @@ base::TimeDelta LevelDBWrapperImpl::ComputeCommitDelay() const {
void LevelDBWrapperImpl::CommitChanges() { void LevelDBWrapperImpl::CommitChanges() {
DCHECK(database_); DCHECK(database_);
if (commit_batch_) if (!commit_batch_)
return; return;
commit_rate_limiter_.add_samples(1); commit_rate_limiter_.add_samples(1);
...@@ -328,13 +331,15 @@ void LevelDBWrapperImpl::CommitChanges() { ...@@ -328,13 +331,15 @@ void LevelDBWrapperImpl::CommitChanges() {
leveldb::mojom::BatchedOperationPtr item = leveldb::mojom::BatchedOperationPtr item =
leveldb::mojom::BatchedOperation::New(); leveldb::mojom::BatchedOperation::New();
item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY; item->type = leveldb::mojom::BatchOperationType::DELETE_PREFIXED_KEY;
item->key = leveldb::StdStringToUint8Vector(prefix_); item->key = prefix_;
operations.push_back(std::move(item)); operations.push_back(std::move(item));
} }
for (auto& it : commit_batch_->changed_values) { for (auto& it : commit_batch_->changed_values) {
leveldb::mojom::BatchedOperationPtr item = leveldb::mojom::BatchedOperationPtr item =
leveldb::mojom::BatchedOperation::New(); leveldb::mojom::BatchedOperation::New();
item->key = std::move(it.first); item->key.reserve(prefix_.size() + it.first.size());
item->key.insert(item->key.end(), prefix_.begin(), prefix_.end());
item->key.insert(item->key.end(), it.first.begin(), it.first.end());
if (!it.second) { if (!it.second) {
item->type = leveldb::mojom::BatchOperationType::DELETE_KEY; item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
} else { } else {
......
...@@ -30,7 +30,7 @@ namespace content { ...@@ -30,7 +30,7 @@ namespace content {
// 2) Enforces a max_size constraint. // 2) Enforces a max_size constraint.
// 3) Informs observers when values scoped by prefix are modified. // 3) Informs observers when values scoped by prefix are modified.
// 4) Throttles requests to avoid overwhelming the disk. // 4) Throttles requests to avoid overwhelming the disk.
class LevelDBWrapperImpl : public mojom::LevelDBWrapper { class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
public: public:
// |no_bindings_callback| will be called when this object has no more // |no_bindings_callback| will be called when this object has no more
// bindings. // bindings.
...@@ -53,6 +53,8 @@ class LevelDBWrapperImpl : public mojom::LevelDBWrapper { ...@@ -53,6 +53,8 @@ class LevelDBWrapperImpl : public mojom::LevelDBWrapper {
static void EnableAggressiveCommitDelay(); static void EnableAggressiveCommitDelay();
private: private:
friend class LevelDBWrapperImplTest;
using ValueMap = std::map<std::vector<uint8_t>, std::vector<uint8_t>>; using ValueMap = std::map<std::vector<uint8_t>, std::vector<uint8_t>>;
using ChangedValueMap = using ChangedValueMap =
std::map<std::vector<uint8_t>, base::Optional<std::vector<uint8_t>>>; std::map<std::vector<uint8_t>, base::Optional<std::vector<uint8_t>>>;
...@@ -114,7 +116,7 @@ class LevelDBWrapperImpl : public mojom::LevelDBWrapper { ...@@ -114,7 +116,7 @@ class LevelDBWrapperImpl : public mojom::LevelDBWrapper {
void CommitChanges(); void CommitChanges();
void OnCommitComplete(leveldb::mojom::DatabaseError error); void OnCommitComplete(leveldb::mojom::DatabaseError error);
std::string prefix_; std::vector<uint8_t> prefix_;
mojo::BindingSet<mojom::LevelDBWrapper> bindings_; mojo::BindingSet<mojom::LevelDBWrapper> bindings_;
mojo::InterfacePtrSet<mojom::LevelDBObserver> observers_; mojo::InterfacePtrSet<mojom::LevelDBObserver> observers_;
base::Closure no_bindings_callback_; base::Closure no_bindings_callback_;
......
This diff is collapsed.
...@@ -1097,6 +1097,7 @@ test("content_unittests") { ...@@ -1097,6 +1097,7 @@ test("content_unittests") {
"../browser/indexed_db/mock_indexed_db_database_callbacks.h", "../browser/indexed_db/mock_indexed_db_database_callbacks.h",
"../browser/indexed_db/mock_indexed_db_factory.cc", "../browser/indexed_db/mock_indexed_db_factory.cc",
"../browser/indexed_db/mock_indexed_db_factory.h", "../browser/indexed_db/mock_indexed_db_factory.h",
"../browser/leveldb_wrapper_impl_unittest.cc",
"../browser/loader/async_resource_handler_unittest.cc", "../browser/loader/async_resource_handler_unittest.cc",
"../browser/loader/async_revalidation_driver_unittest.cc", "../browser/loader/async_revalidation_driver_unittest.cc",
"../browser/loader/async_revalidation_manager_unittest.cc", "../browser/loader/async_revalidation_manager_unittest.cc",
...@@ -1385,6 +1386,8 @@ test("content_unittests") { ...@@ -1385,6 +1386,8 @@ test("content_unittests") {
"//cc/ipc", "//cc/ipc",
"//cc/surfaces", "//cc/surfaces",
"//components/display_compositor", "//components/display_compositor",
"//components/leveldb/public/cpp",
"//components/leveldb/public/interfaces",
"//components/payments:payment_app", "//components/payments:payment_app",
"//components/rappor:test_support", "//components/rappor:test_support",
"//content:resources", "//content:resources",
......
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