[Groonga-commit] groonga/grnxx at 0fb80a7 [master] Update the interface of grnxx::Storage.

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index