Chromium Code Reviews| 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..96b4b8b94b992d315aff580dcd0c15a1bcbb1f1f |
| --- /dev/null |
| +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_store_impl.cc |
| @@ -0,0 +1,131 @@ |
| +// 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 |
|
bengr
2015/06/25 23:22:55
You can delete this line.
Not at Google. Contact bengr
2015/06/29 20:53:27
Having the 'else' will prevent you from adding to
Not at Google. Contact bengr
2015/07/01 17:13:48
Ignore above comment. Done.
|
| + 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() { |
|
michaeln
2015/06/26 20:15:01
What ensures this refcounted object isn't deleted
Not at Google. Contact bengr
2015/06/29 20:53:27
Added check for valid thread. Users of this class
|
| +} |
| + |
| +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(); |
|
michaeln
2015/06/26 20:15:01
What about incognito? Is this used for incognito p
Not at Google. Contact bengr
2015/06/29 20:53:27
No, data_reduction_proxy component does not run fo
|
| + 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 |