| Index: components/leveldb/env_mojo.cc
|
| diff --git a/components/leveldb/env_mojo.cc b/components/leveldb/env_mojo.cc
|
| index 82af93a997036fa73be861228083b196b93f85f9..178f7672747484dde25f81ebe2af1e5ad5d829ce 100644
|
| --- a/components/leveldb/env_mojo.cc
|
| +++ b/components/leveldb/env_mojo.cc
|
| @@ -8,7 +8,10 @@
|
|
|
| #include <memory>
|
|
|
| +#include "base/lazy_instance.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_util.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "third_party/leveldatabase/chromium_logger.h"
|
| #include "third_party/leveldatabase/src/include/leveldb/status.h"
|
| @@ -217,20 +220,35 @@ class MojoWritableFile : public leveldb::WritableFile {
|
|
|
| } // namespace
|
|
|
| -MojoEnv::MojoEnv(const std::string& name,
|
| - scoped_refptr<LevelDBMojoProxy> file_thread,
|
| - LevelDBMojoProxy::OpaqueDir* dir)
|
| - : ChromiumEnv(name), thread_(file_thread), dir_(dir) {}
|
| +MojoEnv::Directory::~Directory() {
|
| + env_->UnregisterDirectory(prefix_);
|
| +}
|
| +
|
| +MojoEnv::Directory::Directory(MojoEnv* env, std::string prefix)
|
| + : env_(env), prefix_(std::move(prefix)) {}
|
|
|
| -MojoEnv::~MojoEnv() {
|
| - thread_->UnregisterDirectory(dir_);
|
| +MojoEnv::MojoEnv(scoped_refptr<base::SingleThreadTaskRunner> file_task_runner)
|
| + : ChromiumEnv("LevelDBEnv.Mojo"),
|
| + thread_(new LevelDBMojoProxy(std::move(file_task_runner))) {}
|
| +
|
| +std::unique_ptr<MojoEnv::Directory> MojoEnv::RegisterDirectory(
|
| + filesystem::mojom::DirectoryPtr directory) {
|
| + LevelDBMojoProxy::OpaqueDir* dir =
|
| + thread_->RegisterDirectory(std::move(directory));
|
| + int dir_id = dirs_.Add(dir);
|
| + std::string prefix = base::StringPrintf("%d:", dir_id);
|
| + return base::WrapUnique(new Directory(this, prefix));
|
| }
|
|
|
| Status MojoEnv::NewSequentialFile(const std::string& fname,
|
| SequentialFile** result) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| base::File f = thread_->OpenFileHandle(
|
| - dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
|
| + dir, path, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
|
| if (!f.IsValid()) {
|
| *result = nullptr;
|
| return MakeIOError(fname, "Unable to create sequential file",
|
| @@ -244,105 +262,152 @@ Status MojoEnv::NewSequentialFile(const std::string& fname,
|
| Status MojoEnv::NewRandomAccessFile(const std::string& fname,
|
| RandomAccessFile** result) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| base::File f = thread_->OpenFileHandle(
|
| - dir_, fname, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen);
|
| + dir, path, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen);
|
| if (!f.IsValid()) {
|
| *result = nullptr;
|
| base::File::Error error_code = f.error_details();
|
| - return MakeIOError(fname, FileErrorString(error_code),
|
| + return MakeIOError(path, FileErrorString(error_code),
|
| leveldb_env::kNewRandomAccessFile, error_code);
|
| }
|
|
|
| - *result = new MojoRandomAccessFile(fname, std::move(f));
|
| + *result = new MojoRandomAccessFile(path, std::move(f));
|
| return Status::OK();
|
| }
|
|
|
| Status MojoEnv::NewWritableFile(const std::string& fname,
|
| WritableFile** result) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname);
|
| - base::File f =
|
| - thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kCreateAlways |
|
| - filesystem::mojom::kFlagWrite);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| + base::File f = thread_->OpenFileHandle(
|
| + dir, path,
|
| + filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite);
|
| if (!f.IsValid()) {
|
| *result = nullptr;
|
| - return MakeIOError(fname, "Unable to create writable file",
|
| + return MakeIOError(path, "Unable to create writable file",
|
| leveldb_env::kNewWritableFile, f.error_details());
|
| }
|
|
|
| - *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
|
| + *result = new MojoWritableFile(dir, path, std::move(f), thread_);
|
| return Status::OK();
|
| }
|
|
|
| Status MojoEnv::NewAppendableFile(const std::string& fname,
|
| WritableFile** result) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname);
|
| - base::File f =
|
| - thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kFlagOpenAlways |
|
| - filesystem::mojom::kFlagAppend);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| + base::File f = thread_->OpenFileHandle(
|
| + dir, path,
|
| + filesystem::mojom::kFlagOpenAlways | filesystem::mojom::kFlagAppend);
|
| if (!f.IsValid()) {
|
| *result = nullptr;
|
| - return MakeIOError(fname, "Unable to create appendable file",
|
| + return MakeIOError(path, "Unable to create appendable file",
|
| leveldb_env::kNewAppendableFile, f.error_details());
|
| }
|
|
|
| - *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
|
| + *result = new MojoWritableFile(dir, path, std::move(f), thread_);
|
| return Status::OK();
|
| }
|
|
|
| bool MojoEnv::FileExists(const std::string& fname) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname);
|
| - return thread_->FileExists(dir_, fname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| + return thread_->FileExists(dir, path);
|
| }
|
|
|
| -Status MojoEnv::GetChildren(const std::string& path,
|
| +Status MojoEnv::GetChildren(const std::string& dirname,
|
| std::vector<std::string>* result) {
|
| - TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
|
| - return FilesystemErrorToStatus(thread_->GetChildren(dir_, path, result), path,
|
| + TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "dirname", dirname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(dirname, &dir, &path);
|
| +
|
| + return FilesystemErrorToStatus(thread_->GetChildren(dir, path, result), path,
|
| leveldb_env::kGetChildren);
|
| }
|
|
|
| Status MojoEnv::DeleteFile(const std::string& fname) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
|
| - return FilesystemErrorToStatus(thread_->Delete(dir_, fname, 0), fname,
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| + return FilesystemErrorToStatus(thread_->Delete(dir, path, 0), path,
|
| leveldb_env::kDeleteFile);
|
| }
|
|
|
| Status MojoEnv::CreateDir(const std::string& dirname) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
|
| - return FilesystemErrorToStatus(thread_->CreateDir(dir_, dirname), dirname,
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(dirname, &dir, &path);
|
| +
|
| + return FilesystemErrorToStatus(thread_->CreateDir(dir, path), path,
|
| leveldb_env::kCreateDir);
|
| }
|
|
|
| Status MojoEnv::DeleteDir(const std::string& dirname) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(dirname, &dir, &path);
|
| +
|
| return FilesystemErrorToStatus(
|
| - thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive),
|
| - dirname, leveldb_env::kDeleteDir);
|
| + thread_->Delete(dir, path, filesystem::mojom::kDeleteFlagRecursive), path,
|
| + leveldb_env::kDeleteDir);
|
| }
|
|
|
| Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
|
| - return FilesystemErrorToStatus(thread_->GetFileSize(dir_, fname, file_size),
|
| - fname,
|
| - leveldb_env::kGetFileSize);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| + return FilesystemErrorToStatus(thread_->GetFileSize(dir, path, file_size),
|
| + path, leveldb_env::kGetFileSize);
|
| }
|
|
|
| Status MojoEnv::RenameFile(const std::string& src, const std::string& target) {
|
| TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target);
|
| - return FilesystemErrorToStatus(thread_->RenameFile(dir_, src, target), src,
|
| - leveldb_env::kRenameFile);
|
| + LevelDBMojoProxy::OpaqueDir* src_dir;
|
| + std::string src_path;
|
| + ParsePath(src, &src_dir, &src_path);
|
| + LevelDBMojoProxy::OpaqueDir* target_dir;
|
| + std::string target_path;
|
| + ParsePath(target, &target_dir, &target_path);
|
| + DCHECK_EQ(src_dir, target_dir);
|
| +
|
| + return FilesystemErrorToStatus(
|
| + thread_->RenameFile(src_dir, src_path, target_path), src_path,
|
| + leveldb_env::kRenameFile);
|
| }
|
|
|
| Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
|
|
| std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p =
|
| - thread_->LockFile(dir_, fname);
|
| + thread_->LockFile(dir, path);
|
|
|
| if (p.second)
|
| *lock = new MojoFileLock(p.second, fname);
|
|
|
| - return FilesystemErrorToStatus(p.first, fname, leveldb_env::kLockFile);
|
| + return FilesystemErrorToStatus(p.first, path, leveldb_env::kLockFile);
|
| }
|
|
|
| Status MojoEnv::UnlockFile(FileLock* lock) {
|
| @@ -368,12 +433,16 @@ Status MojoEnv::GetTestDirectory(std::string* path) {
|
|
|
| Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
|
| TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname);
|
| + LevelDBMojoProxy::OpaqueDir* dir;
|
| + std::string path;
|
| + ParsePath(fname, &dir, &path);
|
| +
|
| base::File f(thread_->OpenFileHandle(
|
| - dir_, fname,
|
| + dir, path,
|
| filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite));
|
| if (!f.IsValid()) {
|
| *result = NULL;
|
| - return MakeIOError(fname, "Unable to create log file",
|
| + return MakeIOError(path, "Unable to create log file",
|
| leveldb_env::kNewLogger, f.error_details());
|
| } else {
|
| *result = new leveldb::ChromiumLogger(std::move(f));
|
| @@ -381,4 +450,35 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
|
| }
|
| }
|
|
|
| +MojoEnv::~MojoEnv() {}
|
| +
|
| +void MojoEnv::ParsePath(const std::string& path,
|
| + LevelDBMojoProxy::OpaqueDir** out_dir,
|
| + std::string* out_path) {
|
| + size_t colon_pos = path.find(':');
|
| + DCHECK_NE(colon_pos, std::string::npos);
|
| +
|
| + int dir_id;
|
| + bool result = base::StringToInt(
|
| + base::StringPiece(path.begin(), path.begin() + colon_pos), &dir_id);
|
| + DCHECK(result) << "Invalid directory id in path '" << path << "'";
|
| + *out_dir = dirs_.Lookup(dir_id);
|
| + DCHECK(*out_dir) << "Invalid directory id " << dir_id;
|
| +
|
| + *out_path = std::string(path.begin() + colon_pos + 1, path.end());
|
| +}
|
| +
|
| +void MojoEnv::UnregisterDirectory(base::StringPiece prefix) {
|
| + DCHECK(!prefix.empty());
|
| + DCHECK_EQ(prefix.back(), ':');
|
| + prefix.remove_suffix(1);
|
| + int dir_id;
|
| + bool result = base::StringToInt(prefix, &dir_id);
|
| + DCHECK(result) << "Invalid directory id '" << prefix << "'";
|
| + LevelDBMojoProxy::OpaqueDir* dir = dirs_.Lookup(dir_id);
|
| + DCHECK(dir) << "Invalid directory id " << dir_id;
|
| + dirs_.Remove(dir_id);
|
| + thread_->UnregisterDirectory(dir);
|
| +}
|
| +
|
| } // namespace leveldb
|
|
|