[Groonga-commit] groonga/grnxx at ee556fa [master] Use grnxx::Exception for error handling.

Back to archive index

susumu.yata null+****@clear*****
Thu Jul 4 10:23:43 JST 2013


susumu.yata	2013-07-04 10:23:43 +0900 (Thu, 04 Jul 2013)

  New Revision: ee556fac7aabadf05c832b9fa1fb8356a8f9cf30
  https://github.com/groonga/grnxx/commit/ee556fac7aabadf05c832b9fa1fb8356a8f9cf30

  Message:
    Use grnxx::Exception for error handling.

  Modified files:
    lib/grnxx/map.cpp
    lib/grnxx/map/array_map.cpp
    lib/grnxx/map/array_map.hpp
    lib/grnxx/map/bytes_array.cpp
    lib/grnxx/map/bytes_array.hpp
    lib/grnxx/map/bytes_store.cpp
    lib/grnxx/map/cursor_impl.cpp
    lib/grnxx/map/cursor_impl.hpp
    lib/grnxx/map/double_array.cpp
    lib/grnxx/map/double_array.hpp
    lib/grnxx/map/hash_table.cpp
    lib/grnxx/map/hash_table.hpp
    lib/grnxx/map/key_store.cpp
    lib/grnxx/map/key_store.hpp
    lib/grnxx/map/patricia.cpp
    lib/grnxx/map/patricia.hpp
    lib/grnxx/map/scanner_impl.cpp
    lib/grnxx/map_cursor.cpp
    test/test_storage.cpp

  Modified: lib/grnxx/map.cpp (+13 -18)
===================================================================
--- lib/grnxx/map.cpp    2013-07-03 17:38:48 +0900 (9f5749e)
+++ lib/grnxx/map.cpp    2013-07-04 10:23:43 +0900 (f51f407)
@@ -20,6 +20,7 @@
 #include <limits>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/storage.hpp"
@@ -68,7 +69,7 @@ Map<T> *Map<T>::create(Storage *storage, uint32_t storage_node_id,
                        MapType type, const MapOptions &options) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   switch (type) {
     case MAP_ARRAY: {
@@ -85,7 +86,7 @@ Map<T> *Map<T>::create(Storage *storage, uint32_t storage_node_id,
     }
     default: {
       GRNXX_ERROR() << "invalid argument: type = " << type;
-      return nullptr;
+      throw LogicError();
     }
   }
 }
@@ -94,12 +95,9 @@ template <typename T>
 Map<T> *Map<T>::open(Storage *storage, uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return nullptr;
-  }
   const map::Header * const header =
       static_cast<const map::Header *>(storage_node.body());
   switch (header->type) {
@@ -117,7 +115,7 @@ Map<T> *Map<T>::open(Storage *storage, uint32_t storage_node_id) {
     }
     default: {
       GRNXX_ERROR() << "invalid format: type = " << header->type;
-      return nullptr;
+      throw LogicError();
     }
   }
 }
@@ -125,16 +123,13 @@ Map<T> *Map<T>::open(Storage *storage, uint32_t storage_node_id) {
 template <typename T>
 bool Map<T>::unlink(Storage *storage, uint32_t storage_node_id) {
   std::unique_ptr<Map<T>> map(open(storage, storage_node_id));
-  if (!map) {
-    return false;
-  }
   return storage->unlink_node(storage_node_id);
 }
 
 template <typename T>
 bool Map<T>::get(int64_t, Key *) {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <typename T>
@@ -194,25 +189,25 @@ bool Map<T>::find(KeyArg key, int64_t *key_id) {
 template <typename T>
 bool Map<T>::add(KeyArg, int64_t *) {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <typename T>
 bool Map<T>::remove(KeyArg) {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <typename T>
 bool Map<T>::replace(KeyArg, KeyArg, int64_t *) {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <typename T>
 bool Map<T>::find_longest_prefix_match(KeyArg, int64_t *, Key *) {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <>
@@ -246,7 +241,7 @@ bool Map<Bytes>::find_longest_prefix_match(KeyArg query, int64_t *key_id,
 template <typename T>
 bool Map<T>::truncate() {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template <typename T>
@@ -271,13 +266,13 @@ template <>
 MapCursor<GeoPoint> *Map<GeoPoint>::create_cursor(
     const MapCursorKeyRange<GeoPoint> &, const MapCursorOptions &) {
   GRNXX_ERROR() << "invalid operation";
-  return nullptr;
+  throw LogicError();
 }
 
 template <typename T>
 MapScanner<T> *Map<T>::create_scanner(KeyArg, const Charset *) {
   GRNXX_ERROR() << "invalid operation";
-  return nullptr;
+  throw LogicError();
 }
 
 template <>

  Modified: lib/grnxx/map/array_map.cpp (+15 -28)
===================================================================
--- lib/grnxx/map/array_map.cpp    2013-07-03 17:38:48 +0900 (1f6537a)
+++ lib/grnxx/map/array_map.cpp    2013-07-04 10:23:43 +0900 (763b9fc)
@@ -20,6 +20,7 @@
 #include <new>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map/array_map/header.hpp"
@@ -45,11 +46,9 @@ ArrayMap<T> *ArrayMap<T>::create(Storage *storage, uint32_t storage_node_id,
   std::unique_ptr<ArrayMap> map(new (std::nothrow) ArrayMap);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::ArrayMap failed";
-    return nullptr;
-  }
-  if (!map->create_map(storage, storage_node_id, options)) {
-    return nullptr;
+    throw MemoryError();
   }
+  map->create_map(storage, storage_node_id, options);
   return map.release();
 }
 
@@ -58,11 +57,9 @@ ArrayMap<T> *ArrayMap<T>::open(Storage *storage, uint32_t storage_node_id) {
   std::unique_ptr<ArrayMap> map(new (std::nothrow) ArrayMap);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::ArrayMap failed";
-    return nullptr;
-  }
-  if (!map->open_map(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  map->open_map(storage, storage_node_id);
   return map.release();
 }
 
@@ -253,45 +250,35 @@ bool ArrayMap<T>::truncate() {
 }
 
 template <typename T>
-bool ArrayMap<T>::create_map(Storage *storage, uint32_t storage_node_id,
+void ArrayMap<T>::create_map(Storage *storage, uint32_t storage_node_id,
                              const MapOptions &) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
-  if (!keys_) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
+    header_->keys_storage_node_id = keys_->storage_node_id();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->keys_storage_node_id = keys_->storage_node_id();
-  return true;
 }
 
 template <typename T>
-bool ArrayMap<T>::open_map(Storage *storage, uint32_t storage_node_id) {
+void ArrayMap<T>::open_map(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   if (storage_node.size() < sizeof(Header)) {
     GRNXX_ERROR() << "invalid format: size = " << storage_node.size()
                   << ", header_size = " << sizeof(Header);
-    return false;
+    throw LogicError();
   }
   storage_node_id_ = storage_node_id;
   header_ = static_cast<Header *>(storage_node.body());
   keys_.reset(KeyStore<T>::open(storage, header_->keys_storage_node_id));
-  if (!keys_) {
-    return false;
-  }
-  return true;
 }
 
 template class ArrayMap<int8_t>;

  Modified: lib/grnxx/map/array_map.hpp (+2 -2)
===================================================================
--- lib/grnxx/map/array_map.hpp    2013-07-03 17:38:48 +0900 (b290e0c)
+++ lib/grnxx/map/array_map.hpp    2013-07-04 10:23:43 +0900 (a37e2c3)
@@ -76,9 +76,9 @@ class ArrayMap : public Map<T> {
   Header *header_;
   std::unique_ptr<KeyStore<T>> keys_;
 
-  bool create_map(Storage *storage, uint32_t storage_node_id,
+  void create_map(Storage *storage, uint32_t storage_node_id,
                   const MapOptions &options);
-  bool open_map(Storage *storage, uint32_t storage_node_id);
+  void open_map(Storage *storage, uint32_t storage_node_id);
 };
 
 }  // namespace map

  Modified: lib/grnxx/map/bytes_array.cpp (+22 -40)
===================================================================
--- lib/grnxx/map/bytes_array.cpp    2013-07-03 17:38:48 +0900 (b6d4aec)
+++ lib/grnxx/map/bytes_array.cpp    2013-07-04 10:23:43 +0900 (eb7963f)
@@ -20,6 +20,7 @@
 #include <cstring>
 #include <new>
 
+#include "grnxx/exception.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map/bytes_store.hpp"
 #include "grnxx/storage.hpp"
@@ -50,40 +51,33 @@ BytesArray *BytesArray::create(Storage *storage, uint32_t storage_node_id,
                                ValueArg default_value) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage = nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<BytesArray> array(new (std::nothrow) BytesArray);
   if (!array) {
     GRNXX_ERROR() << "new grnxx::map::BytesArray failed";
-    return nullptr;
-  }
-  if (!array->create_array(storage, storage_node_id, default_value)) {
-    return nullptr;
+    throw MemoryError();
   }
+  array->create_array(storage, storage_node_id, default_value);
   return array.release();
 }
 
 BytesArray *BytesArray::open(Storage *storage, uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage = nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<BytesArray> array(new (std::nothrow) BytesArray);
   if (!array) {
     GRNXX_ERROR() << "new grnxx::map::BytesArray failed";
-    return nullptr;
-  }
-  if (!array->open_array(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  array->open_array(storage, storage_node_id);
   return array.release();
 }
 
 bool BytesArray::unlink(Storage *storage, uint32_t storage_node_id) {
   std::unique_ptr<BytesArray> array(open(storage, storage_node_id));
-  if (!array) {
-    return false;
-  }
   return storage->unlink_node(storage_node_id);
 }
 
@@ -134,50 +128,38 @@ BytesArray::BytesArray()
       ids_(),
       store_() {}
 
-// Create an array with the default value.
-bool BytesArray::create_array(Storage *storage, uint32_t storage_node_id,
+void BytesArray::create_array(Storage *storage, uint32_t storage_node_id,
                               ValueArg default_value) {
   storage_ = storage;
   uint64_t storage_node_size = sizeof(BytesArrayHeader) + default_value.size();
   StorageNode storage_node =
       storage->create_node(storage_node_id, storage_node_size);
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<BytesArrayHeader *>(storage_node.body());
-  *header_ = BytesArrayHeader();
-  header_->default_value_size = default_value.size();
-  std::memcpy(header_ + 1, default_value.data(), default_value.size());
-  default_value_ = Value(header_ + 1, default_value.size());
-  ids_.reset(IDArray::create(storage, storage_node_id_,
-                             BYTES_STORE_INVALID_BYTES_ID));
-  store_.reset(BytesStore::create(storage, storage_node_id_));
-  if (!ids_ || !store_) {
+  try {
+    header_ = static_cast<BytesArrayHeader *>(storage_node.body());
+    *header_ = BytesArrayHeader();
+    header_->default_value_size = default_value.size();
+    std::memcpy(header_ + 1, default_value.data(), default_value.size());
+    default_value_ = Value(header_ + 1, default_value.size());
+    ids_.reset(IDArray::create(storage, storage_node_id_,
+                               BYTES_STORE_INVALID_BYTES_ID));
+    store_.reset(BytesStore::create(storage, storage_node_id_));
+    header_->ids_storage_node_id = ids_->storage_node_id();
+    header_->store_storage_node_id = store_->storage_node_id();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->ids_storage_node_id = ids_->storage_node_id();
-  header_->store_storage_node_id = store_->storage_node_id();
-  return true;
 }
 
-// Open an array.
-bool BytesArray::open_array(Storage *storage, uint32_t storage_node_id) {
+void BytesArray::open_array(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
   header_ = static_cast<BytesArrayHeader *>(storage_node.body());
   default_value_ = Value(header_ + 1, header_->default_value_size);
   ids_.reset(IDArray::open(storage, header_->ids_storage_node_id));
   store_.reset(BytesStore::open(storage, header_->store_storage_node_id));
-  if (!ids_ || !store_) {
-    return false;
-  }
-  return true;
 }
 
 }  // namespace map

  Modified: lib/grnxx/map/bytes_array.hpp (+2 -2)
===================================================================
--- lib/grnxx/map/bytes_array.hpp    2013-07-03 17:38:48 +0900 (f37540d)
+++ lib/grnxx/map/bytes_array.hpp    2013-07-04 10:23:43 +0900 (571f808)
@@ -100,10 +100,10 @@ class BytesArray {
   BytesArray();
 
   // Create an array with the default value.
-  bool create_array(Storage *storage, uint32_t storage_node_id,
+  void create_array(Storage *storage, uint32_t storage_node_id,
                     ValueArg default_value);
   // Open an array.
-  bool open_array(Storage *storage, uint32_t storage_node_id);
+  void open_array(Storage *storage, uint32_t storage_node_id);
 };
 
 }  // namespace map

  Modified: lib/grnxx/map/bytes_store.cpp (+20 -33)
===================================================================
--- lib/grnxx/map/bytes_store.cpp    2013-07-03 17:38:48 +0900 (550d593)
+++ lib/grnxx/map/bytes_store.cpp    2013-07-04 10:23:43 +0900 (bb8ee4f)
@@ -21,6 +21,7 @@
 #include <memory>
 #include <new>
 
+#include "grnxx/exception.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/periodic_clock.hpp"
 #include "grnxx/storage.hpp"
@@ -157,8 +158,8 @@ class BytesStoreImpl : public BytesStore {
   std::unique_ptr<PageHeaderArray> page_headers_;
   PeriodicClock clock_;
 
-  bool create_store(Storage *storage, uint32_t storage_node_id);
-  bool open_store(Storage *storage, uint32_t storage_node_id);
+  void create_store(Storage *storage, uint32_t storage_node_id);
+  void open_store(Storage *storage, uint32_t storage_node_id);
 
   bool reserve_active_page(uint32_t *page_id,
                            BytesStorePageHeader **page_header);
@@ -195,16 +196,14 @@ BytesStoreImpl *BytesStoreImpl::create(Storage *storage,
                                        uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<BytesStoreImpl> store(new (std::nothrow) BytesStoreImpl);
   if (!store) {
     GRNXX_ERROR() << "new grnxx::map::BytesStoreImpl failed";
-    return nullptr;
-  }
-  if (!store->create_store(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  store->create_store(storage, storage_node_id);
   return store.release();
 }
 
@@ -212,16 +211,14 @@ BytesStoreImpl *BytesStoreImpl::open(Storage *storage,
                                      uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<BytesStoreImpl> store(new (std::nothrow) BytesStoreImpl);
   if (!store) {
     GRNXX_ERROR() << "new grnxx::map::BytesStoreImpl failed";
-    return nullptr;
-  }
-  if (!store->open_store(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  store->open_store(storage, storage_node_id);
   return store.release();
 }
 
@@ -393,42 +390,32 @@ bool BytesStoreImpl::sweep(Duration lifetime) {
   return true;
 }
 
-bool BytesStoreImpl::create_store(Storage *storage, uint32_t storage_node_id) {
+void BytesStoreImpl::create_store(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(BytesStoreHeader));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<BytesStoreHeader *>(storage_node.body());
-  *header_ = BytesStoreHeader();
-  pages_.reset(BytesArray::create(storage, storage_node_id_));
-  page_headers_.reset(PageHeaderArray::create(storage, storage_node_id));
-  if (!pages_ || !page_headers_) {
+  try {
+    header_ = static_cast<BytesStoreHeader *>(storage_node.body());
+    *header_ = BytesStoreHeader();
+    pages_.reset(BytesArray::create(storage, storage_node_id_));
+    page_headers_.reset(PageHeaderArray::create(storage, storage_node_id));
+    header_->pages_storage_node_id = pages_->storage_node_id();
+    header_->page_headers_storage_node_id = page_headers_->storage_node_id();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->pages_storage_node_id = pages_->storage_node_id();
-  header_->page_headers_storage_node_id = page_headers_->storage_node_id();
-  return true;
 }
 
-bool BytesStoreImpl::open_store(Storage *storage, uint32_t storage_node_id) {
+void BytesStoreImpl::open_store(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
   header_ = static_cast<BytesStoreHeader *>(storage_node.body());
   pages_.reset(BytesArray::open(storage, header_->pages_storage_node_id));
   page_headers_.reset(
       PageHeaderArray::open(storage, header_->page_headers_storage_node_id));
-  if (!pages_ || !page_headers_) {
-    return false;
-  }
-  return true;
 }
 
 bool BytesStoreImpl::reserve_active_page(uint32_t *page_id,

  Modified: lib/grnxx/map/cursor_impl.cpp (+12 -20)
===================================================================
--- lib/grnxx/map/cursor_impl.cpp    2013-07-03 17:38:48 +0900 (9720e0d)
+++ lib/grnxx/map/cursor_impl.cpp    2013-07-04 10:23:43 +0900 (98ae596)
@@ -21,6 +21,7 @@
 #include <new>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map.hpp"
@@ -42,11 +43,9 @@ AllKeysCursor<T> *AllKeysCursor<T>::create(
       new (std::nothrow) AllKeysCursor<T>);
   if (!cursor) {
     GRNXX_ERROR() << "new grnxx::map::AllKeysCursor<T> failed";
-    return nullptr;
-  }
-  if (!cursor->init(map, options)) {
-    return nullptr;
+    throw MemoryError();
   }
+  cursor->init(map, options);
   return cursor.release();
 }
 
@@ -72,7 +71,7 @@ bool AllKeysCursor<T>::remove() {
 }
 
 template <typename T>
-bool AllKeysCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
+void AllKeysCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
   map_ = map;
   options_ = options;
   options_.flags = MAP_CURSOR_ORDER_BY_ID;
@@ -85,7 +84,7 @@ bool AllKeysCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
   if (min > max) {
     // There are no keys in the range [min, max].
     cur_ = end_ = 0;
-    return true;
+    return;
   }
 
   if (options_.flags & MAP_CURSOR_REVERSE_ORDER) {
@@ -105,7 +104,6 @@ bool AllKeysCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
       ++count;
     }
   }
-  return true;
 }
 
 template <typename T>
@@ -125,11 +123,9 @@ KeyIDRangeCursor<T> *KeyIDRangeCursor<T>::create(
       new (std::nothrow) KeyIDRangeCursor<T>);
   if (!cursor) {
     GRNXX_ERROR() << "new grnxx::map::KeyIDRangeCursor<T> failed";
-    return nullptr;
-  }
-  if (!cursor->init(map, query, options)) {
-    return nullptr;
+    throw MemoryError();
   }
+  cursor->init(map, query, options);
   return cursor.release();
 }
 
@@ -155,7 +151,7 @@ bool KeyIDRangeCursor<T>::remove() {
 }
 
 template <typename T>
-bool KeyIDRangeCursor<T>::init(Map<T> *map,
+void KeyIDRangeCursor<T>::init(Map<T> *map,
                                const MapCursorKeyIDRange<T> &query,
                                const MapCursorOptions &options) {
   map_ = map;
@@ -187,7 +183,7 @@ bool KeyIDRangeCursor<T>::init(Map<T> *map,
   if (min > max) {
     // There are no keys in the range [min, max].
     cur_ = end_ = 0;
-    return true;
+    return;
   }
 
   if (options_.flags & MAP_CURSOR_REVERSE_ORDER) {
@@ -207,7 +203,6 @@ bool KeyIDRangeCursor<T>::init(Map<T> *map,
       ++count;
     }
   }
-  return true;
 }
 
 template <typename T>
@@ -241,7 +236,7 @@ bool KeyFilterCursor<T>::remove() {
 }
 
 template <typename T>
-bool KeyFilterCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
+void KeyFilterCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
   map_ = map;
   options_ = options;
   options_.flags = MAP_CURSOR_ORDER_BY_ID;
@@ -268,7 +263,6 @@ bool KeyFilterCursor<T>::init(Map<T> *map, const MapCursorOptions &options) {
       }
     }
   }
-  return true;
 }
 
 template <typename T>
@@ -286,12 +280,10 @@ KeyRangeCursor<T> *KeyRangeCursor<T>::create(
       new (std::nothrow) KeyRangeCursor<T>);
   if (!cursor) {
     GRNXX_ERROR() << "new grnxx::map::KeyRangeCursor<T> failed";
-    return nullptr;
+    throw MemoryError();
   }
   cursor->query_ = query;
-  if (!cursor->init(map, options)) {
-    return nullptr;
-  }
+  cursor->init(map, options);
   return cursor.release();
 }
 

  Modified: lib/grnxx/map/cursor_impl.hpp (+3 -3)
===================================================================
--- lib/grnxx/map/cursor_impl.hpp    2013-07-03 17:38:48 +0900 (538c4f6)
+++ lib/grnxx/map/cursor_impl.hpp    2013-07-04 10:23:43 +0900 (21a3116)
@@ -50,7 +50,7 @@ class AllKeysCursor : public MapCursor<T> {
   uint64_t count_;
   MapCursorOptions options_;
 
-  bool init(Map<T> *map, const MapCursorOptions &options);
+  void init(Map<T> *map, const MapCursorOptions &options);
 };
 
 template <typename T>
@@ -78,7 +78,7 @@ class KeyIDRangeCursor : public MapCursor<T> {
   MapCursorKeyIDRange<T> query_;
   MapCursorOptions options_;
 
-  bool init(Map<T> *map,
+  void init(Map<T> *map,
             const MapCursorKeyIDRange<T> &query,
             const MapCursorOptions &options);
 };
@@ -103,7 +103,7 @@ class KeyFilterCursor : public MapCursor<T> {
   uint64_t count_;
   MapCursorOptions options_;
 
-  bool init(Map<T> *map, const MapCursorOptions &options);
+  void init(Map<T> *map, const MapCursorOptions &options);
 
   // Return true if "key" satisfies the query.
   virtual bool filter(KeyArg key) const = 0;

  Modified: lib/grnxx/map/double_array.cpp (+30 -41)
===================================================================
--- lib/grnxx/map/double_array.cpp    2013-07-03 17:38:48 +0900 (8468f96)
+++ lib/grnxx/map/double_array.cpp    2013-07-04 10:23:43 +0900 (0e56a8c)
@@ -20,6 +20,7 @@
 #include <new>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/intrinsic.hpp"
 #include "grnxx/logger.hpp"
@@ -91,11 +92,9 @@ DoubleArray<Bytes> *DoubleArray<Bytes>::create(Storage *storage,
   std::unique_ptr<DoubleArray> map(new (std::nothrow) DoubleArray);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::DoubleArray failed";
-    return nullptr;
-  }
-  if (!map->create_map(storage, storage_node_id, options)) {
-    return nullptr;
+    throw MemoryError();
   }
+  map->create_map(storage, storage_node_id, options);
   return map.release();
 }
 
@@ -104,11 +103,10 @@ DoubleArray<Bytes> *DoubleArray<Bytes>::open(Storage *storage,
   std::unique_ptr<DoubleArray> map(new (std::nothrow) DoubleArray);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::DoubleArray failed";
+    throw MemoryError();
     return nullptr;
   }
-  if (!map->open_map(storage, storage_node_id)) {
-    return nullptr;
-  }
+  map->open_map(storage, storage_node_id);
   return map.release();
 }
 
@@ -461,51 +459,46 @@ bool DoubleArray<Bytes>::find_longest_prefix_match(KeyArg query,
 //  return nullptr;
 //}
 
-bool DoubleArray<Bytes>::create_map(Storage *storage, uint32_t storage_node_id,
+void DoubleArray<Bytes>::create_map(Storage *storage, uint32_t storage_node_id,
                                     const MapOptions &) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  nodes_.reset(NodeArray::create(storage, storage_node_id_));
-  siblings_.reset(SiblingArray::create(storage, storage_node_id_));
-  blocks_.reset(BlockArray::create(storage, storage_node_id_));
-  entries_.reset(EntryArray::create(storage, storage_node_id_));
-  store_.reset(BytesStore::create(storage, storage_node_id_));
-  if (!nodes_ || !siblings_ || !blocks_ || !entries_ || !store_) {
-    storage->unlink_node(storage_node_id_);
-    return false;
-  }
-  header_->nodes_storage_node_id = nodes_->storage_node_id();
-  header_->siblings_storage_node_id = siblings_->storage_node_id();
-  header_->blocks_storage_node_id = blocks_->storage_node_id();
-  header_->entries_storage_node_id = entries_->storage_node_id();
-  header_->store_storage_node_id = store_->storage_node_id();
-  Node * const root_node = reserve_node(ROOT_NODE_ID);
-  if (!root_node) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    nodes_.reset(NodeArray::create(storage, storage_node_id_));
+    siblings_.reset(SiblingArray::create(storage, storage_node_id_));
+    blocks_.reset(BlockArray::create(storage, storage_node_id_));
+    entries_.reset(EntryArray::create(storage, storage_node_id_));
+    store_.reset(BytesStore::create(storage, storage_node_id_));
+    header_->nodes_storage_node_id = nodes_->storage_node_id();
+    header_->siblings_storage_node_id = siblings_->storage_node_id();
+    header_->blocks_storage_node_id = blocks_->storage_node_id();
+    header_->entries_storage_node_id = entries_->storage_node_id();
+    header_->store_storage_node_id = store_->storage_node_id();
+    Node * const root_node = reserve_node(ROOT_NODE_ID);
+    if (!root_node) {
+      // TODO
+      storage->unlink_node(storage_node_id_);
+      throw LogicError();
+    }
+    root_node[NODE_INVALID_OFFSET - ROOT_NODE_ID].set_is_origin(true);
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  root_node[NODE_INVALID_OFFSET - ROOT_NODE_ID].set_is_origin(true);
-  return true;
 }
 
-bool DoubleArray<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
+void DoubleArray<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   storage_node_id_ = storage_node_id;
   StorageNode storage_node = storage->open_node(storage_node_id_);
-  if (!storage_node) {
-    return false;
-  }
   if (storage_node.size() < sizeof(Header)) {
     GRNXX_ERROR() << "invalid format: size = " << storage_node.size()
                   << ", header_size = " << sizeof(Header);
-    return false;
+    throw LogicError();
   }
   header_ = static_cast<Header *>(storage_node.body());
   nodes_.reset(NodeArray::open(storage, header_->nodes_storage_node_id));
@@ -514,10 +507,6 @@ bool DoubleArray<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
   blocks_.reset(BlockArray::open(storage, header_->blocks_storage_node_id));
   entries_.reset(EntryArray::open(storage, header_->entries_storage_node_id));
   store_.reset(BytesStore::open(storage, header_->store_storage_node_id));
-  if (!nodes_ || !siblings_ || !blocks_ || !entries_ || !store_) {
-    return false;
-  }
-  return true;
 }
 
 DoubleArrayResult DoubleArray<Bytes>::get_key(int64_t key_id, Key *key) {

  Modified: lib/grnxx/map/double_array.hpp (+2 -2)
===================================================================
--- lib/grnxx/map/double_array.hpp    2013-07-03 17:38:48 +0900 (539487e)
+++ lib/grnxx/map/double_array.hpp    2013-07-04 10:23:43 +0900 (7984803)
@@ -126,9 +126,9 @@ class DoubleArray<Bytes> : public Map<Bytes> {
   std::unique_ptr<EntryArray> entries_;
   std::unique_ptr<BytesStore> store_;
 
-  bool create_map(Storage *storage, uint32_t storage_node_id,
+  void create_map(Storage *storage, uint32_t storage_node_id,
                   const MapOptions &options);
-  bool open_map(Storage *storage, uint32_t storage_node_id);
+  void open_map(Storage *storage, uint32_t storage_node_id);
 
   DoubleArrayResult get_key(int64_t key_id, Key *key);
 

  Modified: lib/grnxx/map/hash_table.cpp (+18 -31)
===================================================================
--- lib/grnxx/map/hash_table.cpp    2013-07-03 17:38:48 +0900 (5ad41e1)
+++ lib/grnxx/map/hash_table.cpp    2013-07-04 10:23:43 +0900 (0bb2fcc)
@@ -20,6 +20,7 @@
 #include <new>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/intrinsic.hpp"
 #include "grnxx/lock.hpp"
@@ -57,11 +58,9 @@ HashTable<T> *HashTable<T>::create(Storage *storage, uint32_t storage_node_id,
   std::unique_ptr<HashTable> map(new (std::nothrow) HashTable);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::HashTable failed";
-    return nullptr;
-  }
-  if (!map->create_map(storage, storage_node_id, options)) {
-    return nullptr;
+    throw MemoryError();
   }
+  map->create_map(storage, storage_node_id, options);
   return map.release();
 }
 
@@ -70,11 +69,9 @@ HashTable<T> *HashTable<T>::open(Storage *storage, uint32_t storage_node_id) {
   std::unique_ptr<HashTable> map(new (std::nothrow) HashTable);
   if (!map) {
     GRNXX_ERROR() << "new grnxx::map::HashTable failed";
-    return nullptr;
-  }
-  if (!map->open_map(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  map->open_map(storage, storage_node_id);
   return map.release();
 }
 
@@ -320,49 +317,39 @@ bool HashTable<T>::truncate() {
 }
 
 template <typename T>
-bool HashTable<T>::create_map(Storage *storage, uint32_t storage_node_id,
+void HashTable<T>::create_map(Storage *storage, uint32_t storage_node_id,
                               const MapOptions &) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  key_ids_.reset(KeyIDArray::create(storage, storage_node_id_,
-                                    KeyIDArray::page_size() - 1));
-  keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
-  if (!key_ids_ || !keys_) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    key_ids_.reset(KeyIDArray::create(storage, storage_node_id_,
+                                      KeyIDArray::page_size() - 1));
+    keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
+    header_->key_ids_storage_node_id = key_ids_->storage_node_id();
+    header_->keys_storage_node_id = keys_->storage_node_id();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->key_ids_storage_node_id = key_ids_->storage_node_id();
-  header_->keys_storage_node_id = keys_->storage_node_id();
-  return true;
 }
 
 template <typename T>
-bool HashTable<T>::open_map(Storage *storage, uint32_t storage_node_id) {
+void HashTable<T>::open_map(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   if (storage_node.size() < sizeof(Header)) {
     GRNXX_ERROR() << "invalid format: size = " << storage_node.size()
                   << ", header_size = " << sizeof(Header);
-    return false;
+    throw LogicError();
   }
   storage_node_id_ = storage_node_id;
   header_ = static_cast<Header *>(storage_node.body());
   key_ids_.reset(KeyIDArray::open(storage, header_->key_ids_storage_node_id));
   keys_.reset(KeyStore<T>::open(storage, header_->keys_storage_node_id));
-  if (!key_ids_ || !keys_) {
-    return false;
-  }
-  return true;
 }
 
 template <typename T>

  Modified: lib/grnxx/map/hash_table.hpp (+2 -2)
===================================================================
--- lib/grnxx/map/hash_table.hpp    2013-07-03 17:38:48 +0900 (b335a91)
+++ lib/grnxx/map/hash_table.hpp    2013-07-04 10:23:43 +0900 (ffb2fb8)
@@ -80,9 +80,9 @@ class HashTable : public Map<T> {
   std::unique_ptr<KeyIDArray> old_key_ids_;
   std::unique_ptr<KeyStore<T>> keys_;
 
-  bool create_map(Storage *storage, uint32_t storage_node_id,
+  void create_map(Storage *storage, uint32_t storage_node_id,
                   const MapOptions &options);
-  bool open_map(Storage *storage, uint32_t storage_node_id);
+  void open_map(Storage *storage, uint32_t storage_node_id);
 
   // Find a key ID in the hash table.
   // Return true on success and assign the address to "*stored_key_id".

  Modified: lib/grnxx/map/key_store.cpp (+20 -33)
===================================================================
--- lib/grnxx/map/key_store.cpp    2013-07-03 17:38:48 +0900 (5e628ee)
+++ lib/grnxx/map/key_store.cpp    2013-07-04 10:23:43 +0900 (a194a79)
@@ -17,6 +17,7 @@
 */
 #include "grnxx/map/key_store.hpp"
 
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/intrinsic.hpp"
 #include "grnxx/logger.hpp"
@@ -49,16 +50,14 @@ template <typename T>
 KeyStore<T> *KeyStore<T>::create(Storage *storage, uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<KeyStore> store(new (std::nothrow) KeyStore);
   if (!store) {
     GRNXX_ERROR() << "new grnxx::map::KeyStore failed";
-    return nullptr;
-  }
-  if (!store->create_store(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  store->create_store(storage, storage_node_id);
   return store.release();
 }
 
@@ -66,16 +65,14 @@ template <typename T>
 KeyStore<T> *KeyStore<T>::open(Storage *storage, uint32_t storage_node_id) {
   if (!storage) {
     GRNXX_ERROR() << "invalid argument: storage == nullptr";
-    return nullptr;
+    throw LogicError();
   }
   std::unique_ptr<KeyStore> store(new (std::nothrow) KeyStore);
   if (!store) {
     GRNXX_ERROR() << "new grnxx::map::KeyStore failed";
-    return nullptr;
-  }
-  if (!store->open_store(storage, storage_node_id)) {
-    return nullptr;
+    throw MemoryError();
   }
+  store->open_store(storage, storage_node_id);
   return store.release();
 }
 
@@ -172,46 +169,36 @@ bool KeyStore<T>::truncate() {
 }
 
 template <typename T>
-bool KeyStore<T>::create_store(Storage *storage, uint32_t storage_node_id) {
+void KeyStore<T>::create_store(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  keys_.reset(KeyArray::create(storage, storage_node_id_));
-  bits_.reset(BitArray::create(storage, storage_node_id_));
-  links_.reset(LinkArray::create(storage, storage_node_id_));
-  if (!keys_ || !bits_ || !links_) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    keys_.reset(KeyArray::create(storage, storage_node_id_));
+    bits_.reset(BitArray::create(storage, storage_node_id_));
+    links_.reset(LinkArray::create(storage, storage_node_id_));
+    header_->keys_storage_node_id = keys_->storage_node_id();
+    header_->bits_storage_node_id = bits_->storage_node_id();
+    header_->links_storage_node_id = links_->storage_node_id();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->keys_storage_node_id = keys_->storage_node_id();
-  header_->bits_storage_node_id = bits_->storage_node_id();
-  header_->links_storage_node_id = links_->storage_node_id();
-  return true;
 }
 
 template <typename T>
-bool KeyStore<T>::open_store(Storage *storage, uint32_t storage_node_id) {
+void KeyStore<T>::open_store(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
   header_ = static_cast<Header *>(storage_node.body());
   // TODO: Check the format.
   keys_.reset(KeyArray::open(storage, header_->keys_storage_node_id));
   bits_.reset(BitArray::open(storage, header_->bits_storage_node_id));
   links_.reset(LinkArray::open(storage, header_->links_storage_node_id));
-  if (!keys_ || !bits_ || !links_) {
-    return false;
-  }
-  return true;
 }
 
 template class KeyStore<int8_t>;

  Modified: lib/grnxx/map/key_store.hpp (+2 -2)
===================================================================
--- lib/grnxx/map/key_store.hpp    2013-07-03 17:38:48 +0900 (cf8b902)
+++ lib/grnxx/map/key_store.hpp    2013-07-04 10:23:43 +0900 (ddcf62c)
@@ -142,8 +142,8 @@ class KeyStore {
   std::unique_ptr<BitArray> bits_;
   std::unique_ptr<LinkArray> links_;
 
-  bool create_store(Storage *storage, uint32_t storage_node_id);
-  bool open_store(Storage *storage, uint32_t storage_node_id);
+  void create_store(Storage *storage, uint32_t storage_node_id);
+  void open_store(Storage *storage, uint32_t storage_node_id);
 };
 
 }  // namespace map

  Modified: lib/grnxx/map/patricia.cpp (+43 -70)
===================================================================
--- lib/grnxx/map/patricia.cpp    2013-07-03 17:38:48 +0900 (429f273)
+++ lib/grnxx/map/patricia.cpp    2013-07-04 10:23:43 +0900 (aba2098)
@@ -20,6 +20,7 @@
 #include <new>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map/hash_table/hash.hpp"
@@ -62,9 +63,7 @@ Patricia<T> *Patricia<T>::create(Storage *storage,
     GRNXX_ERROR() << "new grnxx::map::Patricia failed";
     return nullptr;
   }
-  if (!map->create_map(storage, storage_node_id, options)) {
-    return nullptr;
-  }
+  map->create_map(storage, storage_node_id, options);
   return map.release();
 }
 
@@ -76,9 +75,7 @@ Patricia<T> *Patricia<T>::open(Storage *storage,
     GRNXX_ERROR() << "new grnxx::map::Patricia failed";
     return nullptr;
   }
-  if (!map->open_map(storage, storage_node_id)) {
-    return nullptr;
-  }
+  map->open_map(storage, storage_node_id);
   return map.release();
 }
 
@@ -549,55 +546,45 @@ bool Patricia<T>::truncate() {
 }
 
 template <typename T>
-bool Patricia<T>::create_map(Storage *storage, uint32_t storage_node_id,
+void Patricia<T>::create_map(Storage *storage, uint32_t storage_node_id,
                              const MapOptions &) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  nodes_.reset(NodeArray::create(storage, storage_node_id_));
-  keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
-  if (!nodes_ || !keys_) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    nodes_.reset(NodeArray::create(storage, storage_node_id_));
+    keys_.reset(KeyStore<T>::create(storage, storage_node_id_));
+    header_->nodes_storage_node_id = nodes_->storage_node_id();
+    header_->keys_storage_node_id = keys_->storage_node_id();
+    Node * const root_node = nodes_->get_pointer(ROOT_NODE_ID);
+    if (!root_node) {
+      // TODO
+      throw LogicError();
+    }
+    *root_node = Node::dead_node();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->nodes_storage_node_id = nodes_->storage_node_id();
-  header_->keys_storage_node_id = keys_->storage_node_id();
-  Node * const root_node = nodes_->get_pointer(ROOT_NODE_ID);
-  if (!root_node) {
-    storage->unlink_node(storage_node_id_);
-    return false;
-  }
-  *root_node = Node::dead_node();
-  return true;
 }
 
 template <typename T>
-bool Patricia<T>::open_map(Storage *storage, uint32_t storage_node_id) {
+void Patricia<T>::open_map(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   if (storage_node.size() < sizeof(Header)) {
     GRNXX_ERROR() << "invalid format: size = " << storage_node.size()
                   << ", header_size = " << sizeof(Header);
-    return false;
+    throw LogicError();
   }
   storage_node_id_ = storage_node_id;
   header_ = static_cast<Header *>(storage_node.body());
   // TODO: Check the format.
   nodes_.reset(NodeArray::open(storage, header_->nodes_storage_node_id));
   keys_.reset(KeyStore<T>::open(storage, header_->keys_storage_node_id));
-  if (!nodes_ || !keys_) {
-    return false;
-  }
-  return true;
 }
 
 template <typename T>
@@ -678,9 +665,7 @@ Patricia<Bytes> *Patricia<Bytes>::create(Storage *storage,
     GRNXX_ERROR() << "new grnxx::map::Patricia failed";
     return nullptr;
   }
-  if (!map->create_map(storage, storage_node_id, options)) {
-    return nullptr;
-  }
+  map->create_map(storage, storage_node_id, options);
   return map.release();
 }
 
@@ -691,9 +676,7 @@ Patricia<Bytes> *Patricia<Bytes>::open(Storage *storage,
     GRNXX_ERROR() << "new grnxx::map::Patricia failed";
     return nullptr;
   }
-  if (!map->open_map(storage, storage_node_id)) {
-    return nullptr;
-  }
+  map->open_map(storage, storage_node_id);
   return map.release();
 }
 
@@ -1600,46 +1583,40 @@ bool Patricia<Bytes>::truncate() {
   return true;
 }
 
-bool Patricia<Bytes>::create_map(Storage *storage, uint32_t storage_node_id,
+void Patricia<Bytes>::create_map(Storage *storage, uint32_t storage_node_id,
                                  const MapOptions &) {
   storage_ = storage;
   StorageNode storage_node =
       storage->create_node(storage_node_id, sizeof(Header));
-  if (!storage_node) {
-    return false;
-  }
   storage_node_id_ = storage_node.id();
-  header_ = static_cast<Header *>(storage_node.body());
-  *header_ = Header();
-  nodes_.reset(NodeArray::create(storage, storage_node_id_));
-  keys_.reset(KeyStore<Bytes>::create(storage, storage_node_id_));
-  cache_.reset(Cache::create(storage, storage_node_id_, -1));
-  if (!nodes_ || !keys_ || !cache_) {
+  try {
+    header_ = static_cast<Header *>(storage_node.body());
+    *header_ = Header();
+    nodes_.reset(NodeArray::create(storage, storage_node_id_));
+    keys_.reset(KeyStore<Bytes>::create(storage, storage_node_id_));
+    cache_.reset(Cache::create(storage, storage_node_id_, -1));
+    header_->nodes_storage_node_id = nodes_->storage_node_id();
+    header_->keys_storage_node_id = keys_->storage_node_id();
+    header_->cache_storage_node_id = cache_->storage_node_id();
+    Node * const root_node = nodes_->get_pointer(ROOT_NODE_ID);
+    if (!root_node) {
+      // TODO
+      throw LogicError();
+    }
+    *root_node = Node::dead_node();
+  } catch (...) {
     storage->unlink_node(storage_node_id_);
-    return false;
+    throw;
   }
-  header_->nodes_storage_node_id = nodes_->storage_node_id();
-  header_->keys_storage_node_id = keys_->storage_node_id();
-  header_->cache_storage_node_id = cache_->storage_node_id();
-  Node * const root_node = nodes_->get_pointer(ROOT_NODE_ID);
-  if (!root_node) {
-    storage->unlink_node(storage_node_id_);
-    return false;
-  }
-  *root_node = Node::dead_node();
-  return true;
 }
 
-bool Patricia<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
+void Patricia<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
   storage_ = storage;
   StorageNode storage_node = storage->open_node(storage_node_id);
-  if (!storage_node) {
-    return false;
-  }
   if (storage_node.size() < sizeof(Header)) {
     GRNXX_ERROR() << "invalid format: size = " << storage_node.size()
                   << ", header_size = " << sizeof(Header);
-    return false;
+    throw LogicError();
   }
   storage_node_id_ = storage_node_id;
   header_ = static_cast<Header *>(storage_node.body());
@@ -1647,10 +1624,6 @@ bool Patricia<Bytes>::open_map(Storage *storage, uint32_t storage_node_id) {
   nodes_.reset(NodeArray::open(storage, header_->nodes_storage_node_id));
   keys_.reset(KeyStore<Bytes>::open(storage, header_->keys_storage_node_id));
   cache_.reset(Cache::open(storage, header_->cache_storage_node_id));
-  if (!nodes_ || !keys_ || !cache_) {
-    return false;
-  }
-  return true;
 }
 
 uint64_t Patricia<Bytes>::get_ith_bit(KeyArg key, uint64_t bit_pos) {

  Modified: lib/grnxx/map/patricia.hpp (+4 -4)
===================================================================
--- lib/grnxx/map/patricia.hpp    2013-07-03 17:38:48 +0900 (0e189e8)
+++ lib/grnxx/map/patricia.hpp    2013-07-04 10:23:43 +0900 (30249ea)
@@ -82,9 +82,9 @@ class Patricia : public Map<T> {
   std::unique_ptr<NodeArray> nodes_;
   std::unique_ptr<KeyStore<T>> keys_;
 
-  bool create_map(Storage *storage, uint32_t storage_node_id,
+  void create_map(Storage *storage, uint32_t storage_node_id,
                   const MapOptions &options);
-  bool open_map(Storage *storage, uint32_t storage_node_id);
+  void open_map(Storage *storage, uint32_t storage_node_id);
 
   static uint64_t get_ith_bit(KeyArg key, uint64_t bit_pos);
   static uint64_t count_common_prefix_bits(KeyArg lhs, KeyArg rhs);
@@ -137,9 +137,9 @@ class Patricia<Bytes> : public Map<Bytes> {
   std::unique_ptr<KeyStore<Bytes>> keys_;
   std::unique_ptr<Cache> cache_;
 
-  bool create_map(Storage *storage, uint32_t storage_node_id,
+  void create_map(Storage *storage, uint32_t storage_node_id,
                   const MapOptions &options);
-  bool open_map(Storage *storage, uint32_t storage_node_id);
+  void open_map(Storage *storage, uint32_t storage_node_id);
 
   static uint64_t get_ith_bit(KeyArg key, uint64_t bit_pos);
 };

  Modified: lib/grnxx/map/scanner_impl.cpp (+2 -1)
===================================================================
--- lib/grnxx/map/scanner_impl.cpp    2013-07-03 17:38:48 +0900 (26714f5)
+++ lib/grnxx/map/scanner_impl.cpp    2013-07-04 10:23:43 +0900 (8c09113)
@@ -22,6 +22,7 @@
 
 #include "grnxx/bytes.hpp"
 #include "grnxx/charset.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map.hpp"
 
@@ -40,7 +41,7 @@ ScannerImpl<T> *ScannerImpl<T>::create(Map<T> *map, KeyArg query,
   std::unique_ptr<ScannerImpl> scanner(new (std::nothrow) ScannerImpl);
   if (!scanner) {
     GRNXX_ERROR() << "new grnxx::map::ScannerImpl failed";
-    return nullptr;
+    throw MemoryError();
   }
   scanner->map_ = map;
   scanner->query_ = query;

  Modified: lib/grnxx/map_cursor.cpp (+2 -1)
===================================================================
--- lib/grnxx/map_cursor.cpp    2013-07-03 17:38:48 +0900 (2c29962)
+++ lib/grnxx/map_cursor.cpp    2013-07-04 10:23:43 +0900 (9e9e284)
@@ -20,6 +20,7 @@
 #include <limits>
 
 #include "grnxx/bytes.hpp"
+#include "grnxx/exception.hpp"
 #include "grnxx/geo_point.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/map.hpp"
@@ -62,7 +63,7 @@ MapCursor<T>::~MapCursor() {}
 template <typename T>
 bool MapCursor<T>::remove() {
   GRNXX_ERROR() << "invalid operation";
-  return false;
+  throw LogicError();
 }
 
 template class MapCursor<int8_t>;

  Modified: test/test_storage.cpp (+0 -2)
===================================================================
--- test/test_storage.cpp    2013-07-03 17:38:48 +0900 (dc67fdc)
+++ test/test_storage.cpp    2013-07-04 10:23:43 +0900 (d2910fb)
@@ -446,9 +446,7 @@ void test_storage_unlink_node() {
 
   storage.reset(grnxx::Storage::create(nullptr));
   node_1 = storage->create_node(grnxx::STORAGE_ROOT_NODE_ID, 1 << 20);
-  assert(node_1);
   node_2 = storage->create_node(grnxx::STORAGE_ROOT_NODE_ID, 1 << 24);
-  assert(node_2);
 
   assert(storage->unlink_node(node_1.id()));
   assert(node_1.status() == grnxx::STORAGE_NODE_UNLINKED);
-------------- next part --------------
HTML����������������������������...
Download 



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