| Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.cc
|
| diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..eb08827a915065151c1b414e545f807abed2d228
|
| --- /dev/null
|
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.cc
|
| @@ -0,0 +1,132 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.h"
|
| +
|
| +#include "base/files/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/ref_counted.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| +#include "components/data_reduction_proxy/proto/store.pb.h"
|
| +#include "third_party/leveldatabase/env_chromium.h"
|
| +#include "third_party/leveldatabase/src/include/leveldb/db.h"
|
| +#include "third_party/leveldatabase/src/include/leveldb/env.h"
|
| +#include "third_party/leveldatabase/src/include/leveldb/options.h"
|
| +#include "third_party/leveldatabase/src/include/leveldb/status.h"
|
| +#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
|
| +
|
| +namespace {
|
| +
|
| +const base::FilePath::CharType kDBName[] =
|
| + FILE_PATH_LITERAL("data_reduction_proxy_leveldb");
|
| +
|
| +data_reduction_proxy::DataReductionProxyStore::Status LevelDbToDRPStoreStatus(
|
| + leveldb::Status leveldb_status) {
|
| + if (leveldb_status.ok())
|
| + return data_reduction_proxy::DataReductionProxyStore::Status::OK;
|
| + else if (leveldb_status.IsNotFound())
|
| + return data_reduction_proxy::DataReductionProxyStore::Status::NOT_FOUND;
|
| + else if (leveldb_status.IsCorruption())
|
| + return data_reduction_proxy::DataReductionProxyStore::Status::CORRUPTED;
|
| + else if (leveldb_status.IsIOError())
|
| + return data_reduction_proxy::DataReductionProxyStore::Status::IO_ERROR;
|
| + else
|
| + return data_reduction_proxy::DataReductionProxyStore::Status::MISC_ERROR;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace data_reduction_proxy {
|
| +
|
| +DataReductionProxyStoreImpl::DataReductionProxyStoreImpl(
|
| + const base::FilePath& profile_path)
|
| + : profile_path_(profile_path) {
|
| + thread_checker_.DetachFromThread();
|
| +}
|
| +
|
| +void DataReductionProxyStoreImpl::InitializeOnDBThread() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + DCHECK(!db_);
|
| +
|
| + DataReductionProxyStore::Status status = OpenDB();
|
| + if (status == CORRUPTED)
|
| + RecreateDB();
|
| +}
|
| +
|
| +DataReductionProxyStore::Status DataReductionProxyStoreImpl::Get(
|
| + const std::string& key,
|
| + std::string* value) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (db_.get() == nullptr) {
|
| + return MISC_ERROR;
|
| + }
|
| +
|
| + leveldb::ReadOptions read_options;
|
| + read_options.verify_checksums = true;
|
| + leveldb::Slice slice(key);
|
| + leveldb::Status status = db_->Get(read_options, slice, value);
|
| + if (status.IsCorruption())
|
| + RecreateDB();
|
| +
|
| + return LevelDbToDRPStoreStatus(status);
|
| +}
|
| +
|
| +DataReductionProxyStore::Status DataReductionProxyStoreImpl::Put(
|
| + const std::map<std::string, std::string>& map) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + if (db_.get() == nullptr) {
|
| + return MISC_ERROR;
|
| + }
|
| +
|
| + leveldb::WriteBatch batch;
|
| + for (const auto& iter : map) {
|
| + leveldb::Slice key_slice(iter.first);
|
| + leveldb::Slice value_slice(iter.second);
|
| + batch.Put(key_slice, value_slice);
|
| + }
|
| +
|
| + leveldb::WriteOptions write_options;
|
| + leveldb::Status status = db_->Write(write_options, &batch);
|
| + if (status.IsCorruption())
|
| + RecreateDB();
|
| +
|
| + return LevelDbToDRPStoreStatus(status);
|
| +}
|
| +
|
| +DataReductionProxyStoreImpl::~DataReductionProxyStoreImpl() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +}
|
| +
|
| +DataReductionProxyStore::Status DataReductionProxyStoreImpl::OpenDB() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + leveldb::Options options;
|
| + options.create_if_missing = true;
|
| + options.paranoid_checks = true;
|
| + options.reuse_logs = leveldb_env::kDefaultLogReuseOptionValue;
|
| + std::string db_name = profile_path_.Append(kDBName).AsUTF8Unsafe();
|
| + leveldb::DB* dbptr = nullptr;
|
| + Status status =
|
| + LevelDbToDRPStoreStatus(leveldb::DB::Open(options, db_name, &dbptr));
|
| + UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.LevelDBOpenStatus", status,
|
| + STATUS_MAX);
|
| +
|
| + if (status != OK)
|
| + LOG(ERROR) << "Failed to open Data Reduction Proxy DB: " << status;
|
| +
|
| + db_.reset(dbptr);
|
| + return status;
|
| +}
|
| +
|
| +void DataReductionProxyStoreImpl::RecreateDB() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + LOG(WARNING) << "Deleting corrupt Data Reduction Proxy LevelDB";
|
| + db_.reset(nullptr);
|
| + base::DeleteFile(profile_path_.Append(kDBName), true);
|
| +
|
| + OpenDB();
|
| +}
|
| +
|
| +} // namespace data_reduction_proxy
|
|
|