Add new namespace to define a file path of a storage
This commit is contained in:
parent
77d66aaf3e
commit
8305d32eea
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
|
using namespace filesystem;
|
||||||
|
|
||||||
const int kNumNonTableCacheFiles = 10;
|
const int kNumNonTableCacheFiles = 10;
|
||||||
|
|
||||||
// Information kept for every waiting writer
|
// Information kept for every waiting writer
|
||||||
@ -132,6 +134,7 @@ DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
|
|||||||
owns_info_log_(options_.info_log != raw_options.info_log),
|
owns_info_log_(options_.info_log != raw_options.info_log),
|
||||||
owns_cache_(options_.block_cache != raw_options.block_cache),
|
owns_cache_(options_.block_cache != raw_options.block_cache),
|
||||||
dbname_(dbname),
|
dbname_(dbname),
|
||||||
|
path_(PathFactory::Create(dbname)),
|
||||||
table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
|
table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
|
||||||
db_lock_(nullptr),
|
db_lock_(nullptr),
|
||||||
shutting_down_(false),
|
shutting_down_(false),
|
||||||
@ -176,6 +179,9 @@ DBImpl::~DBImpl() {
|
|||||||
if (owns_cache_) {
|
if (owns_cache_) {
|
||||||
delete options_.block_cache;
|
delete options_.block_cache;
|
||||||
}
|
}
|
||||||
|
if (path_ != nullptr) {
|
||||||
|
delete path_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status DBImpl::NewDB() {
|
Status DBImpl::NewDB() {
|
||||||
@ -295,6 +301,10 @@ Status DBImpl::Recover(VersionEdit* edit, bool* save_manifest) {
|
|||||||
// Ignore error from CreateDir since the creation of the DB is
|
// Ignore error from CreateDir since the creation of the DB is
|
||||||
// committed only when the descriptor is created, and this directory
|
// committed only when the descriptor is created, and this directory
|
||||||
// may already exist from a previous failed creation attempt.
|
// may already exist from a previous failed creation attempt.
|
||||||
|
if (path_->IsDirectory()) {
|
||||||
|
path_->CreateDirectories();
|
||||||
|
}
|
||||||
|
|
||||||
env_->CreateDir(dbname_);
|
env_->CreateDir(dbname_);
|
||||||
assert(db_lock_ == nullptr);
|
assert(db_lock_ == nullptr);
|
||||||
Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);
|
Status s = env_->LockFile(LockFileName(dbname_), &db_lock_);
|
||||||
|
@ -17,9 +17,12 @@
|
|||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
#include "port/port.h"
|
#include "port/port.h"
|
||||||
#include "port/thread_annotations.h"
|
#include "port/thread_annotations.h"
|
||||||
|
#include "leveldb/filesystem.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
|
using namespace filesystem;
|
||||||
|
|
||||||
class MemTable;
|
class MemTable;
|
||||||
class TableCache;
|
class TableCache;
|
||||||
class Version;
|
class Version;
|
||||||
@ -162,7 +165,9 @@ class DBImpl : public DB {
|
|||||||
const Options options_; // options_.comparator == &internal_comparator_
|
const Options options_; // options_.comparator == &internal_comparator_
|
||||||
const bool owns_info_log_;
|
const bool owns_info_log_;
|
||||||
const bool owns_cache_;
|
const bool owns_cache_;
|
||||||
|
// TODO: replace with Path;
|
||||||
const std::string dbname_;
|
const std::string dbname_;
|
||||||
|
Path* const path_;
|
||||||
|
|
||||||
// table_cache_ provides its own synchronization
|
// table_cache_ provides its own synchronization
|
||||||
TableCache* const table_cache_;
|
TableCache* const table_cache_;
|
||||||
|
109
include/leveldb/filesystem.h
Normal file
109
include/leveldb/filesystem.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#ifndef STORAGE_LEVELDB_INCLUDE_FILE_SYSTEM_H_
|
||||||
|
#define STORAGE_LEVELDB_INCLUDE_FILE_SYSTEM_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "leveldb/export.h"
|
||||||
|
|
||||||
|
namespace leveldb {
|
||||||
|
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
bool IsDirectorySeparator(const char c);
|
||||||
|
|
||||||
|
class Path {
|
||||||
|
public:
|
||||||
|
// Constants
|
||||||
|
static const char kDirectorySeparator = '\\';
|
||||||
|
static const char kAltDirecttorySeparator = '/';
|
||||||
|
static const char kVolumeSeparatorChar = ':';
|
||||||
|
|
||||||
|
Path() : isDir_{false}, path_("") {}
|
||||||
|
Path(const std::string& path) : path_(path) {
|
||||||
|
isDir_ = !IsEmpty() && IsDirectorySeparator(path_[Size() - 1]);
|
||||||
|
}
|
||||||
|
virtual ~Path() {}
|
||||||
|
|
||||||
|
const std::string& ToString() const { return path_; }
|
||||||
|
const char* ToCString() const { return path_.c_str(); }
|
||||||
|
|
||||||
|
virtual bool IsAbsolute() const = 0;
|
||||||
|
virtual bool IsRelative() const = 0;
|
||||||
|
|
||||||
|
virtual bool CreateDirectories() = 0;
|
||||||
|
virtual bool CreateDirectory() = 0;
|
||||||
|
|
||||||
|
inline size_t Size() const { return path_.size(); }
|
||||||
|
inline bool IsEmpty() const { return path_.empty(); }
|
||||||
|
inline bool IsDirectory() const { return isDir_; }
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
|
||||||
|
inline bool HasExtension() {
|
||||||
|
if (!IsEmpty()) {
|
||||||
|
std::string::reverse_iterator& path_iter = path_.rbegin();
|
||||||
|
|
||||||
|
while (path_iter != path_.rend()) {
|
||||||
|
char c = *path_iter;
|
||||||
|
|
||||||
|
if (c == '.') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (IsDirectorySeparator(c)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool isDir_;
|
||||||
|
std::string path_;
|
||||||
|
|
||||||
|
virtual void Normalize() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef LEVELDB_PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
class WindowsFilePath : public Path {
|
||||||
|
public:
|
||||||
|
explicit WindowsFilePath(const std::string& path) : Path(path) {
|
||||||
|
Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
~WindowsFilePath() {}
|
||||||
|
|
||||||
|
bool IsAbsolute() const override;
|
||||||
|
bool IsRelative() const override;
|
||||||
|
|
||||||
|
bool CreateDirectories() override;
|
||||||
|
bool CreateDirectory() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Normalize() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool IsValidDriveChar(const char c) {
|
||||||
|
const char drive_char = std::toupper(c);
|
||||||
|
return drive_char >= 'A' && drive_char <= 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Factory
|
||||||
|
class PathFactory {
|
||||||
|
public:
|
||||||
|
static Path* Create(const std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PathFactory() {}
|
||||||
|
~PathFactory() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace filesystem
|
||||||
|
} // namespace leveldb
|
||||||
|
|
||||||
|
#endif // STORAGE_LEVELDB_INCLUDE_FILE_SYSTEM_H_
|
71
util/filesystem.cc
Normal file
71
util/filesystem.cc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include "leveldb/filesystem.h"
|
||||||
|
|
||||||
|
namespace leveldb {
|
||||||
|
namespace filesystem {
|
||||||
|
|
||||||
|
bool IsDirectorySeparator(const char c) {
|
||||||
|
return (c == Path::kDirectorySeparator || c == Path::kAltDirecttorySeparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path* PathFactory::Create(const std::string& path)
|
||||||
|
{
|
||||||
|
#ifdef LEVELDB_PLATFORM_WINDOWS
|
||||||
|
return new WindowsFilePath(path);
|
||||||
|
#elif LEVELDB_PLATFORM_POSIX
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef LEVELDB_PLATFORM_WINDOWS
|
||||||
|
|
||||||
|
bool WindowsFilePath::IsAbsolute() const {
|
||||||
|
return path_.size() >= 3 && IsValidDriveChar(path_[0]) &&
|
||||||
|
path_[1] == Path::kVolumeSeparatorChar;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool WindowsFilePath::IsRelative() const {
|
||||||
|
if (path_.size() < 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDirectorySeparator(path_[0])) {
|
||||||
|
if (path_[1] != '?') {
|
||||||
|
return !IsDirectorySeparator(path_[1]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (path_.size() >= 3 && path_[1] == Path::kVolumeSeparatorChar &&
|
||||||
|
IsDirectorySeparator(path_[2])) {
|
||||||
|
return IsValidDriveChar(path_[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void WindowsFilePath::Normalize() {
|
||||||
|
auto out = path_.begin();
|
||||||
|
|
||||||
|
for (const char c : path_) {
|
||||||
|
if (!IsDirectorySeparator(c)) {
|
||||||
|
*(out++) = c;
|
||||||
|
} else if (out == path_.begin() || IsDirectorySeparator(*std::prev(out))) {
|
||||||
|
*(out++) = Path::kDirectorySeparator;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path_.erase(out, path_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowsFilePath::CreateDirectories() { return true; }
|
||||||
|
|
||||||
|
bool WindowsFilePath::CreateDirectory() { return true; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user