susumu.yata
null+****@clear*****
Mon Mar 11 13:08:43 JST 2013
susumu.yata 2013-03-11 13:08:43 +0900 (Mon, 11 Mar 2013) New Revision: a9fbf9d9b6dc75aa71d14ab9d7a321835b9f574f https://github.com/groonga/grnxx/commit/a9fbf9d9b6dc75aa71d14ab9d7a321835b9f574f Message: Add a skeleton of grnxx::Storage. Added files: lib/storage.cpp lib/storage.hpp Modified files: lib/Makefile.am Modified: lib/Makefile.am (+2 -0) =================================================================== --- lib/Makefile.am 2013-03-08 16:55:52 +0900 (8fb79e5) +++ lib/Makefile.am 2013-03-11 13:08:43 +0900 (4e9f895) @@ -24,6 +24,7 @@ libgrnxx_la_SOURCES = \ recycler.cpp \ slice.cpp \ stopwatch.cpp \ + storage.cpp \ string.cpp \ string_builder.cpp \ system_clock.cpp \ @@ -51,6 +52,7 @@ libgrnxx_include_HEADERS = \ recycler.hpp \ slice.hpp \ stopwatch.hpp \ + storage.hpp \ string.hpp \ string_builder.hpp \ string_format.hpp \ Added: lib/storage.cpp (+94 -0) 100644 =================================================================== --- /dev/null +++ lib/storage.cpp 2013-03-11 13:08:43 +0900 (ce67f41) @@ -0,0 +1,94 @@ +/* + 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 +*/ +#include "storage.hpp" + +#include <ostream> + +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) { + if (flags) { + bool is_first = true; + GRNXX_FLAGS_WRITE(STORAGE_ANONYMOUS); + GRNXX_FLAGS_WRITE(STORAGE_CREATE); + GRNXX_FLAGS_WRITE(STORAGE_HUGE_TLB); + GRNXX_FLAGS_WRITE(STORAGE_OPEN); + GRNXX_FLAGS_WRITE(STORAGE_READ_ONLY); + GRNXX_FLAGS_WRITE(STORAGE_TEMPORARY); + return builder; + } else { + return builder << "0"; + } +} + +std::ostream &operator<<(std::ostream &stream, StorageFlags flags) { + char buf[256]; + StringBuilder builder(buf); + builder << flags; + return stream.write(builder.c_str(), builder.length()); +} + +StorageOptions::StorageOptions() + : max_num_files(1000), + max_file_size(1ULL << 40), + chunk_size_ratio(1.0 / 64) {} + +StorageNodeInfo::StorageNodeInfo() + : id(0), + status(STORAGE_PHANTOM), + bits(0), + chunk_id(0), + offset(0), + size(0), + next_id(0), + prev_id(0), + next_phantom_id(0), + sibling_id(0), + modified_time(0), + reserved{}, + user_data{} {} + +Storage::Storage() {} +Storage::~Storage() {} + +Storage *Storage::open(StorageFlags flags, const char *path, + const StorageOptions &options) { + // TODO + return nullptr; +} + +bool Storage::exists(const char *path) { + // TODO + return false; +} + +void Storage::unlink(const char *path) { + // TODO +} + +} // namespace grnxx Added: lib/storage.hpp (+183 -0) 100644 =================================================================== --- /dev/null +++ lib/storage.hpp 2013-03-11 13:08:43 +0900 (d4fb4f1) @@ -0,0 +1,183 @@ +/* + 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_HPP +#define GRNXX_STORAGE_HPP + +#include "basic.hpp" +#include "time.hpp" + +namespace grnxx { + +class Storage; +typedef FlagsImpl<Storage> StorageFlags; + +// Create an anonymous (non-file-backed) temporary storage. All other flags, +// except STORAGE_HUGE_TLB, are ignored. +constexpr StorageFlags STORAGE_ANONYMOUS = StorageFlags::define(0x0010); +// Create a storage if missing. STORAGE_READ_ONLY is ignored. +constexpr StorageFlags STORAGE_CREATE = StorageFlags::define(0x0040); +// Create a storage if missing, or open an existing storage. +constexpr StorageFlags STORAGE_CREATE_OR_OPEN = StorageFlags::define(0x0140); +// Try to use huge pages. If huge pages are not available, regular pages will +// be used. +constexpr StorageFlags STORAGE_HUGE_TLB = StorageFlags::define(0x0080); +// Open an existing storage. This flag is implicitly set if STORAGE_CREATE is +// not set. +constexpr StorageFlags STORAGE_OPEN = StorageFlags::define(0x0100); +// Open a storage in read-only mode. If not, a storage is created/opened in +// read-write mode. +constexpr StorageFlags STORAGE_READ_ONLY = StorageFlags::define(0x0001); +// Create a file-backed temporary storage. All other flags, except +// STORAGE_ANONYMOUS and STORAGE_HUGE_TLB, are ignored. +constexpr StorageFlags STORAGE_TEMPORARY = StorageFlags::define(0x0200); + +// Generate a string from a set of flags. +StringBuilder &operator<<(StringBuilder &builder, StorageFlags flags); +std::ostream &operator<<(std::ostream &builder, StorageFlags flags); + +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; + + // Initialize the members with the default parameters. + StorageOptions(); +}; + +enum StorageNodeStatus : uint8_t { + // A node without body. + STORAGE_PHANTOM = 0, + // An active node. + STORAGE_ACTIVE = 1, + // A node marked to be removed. + STORAGE_MARKED = 2, + // An unused node. + STORAGE_IDLE = 3, +}; + +struct StorageNodeInfo { + // The ID of this node. + uint32_t id; + // The status of this node. Phantom, active, frozen, or idle. + StorageNodeStatus status; + // (Non-phantom) + // For calculating the actual 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_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_id; + union { + // (Phantom) + // The ID of the next phantom node. + uint32_t next_phantom_id; + // (Active or frozen) + // 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_id; + }; + union { + // (Active or frozen) + // The ID of the next sibling node. INVALID_ID indicates that this node has + // no elder siblings. + uint32_t sibling_id; + // (Idle) + // The ID of the previous idle node. + uint32_t prev_idle_id; + }; + // The time of the last modification. + Time modified_time; + // Reserved for future use. + uint8_t reserved[8]; + // User data. + uint8_t user_data[16]; + + // Initialize the members. + StorageNodeInfo(); +}; + +static_assert(sizeof(StorageNodeInfo) == 64, + "sizeof(StorageNodeInfo) != 64"); + +struct StorageNode { + // The address to the header of this node. + StorageNodeInfo *info; + // The address to the body of this node. + void *body; +}; + +class Storage { + public: + Storage(); + virtual ~Storage(); + + // Create or open a storage. If "flags" contains STORAGE_ANONYMOUS or + // STORAGE_TEMPORARY, "path" == nullptr is acceptable. + static Storage *open(StorageFlags flags, const char *path = nullptr, + const StorageOptions &options = StorageOptions()); + + // Return true iff "path" refers to a valid storage. + static bool exists(const char *path); + // Remove a storage and return true on success. + static void unlink(const char *path); + + // Return the ID of the root node. + static constexpr uint32_t root_id() { + return 0; + } + // Return an invalid ID. + static constexpr uint32_t invalid_id() { + return std::numeric_limits<uint32_t>::max(); + } + + // Open an existing 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(StorageNode *parent_node, uint64_t size) = 0; + + // Mark a node to be removed. Note that the marked node and its descendants + // will be removed by sweep() after a specific time duration. + virtual bool mark_node(StorageNode *node) = 0; + // Sweep marked nodes whose last modified time < (now - lifetime). + virtual void sweep(Duration lifetime) = 0; +}; + +} // namespace grnxx + +#endif // GRNXX_STORAGE_HPP -------------- next part -------------- HTML����������������������������... Download