susumu.yata
null+****@clear*****
Wed Apr 24 16:14:18 JST 2013
susumu.yata 2013-04-24 16:14:18 +0900 (Wed, 24 Apr 2013) New Revision: 9b5fd48a4d9ab5fbf63ebc8f97bc3d22b248cbd5 https://github.com/groonga/grnxx/commit/9b5fd48a4d9ab5fbf63ebc8f97bc3d22b248cbd5 Message: Implement a part of grnxx::Storage. Modified files: lib/grnxx/storage.cpp lib/grnxx/storage.hpp lib/grnxx/storage/file-posix.cpp lib/grnxx/storage/file-windows.cpp lib/grnxx/storage/header.hpp lib/grnxx/storage/storage_impl.cpp lib/grnxx/storage/storage_impl.hpp lib/grnxx/storage/view.hpp Modified: lib/grnxx/storage.cpp (+37 -3) =================================================================== --- lib/grnxx/storage.cpp 2013-04-24 14:30:45 +0900 (134e6a7) +++ lib/grnxx/storage.cpp 2013-04-24 16:14:18 +0900 (8d68dc7) @@ -22,6 +22,15 @@ #include "grnxx/string_builder.hpp" namespace grnxx { +namespace { + +constexpr uint32_t MAX_NUM_FILES_LOWER_LIMIT = 1; +constexpr uint32_t MAX_NUM_FILES_UPPER_LIMIT = 1000; +constexpr uint64_t MAX_FILE_SIZE_LOWER_LIMIT = 1ULL << 40; +constexpr uint64_t MAX_FILE_SIZE_UPPER_LIMIT = 1ULL << 30; +constexpr uint64_t ROOT_SIZE_DEFAULT = 1ULL << 12; + +} // namespace #define GRNXX_FLAGS_WRITE(flag) do { \ if (flags & flag) { \ @@ -64,9 +73,34 @@ StringBuilder &operator<<(StringBuilder &builder, StorageNodeStatus status) { } StorageOptions::StorageOptions() - : max_num_files(1000), - max_file_size(1ULL << 40), - root_size(4096) {} + : max_num_files(MAX_NUM_FILES_UPPER_LIMIT), + max_file_size(MAX_FILE_SIZE_UPPER_LIMIT), + root_size(ROOT_SIZE_DEFAULT) {} + +bool StorageOptions::is_valid() const { + if ((max_num_files < MAX_NUM_FILES_LOWER_LIMIT) || + (max_num_files > MAX_NUM_FILES_UPPER_LIMIT)) { + return false; + } + if ((max_file_size < MAX_FILE_SIZE_LOWER_LIMIT) || + (max_file_size > MAX_FILE_SIZE_UPPER_LIMIT)) { + return false; + } + if (root_size > max_file_size) { + return false; + } + return true; +} + +StringBuilder &operator<<(StringBuilder &builder, + const StorageOptions &options) { + if (!builder) { + return builder; + } + return builder << "{ max_num_files = " << options.max_num_files + << ", max_file_size = " << options.max_file_size + << ", root_size = " << options.root_size << " }"; +} uint32_t StorageNode::id() const { return header_->id; Modified: lib/grnxx/storage.hpp (+8 -1) =================================================================== --- lib/grnxx/storage.hpp 2013-04-24 14:30:45 +0900 (61a162c) +++ lib/grnxx/storage.hpp 2013-04-24 16:14:18 +0900 (7de8ab2) @@ -75,7 +75,7 @@ constexpr uint32_t STORAGE_INVALID_NODE_ID = storage::INVALID_NODE_ID; struct StorageOptions { // The maximum number of files. - uint64_t max_num_files; + uint32_t max_num_files; // The maximum size of each file. uint64_t max_file_size; // The size of the root node. @@ -83,8 +83,14 @@ struct StorageOptions { // Initialize the members with the default parameters. StorageOptions(); + + // Return true if the parameters are valid. + bool is_valid() const; }; +StringBuilder &operator<<(StringBuilder &builder, + const StorageOptions &options); + class StorageNode { public: StorageNode() = default; @@ -154,6 +160,7 @@ class Storage { virtual bool sweep(Duration lifetime) = 0; // Return the storage path. + // Note that an anonymous or temporary storage may return nullptr. virtual const char *path() const = 0; // Return the activated flags. virtual StorageFlags flags() const = 0; Modified: lib/grnxx/storage/file-posix.cpp (+1 -1) =================================================================== --- lib/grnxx/storage/file-posix.cpp 2013-04-24 14:30:45 +0900 (565d2be) +++ lib/grnxx/storage/file-posix.cpp 2013-04-24 16:14:18 +0900 (3cb6ed1) @@ -40,7 +40,7 @@ constexpr int UNIQUE_PATH_GENERATION_TRIAL_COUNT = 10; FileImpl::FileImpl() : File(), - path_(nullptr), + path_(), flags_(FILE_DEFAULT), fd_(-1), locked_(false) {} Modified: lib/grnxx/storage/file-windows.cpp (+1 -1) =================================================================== --- lib/grnxx/storage/file-windows.cpp 2013-04-24 14:30:45 +0900 (5ba505d) +++ lib/grnxx/storage/file-windows.cpp 2013-04-24 16:14:18 +0900 (9f2c034) @@ -37,7 +37,7 @@ constexpr int UNIQUE_PATH_GENERATION_TRIAL_COUNT = 10; FileImpl::FileImpl() : File(), - path_(nullptr), + path_(), flags_(FILE_DEFAULT), handle_(INVALID_HANDLE_VALUE), locked_(false) {} Modified: lib/grnxx/storage/header.hpp (+1 -1) =================================================================== --- lib/grnxx/storage/header.hpp 2013-04-24 14:30:45 +0900 (ac64a69) +++ lib/grnxx/storage/header.hpp 2013-04-24 16:14:18 +0900 (f3763c3) @@ -39,7 +39,7 @@ struct Header { // The grnxx version. char version[HEADER_VERSION_SIZE]; // The maximum number of files. - uint64_t max_num_files; + uint32_t max_num_files; // The maximum size of each file. uint64_t max_file_size; // The total size including headers. Modified: lib/grnxx/storage/storage_impl.cpp (+160 -10) =================================================================== --- lib/grnxx/storage/storage_impl.cpp 2013-04-24 14:30:45 +0900 (c88ae6d) +++ lib/grnxx/storage/storage_impl.cpp 2013-04-24 16:14:18 +0900 (669274b) @@ -17,30 +17,93 @@ */ #include "grnxx/storage/storage_impl.hpp" +#include "grnxx/logger.hpp" +#include "grnxx/storage/file.hpp" +#include "grnxx/storage/header.hpp" +#include "grnxx/storage/path.hpp" +#include "grnxx/storage/view.hpp" + namespace grnxx { namespace storage { +namespace { + +constexpr uint32_t MAX_NODE_ID = INVALID_NODE_ID - 1; + +// TODO: Define constant values. + +} // namespace + +StorageImpl::StorageImpl() + : Storage(), + path_(), + flags_(STORAGE_DEFAULT), + header_(nullptr), + files_(), + header_view_(), + node_header_views_(), + node_body_views_() {} -StorageImpl::StorageImpl() : Storage() {} StorageImpl::~StorageImpl() {} StorageImpl *StorageImpl::create(const char *path, StorageFlags flags, const StorageOptions &options) { - // TODO - return nullptr; + if (!options.is_valid()) { + GRNXX_ERROR() << "invalid argument: options = " << options; + return false; + } + std::unique_ptr<StorageImpl> storage(new (std::nothrow) StorageImpl); + if (!storage) { + GRNXX_ERROR() << "new grnxx::storage::StorageImpl failed"; + return nullptr; + } + if (path && (~flags & STORAGE_TEMPORARY)) { + storage->create_persistent_storage(path, flags, options); + } else if (flags & STORAGE_TEMPORARY) { + storage->create_temporary_storage(path, flags, options); + } else { + storage->create_anonymous_storage(flags, options); + } + return storage.release(); } StorageImpl *StorageImpl::open(const char *path, StorageFlags flags) { - // TODO - return nullptr; + if (!path) { + GRNXX_ERROR() << "invalid argument: path = nullptr"; + return nullptr; + } + std::unique_ptr<StorageImpl> storage(new (std::nothrow) StorageImpl); + if (!storage) { + GRNXX_ERROR() << "new grnxx::storage::StorageImpl failed"; + return nullptr; + } + if (!storage->open_storage(path, flags)) { + return nullptr; + } + return storage.release(); } StorageImpl *StorageImpl::open_or_create(const char *path, StorageFlags flags, const StorageOptions &options) { - // TODO - return nullptr; + if (!path) { + GRNXX_ERROR() << "invalid argument: path = nullptr"; + return nullptr; + } + if (!options.is_valid()) { + GRNXX_ERROR() << "invalid argument: options = " << options; + return false; + } + std::unique_ptr<StorageImpl> storage(new (std::nothrow) StorageImpl); + if (!storage) { + GRNXX_ERROR() << "new grnxx::storage::StorageImpl failed"; + return nullptr; + } + if (!storage->open_or_create_storage(path, flags, options)) { + return nullptr; + } + return storage.release(); } bool StorageImpl::exists(const char *path) { @@ -61,16 +124,35 @@ bool StorageImpl::unlink(const char *path) { } StorageNode StorageImpl::create_node(uint32_t parent_node_id, uint64_t size) { + if (parent_node_id >= header_->num_nodes) { + GRNXX_ERROR() << "invalid argument: parent_node_id = " << parent_node_id + << ", num_nodes = " << header_->num_nodes; + return StorageNode(nullptr, nullptr); + } else if (size > header_->max_file_size) { + GRNXX_ERROR() << "invalid argument: size = " << size + << ", max_file_size = " << header_->max_file_size; + return StorageNode(nullptr, nullptr); + } // TODO return StorageNode(nullptr, nullptr); } StorageNode StorageImpl::open_node(uint32_t node_id) { + if (node_id >= header_->num_nodes) { + GRNXX_ERROR() << "invalid argument: node_id = " << node_id + << ", num_nodes = " << header_->num_nodes; + return StorageNode(nullptr, nullptr); + } // TODO return StorageNode(nullptr, nullptr); } bool StorageImpl::unlink_node(uint32_t node_id) { + if (node_id >= header_->num_nodes) { + GRNXX_ERROR() << "invalid argument: node_id = " << node_id + << ", num_nodes = " << header_->num_nodes; + return false; + } // TODO return false; } @@ -81,13 +163,81 @@ bool StorageImpl::sweep(Duration lifetime) { } const char *StorageImpl::path() const { - // TODO - return nullptr; + return path_.get(); } StorageFlags StorageImpl::flags() const { + return flags_; +} + +bool StorageImpl::create_persistent_storage(const char *path, + StorageFlags flags, + const StorageOptions &options) { + path_.reset(Path::clone_path(path)); + if (!path_) { + return false; + } + if (flags & STORAGE_HUGE_TLB) { + flags_ |= STORAGE_HUGE_TLB; + } + // TODO + return false; +} + +bool StorageImpl::create_temporary_storage(const char *path, + StorageFlags flags, + const StorageOptions &options) { + if (path) { + path_.reset(Path::clone_path(path)); + if (!path_) { + return false; + } + } + flags_ |= STORAGE_TEMPORARY; + if (flags & STORAGE_HUGE_TLB) { + flags_ |= STORAGE_HUGE_TLB; + } // TODO - return STORAGE_DEFAULT; + return false; +} + +bool StorageImpl::create_anonymous_storage(StorageFlags flags, + const StorageOptions &options) { + flags_ |= STORAGE_ANONYMOUS; + if (flags & STORAGE_HUGE_TLB) { + flags_ |= STORAGE_HUGE_TLB; + } + // TODO + return false; +} + +bool StorageImpl::open_storage(const char *path, StorageFlags flags) { + path_.reset(Path::clone_path(path)); + if (!path_) { + return false; + } + if (flags & STORAGE_READ_ONLY) { + flags_ |= STORAGE_READ_ONLY; + } + if (flags & STORAGE_HUGE_TLB) { + flags_ |= STORAGE_HUGE_TLB; + } + // TODO + return false; +} + +bool StorageImpl::open_or_create_storage(const char *path, + StorageFlags flags, + const StorageOptions &options) { + path_.reset(Path::clone_path(path)); + if (!path_) { + return false; + } + if (flags & STORAGE_HUGE_TLB) { + flags_ |= STORAGE_HUGE_TLB; + } + // TODO + return false; } } // namespace storage Modified: lib/grnxx/storage/storage_impl.hpp (+21 -0) =================================================================== --- lib/grnxx/storage/storage_impl.hpp 2013-04-24 14:30:45 +0900 (0bca59e) +++ lib/grnxx/storage/storage_impl.hpp 2013-04-24 16:14:18 +0900 (895de63) @@ -23,6 +23,10 @@ namespace grnxx { namespace storage { +struct Header; +class File; +class View; + class StorageImpl : public Storage { public: StorageImpl(); @@ -53,6 +57,23 @@ class StorageImpl : public Storage { // TODO: Member functions to get details, such as total size, #nodes, etc. private: + std::unique_ptr<char[]> path_; + StorageFlags flags_; + Header *header_; + std::unique_ptr<std::unique_ptr<File>> files_; + std::unique_ptr<View> header_view_; + std::unique_ptr<std::unique_ptr<View>> node_header_views_; + std::unique_ptr<std::unique_ptr<View>> node_body_views_; + + bool create_persistent_storage(const char *path, StorageFlags flags, + const StorageOptions &options); + bool create_temporary_storage(const char *path, StorageFlags flags, + const StorageOptions &options); + bool create_anonymous_storage(StorageFlags flags, + const StorageOptions &options); + bool open_storage(const char *path, StorageFlags flags); + bool open_or_create_storage(const char *path, StorageFlags flags, + const StorageOptions &options); }; } // namespace storage Modified: lib/grnxx/storage/view.hpp (+2 -2) =================================================================== --- lib/grnxx/storage/view.hpp 2013-04-24 14:30:45 +0900 (999c37c) +++ lib/grnxx/storage/view.hpp 2013-04-24 16:14:18 +0900 (fcd9d8e) @@ -27,6 +27,8 @@ class StringBuilder; namespace storage { +class File; + class View; using ViewFlags = FlagsImpl<View>; @@ -43,8 +45,6 @@ constexpr ViewFlags VIEW_READ_ONLY = ViewFlags::define(0x04); StringBuilder &operator<<(StringBuilder &builder, ViewFlags flags); -class File; - class View { public: View(); -------------- next part -------------- HTML����������������������������...Download