BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
generic_index.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #pragma once
25 #include <graphene/db/index.hpp>
26 #include <boost/multi_index_container.hpp>
27 #include <boost/multi_index/member.hpp>
28 #include <boost/multi_index/ordered_index.hpp>
29 #include <boost/multi_index/mem_fun.hpp>
30 
31 namespace graphene { namespace db {
32 
33  using boost::multi_index_container;
34  using namespace boost::multi_index;
35 
36  struct by_id;
42  template<typename ObjectType, typename MultiIndexType>
43  class generic_index : public index
44  {
45  public:
46  using index_type = MultiIndexType;
47  using object_type = ObjectType;
48 
49  const object& insert( object&& obj )override
50  {
51  assert( nullptr != dynamic_cast<ObjectType*>(&obj) );
52  auto insert_result = _indices.insert( std::move( static_cast<ObjectType&>(obj) ) );
53  FC_ASSERT( insert_result.second,
54  "Could not insert object, most likely a uniqueness constraint was violated" );
55  return *insert_result.first;
56  }
57 
58  const object& create(const std::function<void(object&)>& constructor )override
59  {
60  ObjectType item;
61  item.id = get_next_id();
62  constructor( item );
63  auto insert_result = _indices.insert( std::move(item) );
64  FC_ASSERT( insert_result.second,
65  "Could not create object! Most likely a uniqueness constraint is violated.");
66  use_next_id();
67  return *insert_result.first;
68  }
69 
70  void modify( const object& obj, const std::function<void(object&)>& m )override
71  {
72  assert(nullptr != dynamic_cast<const ObjectType*>(&obj));
74  auto ok = _indices.modify(_indices.iterator_to(static_cast<const ObjectType&>(obj)),
75  [&m, &exc](ObjectType& o) mutable {
76  try {
77  m(o);
78  } catch (fc::exception& e) {
79  exc = std::current_exception();
80  elog("Exception while modifying object: ${e} -- object may be corrupted",
81  ("e", e));
82  } catch (...) {
83  exc = std::current_exception();
84  elog("Unknown exception while modifying object");
85  }
86  }
87  );
88  if (exc)
89  std::rethrow_exception(exc);
90  FC_ASSERT(ok, "Could not modify object, most likely an index constraint was violated");
91  }
92 
93  void remove( const object& obj )override
94  {
95  _indices.erase( _indices.iterator_to( static_cast<const ObjectType&>(obj) ) );
96  }
97 
98  const object* find( object_id_type id )const override
99  {
100  static_assert(std::is_same<typename MultiIndexType::key_type, object_id_type>::value,
101  "First index of MultiIndexType MUST be object_id_type!");
102  auto itr = _indices.find( id );
103  if( itr == _indices.end() ) return nullptr;
104  return &*itr;
105  }
106 
107  void inspect_all_objects(std::function<void (const object&)> inspector)const override
108  {
109  try {
110  for( const auto& ptr : _indices )
111  inspector(ptr);
113  }
114 
115  const index_type& indices()const { return _indices; }
116 
117  private:
118  index_type _indices;
119  };
120 
126  template< class T >
127  struct sparse_index : public generic_index<T, boost::multi_index_container<
128  T,
129  indexed_by<
130  ordered_unique<
131  tag<by_id>,
132  member<object, object_id_type, &object::id>
133  >
134  >
135  >>{};
136 
137 } }
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::db::generic_index::create
const object & create(const std::function< void(object &)> &constructor) override
Definition: generic_index.hpp:58
index.hpp
fc::exception
Used to generate a useful error report when an exception is thrown.
Definition: exception.hpp:56
graphene::db::generic_index::remove
void remove(const object &obj) override
Definition: generic_index.hpp:93
graphene::db::generic_index::object_type
ObjectType object_type
Definition: generic_index.hpp:47
fc::exception_ptr
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
graphene::db::generic_index::index_type
MultiIndexType index_type
Definition: generic_index.hpp:46
graphene::db::generic_index::find
const object * find(object_id_type id) const override
Definition: generic_index.hpp:98
graphene::db::generic_index::indices
const index_type & indices() const
Definition: generic_index.hpp:115
graphene::db::generic_index::insert
const object & insert(object &&obj) override
Definition: generic_index.hpp:49
graphene::db::sparse_index
An index type for objects which may be deleted.
Definition: generic_index.hpp:127
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::db::index
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:70
graphene
Definition: api.cpp:48
graphene::db::generic_index::modify
void modify(const object &obj, const std::function< void(object &)> &m) override
Definition: generic_index.hpp:70
elog
#define elog(FORMAT,...)
Definition: logger.hpp:129
graphene::db::generic_index::inspect_all_objects
void inspect_all_objects(std::function< void(const object &)> inspector) const override
Definition: generic_index.hpp:107