[Groonga-commit] groonga/grnxx at 9b5fd48 [master] Implement a part of grnxx::Storage.

Back to archive index

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 



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