Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: sync/internal_api/model_type_store_backend.cc

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "sync/internal_api/public/model_type_store_backend.h"
6
7 #include <utility>
8
9 #include "base/files/file_path.h"
10 #include "base/memory/ptr_util.h"
11 #include "third_party/leveldatabase/env_chromium.h"
12 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
13 #include "third_party/leveldatabase/src/include/leveldb/db.h"
14 #include "third_party/leveldatabase/src/include/leveldb/env.h"
15 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
16 #include "third_party/leveldatabase/src/include/leveldb/options.h"
17 #include "third_party/leveldatabase/src/include/leveldb/slice.h"
18 #include "third_party/leveldatabase/src/include/leveldb/status.h"
19 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
20
21 namespace syncer_v2 {
22
23 // static
24 base::LazyInstance<ModelTypeStoreBackend::BackendMap>
25 ModelTypeStoreBackend::backend_map_ = LAZY_INSTANCE_INITIALIZER;
26
27 ModelTypeStoreBackend::ModelTypeStoreBackend(const std::string& path)
28 : path_(path) {}
29
30 ModelTypeStoreBackend::~ModelTypeStoreBackend() {
31 backend_map_.Get().erase(path_);
32 }
33
34 std::unique_ptr<leveldb::Env> ModelTypeStoreBackend::CreateInMemoryEnv() {
35 return base::WrapUnique(leveldb::NewMemEnv(leveldb::Env::Default()));
36 }
37
38 // static
39 scoped_refptr<ModelTypeStoreBackend> ModelTypeStoreBackend::GetOrCreateBackend(
40 const std::string& path,
41 std::unique_ptr<leveldb::Env> env,
42 ModelTypeStore::Result* result) {
43 if (backend_map_.Get().find(path) != backend_map_.Get().end()) {
44 *result = ModelTypeStore::Result::SUCCESS;
45 return make_scoped_refptr(backend_map_.Get()[path]);
46 }
47
48 scoped_refptr<ModelTypeStoreBackend> backend =
49 new ModelTypeStoreBackend(path);
50
51 *result = backend->Init(path, std::move(env));
52
53 if (*result == ModelTypeStore::Result::SUCCESS) {
54 backend_map_.Get()[path] = backend.get();
55 } else {
56 backend = nullptr;
57 }
58
59 return backend;
60 }
61
62 ModelTypeStore::Result ModelTypeStoreBackend::Init(
63 const std::string& path,
64 std::unique_ptr<leveldb::Env> env) {
65 DFAKE_SCOPED_LOCK(push_pop_);
66 leveldb::DB* db_raw = nullptr;
67
68 leveldb::Options options;
69 options.create_if_missing = true;
70 options.reuse_logs = leveldb_env::kDefaultLogReuseOptionValue;
71 options.paranoid_checks = true;
72 if (env.get()) {
73 options.env = env.get();
74 env_ = std::move(env);
75 }
76
77 leveldb::Status status = leveldb::DB::Open(options, path, &db_raw);
78 if (!status.ok()) {
79 DCHECK(db_raw == nullptr);
80 return ModelTypeStore::Result::UNSPECIFIED_ERROR;
81 }
82 db_.reset(db_raw);
83 return ModelTypeStore::Result::SUCCESS;
84 }
85
86 ModelTypeStore::Result ModelTypeStoreBackend::ReadRecordsWithPrefix(
87 const std::string& prefix,
88 const ModelTypeStore::IdList& id_list,
89 ModelTypeStore::RecordList* record_list,
90 ModelTypeStore::IdList* missing_id_list) {
91 DFAKE_SCOPED_LOCK(push_pop_);
92 DCHECK(db_);
93 record_list->reserve(id_list.size());
94 leveldb::ReadOptions read_options;
95 read_options.verify_checksums = true;
96 std::string key;
97 std::string value;
98 for (const std::string& id : id_list) {
99 key = prefix + id;
100 leveldb::Status status = db_->Get(read_options, key, &value);
101 if (status.ok()) {
102 // TODO(pavely): Use emplace_back instead of push_back once it is allowed.
103 record_list->push_back(ModelTypeStore::Record(id, value));
104 } else if (status.IsNotFound()) {
105 missing_id_list->push_back(id);
106 } else {
107 return ModelTypeStore::Result::UNSPECIFIED_ERROR;
108 }
109 }
110 return ModelTypeStore::Result::SUCCESS;
111 }
112
113 ModelTypeStore::Result ModelTypeStoreBackend::ReadAllRecordsWithPrefix(
114 const std::string& prefix,
115 ModelTypeStore::RecordList* record_list) {
116 DFAKE_SCOPED_LOCK(push_pop_);
117 DCHECK(db_);
118 leveldb::ReadOptions read_options;
119 read_options.verify_checksums = true;
120 std::unique_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
121 const leveldb::Slice prefix_slice(prefix);
122 for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) {
123 leveldb::Slice key = iter->key();
124 if (!key.starts_with(prefix_slice))
125 break;
126 key.remove_prefix(prefix_slice.size());
127 // TODO(pavely): Use emplace_back instead of push_back once it is allowed.
128 record_list->push_back(
129 ModelTypeStore::Record(key.ToString(), iter->value().ToString()));
130 }
131 return iter->status().ok() ? ModelTypeStore::Result::SUCCESS
132 : ModelTypeStore::Result::UNSPECIFIED_ERROR;
133 }
134
135 ModelTypeStore::Result ModelTypeStoreBackend::WriteModifications(
136 std::unique_ptr<leveldb::WriteBatch> write_batch) {
137 DFAKE_SCOPED_LOCK(push_pop_);
138 DCHECK(db_);
139 leveldb::Status status =
140 db_->Write(leveldb::WriteOptions(), write_batch.get());
141 return status.ok() ? ModelTypeStore::Result::SUCCESS
142 : ModelTypeStore::Result::UNSPECIFIED_ERROR;
143 }
144
145 } // namespace syncer_v2
OLDNEW
« no previous file with comments | « sync/internal_api/model_type_connector_proxy_unittest.cc ('k') | sync/internal_api/model_type_store_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698