Index: sync/internal_api/model_type_store_backend.cc |
diff --git a/sync/internal_api/model_type_store_backend.cc b/sync/internal_api/model_type_store_backend.cc |
index dc4cf1f694739604c4c79e2f390e53588dbb2a52..ebe4118b0480d69143213da85b7844b85519b4ff 100644 |
--- a/sync/internal_api/model_type_store_backend.cc |
+++ b/sync/internal_api/model_type_store_backend.cc |
@@ -4,6 +4,17 @@ |
#include "sync/internal_api/public/model_type_store_backend.h" |
+#include "base/files/file_path.h" |
+#include "third_party/leveldatabase/env_chromium.h" |
+#include "third_party/leveldatabase/src/helpers/memenv/memenv.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/iterator.h" |
+#include "third_party/leveldatabase/src/include/leveldb/options.h" |
+#include "third_party/leveldatabase/src/include/leveldb/slice.h" |
+#include "third_party/leveldatabase/src/include/leveldb/status.h" |
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
+ |
namespace syncer_v2 { |
ModelTypeStoreBackend::ModelTypeStoreBackend() { |
@@ -16,9 +27,91 @@ ModelTypeStoreBackend::~ModelTypeStoreBackend() { |
DCHECK(CalledOnValidThread()); |
} |
-ModelTypeStore::Result ModelTypeStoreBackend::Init() { |
+scoped_ptr<leveldb::Env> ModelTypeStoreBackend::CreateInMemoryEnv() { |
+ return make_scoped_ptr(leveldb::NewMemEnv(leveldb::Env::Default())); |
+} |
+ |
+void ModelTypeStoreBackend::TakeEnvOwnership(scoped_ptr<leveldb::Env> env) { |
+ env_ = env.Pass(); |
+} |
+ |
+ModelTypeStore::Result ModelTypeStoreBackend::Init(const std::string& path, |
+ leveldb::Env* env) { |
+ DCHECK(CalledOnValidThread()); |
+ leveldb::DB* db_raw = nullptr; |
+ |
+ leveldb::Options options; |
+ options.create_if_missing = true; |
+ options.reuse_logs = leveldb_env::kDefaultLogReuseOptionValue; |
+ options.paranoid_checks = true; |
+ if (env) |
+ options.env = env; |
+ leveldb::Status status = leveldb::DB::Open(options, path, &db_raw); |
+ if (!status.ok()) { |
+ DCHECK(db_raw == nullptr); |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+ db_.reset(db_raw); |
+ return ModelTypeStore::Result::SUCCESS; |
+} |
+ |
+ModelTypeStore::Result ModelTypeStoreBackend::ReadRecordsWithPrefix( |
+ const std::string& prefix, |
+ const ModelTypeStore::IdList& id_list, |
+ ModelTypeStore::RecordList* record_list, |
+ ModelTypeStore::IdList* missing_id_list) { |
DCHECK(CalledOnValidThread()); |
+ DCHECK(db_); |
+ record_list->reserve(id_list.size()); |
+ leveldb::ReadOptions read_options; |
+ read_options.verify_checksums = true; |
+ std::string key; |
+ std::string value; |
+ for (const std::string& id : id_list) { |
+ key = prefix + id; |
+ leveldb::Status status = db_->Get(read_options, key, &value); |
+ if (status.ok()) { |
+ // TODO(pavely): Use emplace_back instead of push_back once it is allowed. |
+ record_list->push_back(ModelTypeStore::Record(id, value)); |
+ } else if (status.IsNotFound()) { |
+ missing_id_list->push_back(id); |
+ } else { |
+ return ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+ } |
+ } |
return ModelTypeStore::Result::SUCCESS; |
} |
+ModelTypeStore::Result ModelTypeStoreBackend::ReadAllRecordsWithPrefix( |
+ const std::string& prefix, |
+ ModelTypeStore::RecordList* record_list) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(db_); |
+ leveldb::ReadOptions read_options; |
+ read_options.verify_checksums = true; |
+ scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options)); |
+ const leveldb::Slice prefix_slice(prefix); |
+ for (iter->Seek(prefix_slice); iter->Valid(); iter->Next()) { |
+ leveldb::Slice key = iter->key(); |
+ if (!key.starts_with(prefix_slice)) |
+ break; |
+ key.remove_prefix(prefix_slice.size()); |
+ // TODO(pavely): Use emplace_back instead of push_back once it is allowed. |
+ record_list->push_back( |
+ ModelTypeStore::Record(key.ToString(), iter->value().ToString())); |
+ } |
+ return iter->status().ok() ? ModelTypeStore::Result::SUCCESS |
+ : ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+} |
+ |
+ModelTypeStore::Result ModelTypeStoreBackend::WriteModifications( |
+ scoped_ptr<leveldb::WriteBatch> write_batch) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(db_); |
+ leveldb::Status status = |
+ db_->Write(leveldb::WriteOptions(), write_batch.get()); |
+ return status.ok() ? ModelTypeStore::Result::SUCCESS |
+ : ModelTypeStore::Result::UNSPECIFIED_ERROR; |
+} |
+ |
} // namespace syncer_v2 |