susumu.yata
null+****@clear*****
Tue Apr 23 17:53:19 JST 2013
susumu.yata 2013-04-23 17:53:19 +0900 (Tue, 23 Apr 2013) New Revision: 0fb80a7bc29629c1293f3550250af86344bc6dfb https://github.com/groonga/grnxx/commit/0fb80a7bc29629c1293f3550250af86344bc6dfb Message: Update the interface of grnxx::Storage. Added files: lib/grnxx/storage/node_header.hpp Copied files: lib/grnxx/storage/node_header.cpp (from lib/grnxx/storage/view.cpp) Modified files: lib/grnxx/storage.cpp lib/grnxx/storage.hpp lib/grnxx/storage/Makefile.am lib/grnxx/storage/file.cpp lib/grnxx/storage/file.hpp lib/grnxx/storage/view.cpp lib/grnxx/storage/view.hpp Modified: lib/grnxx/storage.cpp (+65 -19) =================================================================== --- lib/grnxx/storage.cpp 2013-04-23 13:33:25 +0900 (1bf05c5) +++ lib/grnxx/storage.cpp 2013-04-23 17:53:19 +0900 (0986e58) @@ -17,28 +17,74 @@ */ #include "grnxx/storage.hpp" +#include "grnxx/storage/node_header.hpp" + namespace grnxx { +#define GRNXX_FLAGS_WRITE(flag) do { \ + if (flags & flag) { \ + if (!is_first) { \ + builder << " | "; \ + } \ + builder << #flag; \ + is_first = false; \ + } \ +} while (false) + +StringBuilder &operator<<(StringBuilder &builder, StorageFlags flags) { + bool is_first = true; + GRNXX_FLAGS_WRITE(STORAGE_ANONYMOUS); + GRNXX_FLAGS_WRITE(STORAGE_HUGE_TLB); + GRNXX_FLAGS_WRITE(STORAGE_READ_ONLY); + GRNXX_FLAGS_WRITE(STORAGE_TEMPORARY); + if (is_first) { + builder << "STORAGE_DEFAULT"; + } + return builder; +} + +#define GRNXX_STATUS_CASE(status) \ + case status: { \ + return builder << #status; \ + } + +StringBuilder &operator<<(StringBuilder &builder, StorageNodeStatus status) { + switch (status) { + GRNXX_STATUS_CASE(STORAGE_NODE_PHANTOM) + GRNXX_STATUS_CASE(STORAGE_NODE_ACTIVE) + GRNXX_STATUS_CASE(STORAGE_NODE_MARKED) + GRNXX_STATUS_CASE(STORAGE_NODE_UNLINKED) + GRNXX_STATUS_CASE(STORAGE_NODE_IDLE) + default: { + return builder << "n/a"; + } + } +} + StorageOptions::StorageOptions() - : max_num_files(1000), - max_file_size(1ULL << 40), - chunk_size_ratio(1.0 / 64), - root_size(4096) {} - -StorageNodeHeader::StorageNodeHeader() - : id(0), - status(STORAGE_PHANTOM), - bits(0), - chunk_id(0), - offset(0), - size(0), - next_node_id(0), - prev_node_id(0), - next_phantom_node_id(0), - sibling_node_id(0), - last_modified_time(0), - reserved{}, - user_data{} {} + : max_num_files(1000), + max_file_size(1ULL << 40), + root_size(4096) {} + +uint32_t StorageNode::id() const { + return header_->id; +} + +StorageNodeStatus StorageNode::status() const { + return header_->status; +} + +uint64_t StorageNode::size() const { + return header_->size << header_->bits; +} + +Time StorageNode::modified_time() const { + return header_->modified_time; +} + +void *StorageNode::user_data() const { + return header_->user_data; +} Storage::Storage() {} Storage::~Storage() {} Modified: lib/grnxx/storage.hpp (+71 -104) =================================================================== --- lib/grnxx/storage.hpp 2013-04-23 13:33:25 +0900 (a8649a4) +++ lib/grnxx/storage.hpp 2013-04-23 17:53:19 +0900 (eff9a57) @@ -22,113 +22,51 @@ #include "grnxx/time/time.hpp" namespace grnxx { +namespace storage { -enum StorageNodeStatus : uint8_t { - // A node without body. - STORAGE_PHANTOM = 0, - // An active node. - STORAGE_ACTIVE = 1, - // A marked node to be unlinked. - STORAGE_MARKED = 2, - // An unlinked node. - STORAGE_UNLINKED = 3, - // An unused node. - STORAGE_IDLE = 4, -}; - -struct StorageNodeHeader { - // The ID of this node. - uint32_t id; - // The status of this node. - StorageNodeStatus status; - // (Non-phantom) - // For calculating the actual offset and size, see also "offset" and "size". - uint8_t bits; - // (Non-phantom) - // The ID of the chunk to which this node belongs. - uint16_t chunk_id; - // (Non-phantom) - // The offset of this node in chunk. - // The actual offset is "offset" << "bits". - uint32_t offset; - // (Non-phantom) - // The size of this node. The actual size is "size" << "bits". - uint32_t size; - // (Non-phantom) - // The ID of the next node in chunk. - // INVALID_ID indicates that this node is the last node in chunk. - uint32_t next_node_id; - // (Non-phantom) - // The ID of the previous node in chunk. - // INVALID_ID indicates that this node is the first node in chunk. - uint32_t prev_node_id; - union { - // (Phantom) - // The ID of the next phantom node. - uint32_t next_phantom_node_id; - // (Active, marked, or unlinked) - // The ID of the latest child node. - // INVALID_ID indicates that this node has no children. - uint32_t child_id; - // (Idle) - // The ID of the next idle node. - uint32_t next_idle_node_id; - }; - union { - // (Active or marked) - // The ID of the next sibling node. - // INVALID_ID indicates that this node has no elder siblings. - uint32_t sibling_node_id; - // (Unlinked) - // The ID of the next unlinked node. - // INVALID_ID indicates that this node is the last unlinked node. - uint32_t next_unlinked_node_id; - // (Idle) - // The ID of the previous idle node. - uint32_t prev_idle_node_id; - }; - // The time of the last modification. - Time last_modified_time; - // Reserved for future use. - uint8_t reserved[8]; - // User data. - uint8_t user_data[16]; - - // Initialize the members. - StorageNodeHeader(); -}; +struct NodeHeader; -static_assert(sizeof(StorageNodeHeader) == 64, - "sizeof(StorageNodeHeader) != 64"); - -struct StorageNode { - // The address to the node header. - StorageNodeHeader *header; - // The address to the node body. - void *body; -}; +} // namespace storage class Storage; -typedef FlagsImpl<Storage> StorageFlags; +using StorageFlags = FlagsImpl<Storage>; // Use the default settings. constexpr StorageFlags STORAGE_DEFAULT = StorageFlags::define(0x00); +// Create an anonymous storage. +// This flag is implicitly enabled if "path" == nullptr and "flags" does not +// contain STORAGE_TEMPORARY. +constexpr StorageFlags STORAGE_ANONYMOUS = StorageFlags::define(0x01); // Use huge pages if available, or use regular pages. -constexpr StorageFlags STORAGE_HUGE_TLB = StorageFlags::define(0x01); +constexpr StorageFlags STORAGE_HUGE_TLB = StorageFlags::define(0x02); // Open a storage in read-only mode. // If not specified, a storage is opened in read-write mode. -constexpr StorageFlags STORAGE_READ_ONLY = StorageFlags::define(0x02); -// Create an anonymous (non-file-backed) temporary storage if "path" == -// nullptr, or create a file-backed temporary storage. -constexpr StorageFlags STORAGE_TEMPORARY = StorageFlags::define(0x04); +constexpr StorageFlags STORAGE_READ_ONLY = StorageFlags::define(0x04); +// Create a file-backed temporary storage. +constexpr StorageFlags STORAGE_TEMPORARY = StorageFlags::define(0x08); + +StringBuilder &operator<<(StringBuilder &builder, StorageFlags flags); + +enum StorageNodeStatus : uint8_t { + // A node without body. + STORAGE_NODE_PHANTOM = 0, + // An active node. + STORAGE_NODE_ACTIVE = 1, + // A marked node to be unlinked. + STORAGE_NODE_MARKED = 2, + // An unlinked node. + STORAGE_NODE_UNLINKED = 3, + // An unused node. + STORAGE_NODE_IDLE = 4 +}; + +StringBuilder &operator<<(StringBuilder &builder, StorageNodeStatus status); struct StorageOptions { // The maximum number of files. uint64_t max_num_files; // The maximum size of each file. uint64_t max_file_size; - // The ratio of the new chunk size to the storage total size. - double chunk_size_ratio; // The size of the root node. uint64_t root_size; @@ -136,11 +74,35 @@ struct StorageOptions { StorageOptions(); }; -struct StorageHeader { - // TODO +using StorageNodeHeader = storage::NodeHeader; - // Initialize the members. - StorageHeader(); +struct StorageNode { + public: + StorageNode() = default; + StorageNode(StorageNodeHeader *header, void *body) + : header_(header), + body_(body) {} + + // Return the ID. + uint32_t id() const; + // Return the status. + StorageNodeStatus status() const; + // Return the body size. + uint64_t size() const; + // Return the last modified time. + Time modified_time() const; + // Return the address to the user data (16 bytes) in the header. + void *user_data() const; + // Return the address to the body. + void *body() const { + return body_; + } + + private: + // The address to the node header. + StorageNodeHeader *header_; + // The address to the node body. + void *body_; }; class Storage { @@ -149,7 +111,8 @@ class Storage { virtual ~Storage(); // Create a storage. - // "path" == nullptr is acceptable iff "flags" contains STORAGE_TEMPORARY. + // STORAGE_ANONYMOUS is implicitly enabled if "path" == nullptr and "flags" + // does not contain STORAGE_TEMPORARY. // Available flags are STORAGE_HUGE_TLB and STORAGE_TEMPORARY. static Storage *create(const char *path, StorageFlags flags = STORAGE_DEFAULT, @@ -173,25 +136,29 @@ class Storage { static constexpr uint32_t root_id() { return 0U; } - // Return an invalid ID. + // Return the invalid node ID. static constexpr uint32_t invalid_id() { return std::numeric_limits<uint32_t>::max(); } - // Return the address to the header. - virtual const StorageHeader *header() const = 0; - + // Create a node of at least "size" bytes under the specified parent node. + virtual StorageNode create_node(uint32_t parent_node_id, uint64_t size) = 0; // Open a node. virtual StorageNode open_node(uint32_t node_id) = 0; - // Create a node of at least "size" bytes under "parent_node". - virtual StorageNode create_node(const StorageNode &parent_node, - uint64_t size) = 0; + // Mark a node to be unlinked. Note that the marked node and its descendants // will be unlinked by sweep(). - virtual bool unlink_node(const StorageNode &node) = 0; + virtual bool unlink_node(uint32_t node_id) = 0; // Sweep marked nodes whose last modified time < (now - lifetime). virtual void sweep(Duration lifetime) = 0; + + // Return the storage path. + virtual const char *path() const = 0; + // Return the activated flags. + virtual StorageFlags flags() const = 0; + + // TODO: Member functions to get details, such as total size, #nodes, etc. }; } // namespace grnxx Modified: lib/grnxx/storage/Makefile.am (+4 -2) =================================================================== --- lib/grnxx/storage/Makefile.am 2013-04-23 13:33:25 +0900 (c94aee2) +++ lib/grnxx/storage/Makefile.am 2013-04-23 17:53:19 +0900 (459fca7) @@ -9,7 +9,8 @@ libgrnxx_storage_la_SOURCES = \ path.cpp \ view.cpp \ view-posix.cpp \ - view-windows.cpp + view-windows.cpp \ + node_header.cpp libgrnxx_storage_includedir = ${includedir}/grnxx/storage libgrnxx_storage_include_HEADERS = \ @@ -19,4 +20,5 @@ libgrnxx_storage_include_HEADERS = \ path.hpp \ view.hpp \ view-posix.hpp \ - view-windows.hpp + view-windows.hpp \ + node_header.hpp Modified: lib/grnxx/storage/file.cpp (+13 -15) =================================================================== --- lib/grnxx/storage/file.cpp 2013-04-23 13:33:25 +0900 (90fbed1) +++ lib/grnxx/storage/file.cpp 2013-04-23 17:53:19 +0900 (601b114) @@ -35,26 +35,24 @@ namespace storage { } while (false) StringBuilder &operator<<(StringBuilder &builder, FileFlags flags) { - if (flags) { - bool is_first = true; - GRNXX_FLAGS_WRITE(FILE_READ_ONLY); - GRNXX_FLAGS_WRITE(FILE_TEMPORARY); - return builder; - } else { - return builder << "FILE_DEFAULT"; + bool is_first = true; + GRNXX_FLAGS_WRITE(FILE_READ_ONLY); + GRNXX_FLAGS_WRITE(FILE_TEMPORARY); + if (is_first) { + builder << "FILE_DEFAULT"; } + return builder; } StringBuilder &operator<<(StringBuilder &builder, FileLockFlags flags) { - if (flags) { - bool is_first = true; - GRNXX_FLAGS_WRITE(FILE_LOCK_SHARED); - GRNXX_FLAGS_WRITE(FILE_LOCK_EXCLUSIVE); - GRNXX_FLAGS_WRITE(FILE_LOCK_NONBLOCKING); - return builder; - } else { - return builder << "0"; + bool is_first = true; + GRNXX_FLAGS_WRITE(FILE_LOCK_SHARED); + GRNXX_FLAGS_WRITE(FILE_LOCK_EXCLUSIVE); + GRNXX_FLAGS_WRITE(FILE_LOCK_NONBLOCKING); + if (is_first) { + builder << "0"; } + return builder; } File::File() {} Modified: lib/grnxx/storage/file.hpp (+2 -2) =================================================================== --- lib/grnxx/storage/file.hpp 2013-04-23 13:33:25 +0900 (d788a75) +++ lib/grnxx/storage/file.hpp 2013-04-23 17:53:19 +0900 (6b08716) @@ -28,7 +28,7 @@ class StringBuilder; namespace storage { class File; -typedef FlagsImpl<File> FileFlags; +using FileFlags = FlagsImpl<File>; // Use the default settings. constexpr FileFlags FILE_DEFAULT = FileFlags::define(0x00); @@ -41,7 +41,7 @@ constexpr FileFlags FILE_TEMPORARY = FileFlags::define(0x02); StringBuilder &operator<<(StringBuilder &builder, FileFlags flags); class FileLock; -typedef FlagsImpl<FileLock> FileLockFlags; +using FileLockFlags = FlagsImpl<FileLock>; // Apply an exclusive advisory lock. constexpr FileLockFlags FILE_LOCK_SHARED = FileLockFlags::define(0x01); Copied: lib/grnxx/storage/node_header.cpp (+15 -33) 51% =================================================================== --- lib/grnxx/storage/view.cpp 2013-04-23 13:33:25 +0900 (72c3987) +++ lib/grnxx/storage/node_header.cpp 2013-04-23 17:53:19 +0900 (0436eb2) @@ -15,43 +15,25 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "grnxx/storage/view.hpp" - -#include "grnxx/storage/view-posix.hpp" -#include "grnxx/storage/view-windows.hpp" -#include "grnxx/string_builder.hpp" +#include "grnxx/storage/node_header.hpp" namespace grnxx { namespace storage { -#define GRNXX_FLAGS_WRITE(flag) do { \ - if (flags & flag) { \ - if (!is_first) { \ - builder << " | "; \ - } \ - builder << #flag; \ - is_first = false; \ - } \ -} while (false) - -StringBuilder &operator<<(StringBuilder &builder, ViewFlags flags) { - if (flags) { - bool is_first = true; - GRNXX_FLAGS_WRITE(VIEW_ANONYMOUS); - GRNXX_FLAGS_WRITE(VIEW_HUGE_TLB); - GRNXX_FLAGS_WRITE(VIEW_READ_ONLY); - return builder; - } else { - return builder << "0"; - } -} - -View::View() {} -View::~View() {} - -View *View::create(File *file, int64_t offset, int64_t size, ViewFlags flags) { - return ViewImpl::create(file, offset, size, flags); -} +NodeHeader::NodeHeader() + : id(0), + status(STORAGE_NODE_PHANTOM), + bits(0), + chunk_id(0), + offset(0), + size(0), + next_node_id(0), + prev_node_id(0), + next_phantom_node_id(0), + sibling_node_id(0), + modified_time(0), + reserved{}, + user_data{} {} } // namespace storage } // namespace grnxx Added: lib/grnxx/storage/node_header.hpp (+93 -0) 100644 =================================================================== --- /dev/null +++ lib/grnxx/storage/node_header.hpp 2013-04-23 17:53:19 +0900 (49d4781) @@ -0,0 +1,93 @@ +/* + Copyright (C) 2012-2013 Brazil, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef GRNXX_STORAGE_NODE_HEADER_HPP +#define GRNXX_STORAGE_NODE_HEADER_HPP + +#include "grnxx/storage.hpp" + +namespace grnxx { +namespace storage { + +using NodeStatus = StorageNodeStatus; + +struct NodeHeader { + // The ID of this node. + uint32_t id; + // The status of this node. + NodeStatus status; + // (Non-phantom) + // For calculating the actual offset and size, see also "offset" and "size". + uint8_t bits; + // (Non-phantom) + // The ID of the chunk to which this node belongs. + uint16_t chunk_id; + // (Non-phantom) + // The offset of this node in chunk. + // The actual offset is "offset" << "bits". + uint32_t offset; + // (Non-phantom) + // The size of this node. The actual size is "size" << "bits". + uint32_t size; + // (Non-phantom) + // The ID of the next node in chunk. + // INVALID_ID indicates that this node is the last node in chunk. + uint32_t next_node_id; + // (Non-phantom) + // The ID of the previous node in chunk. + // INVALID_ID indicates that this node is the first node in chunk. + uint32_t prev_node_id; + union { + // (Phantom) + // The ID of the next phantom node. + uint32_t next_phantom_node_id; + // (Active, marked, or unlinked) + // The ID of the latest child node. + // INVALID_ID indicates that this node has no children. + uint32_t child_id; + // (Idle) + // The ID of the next idle node. + uint32_t next_idle_node_id; + }; + union { + // (Active or marked) + // The ID of the next sibling node. + // INVALID_ID indicates that this node has no elder siblings. + uint32_t sibling_node_id; + // (Unlinked) + // The ID of the next unlinked node. + // INVALID_ID indicates that this node is the last unlinked node. + uint32_t next_unlinked_node_id; + // (Idle) + // The ID of the previous idle node. + uint32_t prev_idle_node_id; + }; + // The last modified time. + Time modified_time; + // Reserved for future use. + uint8_t reserved[8]; + // User data. + uint8_t user_data[16]; + + // Initialize the members. + NodeHeader(); +}; + +} // namespace storage +} // namespace grnxx + +#endif // GRNXX_STORAGE_NODE_HEADER_HPP Modified: lib/grnxx/storage/view.cpp (+7 -8) =================================================================== --- lib/grnxx/storage/view.cpp 2013-04-23 13:33:25 +0900 (72c3987) +++ lib/grnxx/storage/view.cpp 2013-04-23 17:53:19 +0900 (0132c83) @@ -35,15 +35,14 @@ namespace storage { } while (false) StringBuilder &operator<<(StringBuilder &builder, ViewFlags flags) { - if (flags) { - bool is_first = true; - GRNXX_FLAGS_WRITE(VIEW_ANONYMOUS); - GRNXX_FLAGS_WRITE(VIEW_HUGE_TLB); - GRNXX_FLAGS_WRITE(VIEW_READ_ONLY); - return builder; - } else { - return builder << "0"; + bool is_first = true; + GRNXX_FLAGS_WRITE(VIEW_ANONYMOUS); + GRNXX_FLAGS_WRITE(VIEW_HUGE_TLB); + GRNXX_FLAGS_WRITE(VIEW_READ_ONLY); + if (is_first) { + builder << "VIEW_DEFAULT"; } + return builder; } View::View() {} Modified: lib/grnxx/storage/view.hpp (+1 -1) =================================================================== --- lib/grnxx/storage/view.hpp 2013-04-23 13:33:25 +0900 (04e5e76) +++ lib/grnxx/storage/view.hpp 2013-04-23 17:53:19 +0900 (42b9e11) @@ -28,7 +28,7 @@ class StringBuilder; namespace storage { class View; -typedef FlagsImpl<View> ViewFlags; +using ViewFlags = FlagsImpl<View>; // Use the default settings. constexpr ViewFlags VIEW_DEFAULT = ViewFlags::define(0x00); -------------- next part -------------- HTML����������������������������...Download