BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface 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  typedef MultiIndexType index_type;
47  typedef ObjectType object_type;
48 
49  virtual 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, "Could not insert object, most likely a uniqueness constraint was violated" );
54  return *insert_result.first;
55  }
56 
57  virtual const object& create(const std::function<void(object&)>& constructor )override
58  {
59  ObjectType item;
60  item.id = get_next_id();
61  constructor( item );
62  auto insert_result = _indices.insert( std::move(item) );
63  FC_ASSERT(insert_result.second, "Could not create object! Most likely a uniqueness constraint is violated.");
64  use_next_id();
65  return *insert_result.first;
66  }
67 
68  virtual void modify( const object& obj, const std::function<void(object&)>& m )override
69  {
70  assert(nullptr != dynamic_cast<const ObjectType*>(&obj));
72  auto ok = _indices.modify(_indices.iterator_to(static_cast<const ObjectType&>(obj)),
73  [&m, &exc](ObjectType& o) mutable {
74  try {
75  m(o);
76  } catch (fc::exception& e) {
77  exc = std::current_exception();
78  elog("Exception while modifying object: ${e} -- object may be corrupted",
79  ("e", e));
80  } catch (...) {
81  exc = std::current_exception();
82  elog("Unknown exception while modifying object");
83  }
84  }
85  );
86  if (exc)
87  std::rethrow_exception(exc);
88  FC_ASSERT(ok, "Could not modify object, most likely an index constraint was violated");
89  }
90 
91  virtual void remove( const object& obj )override
92  {
93  _indices.erase( _indices.iterator_to( static_cast<const ObjectType&>(obj) ) );
94  }
95 
96  virtual const object* find( object_id_type id )const override
97  {
98  static_assert(std::is_same<typename MultiIndexType::key_type, object_id_type>::value,
99  "First index of MultiIndexType MUST be object_id_type!");
100  auto itr = _indices.find( id );
101  if( itr == _indices.end() ) return nullptr;
102  return &*itr;
103  }
104 
105  virtual void inspect_all_objects(std::function<void (const object&)> inspector)const override
106  {
107  try {
108  for( const auto& ptr : _indices )
109  inspector(ptr);
111  }
112 
113  const index_type& indices()const { return _indices; }
114 
115  private:
116  index_type _indices;
117  };
118 
124  template< class T >
125  struct sparse_index : public generic_index<T, boost::multi_index_container<
126  T,
127  indexed_by<
128  ordered_unique<
129  tag<by_id>,
130  member<object, object_id_type, &object::id>
131  >
132  >
133  >>{};
134 
135 } }
virtual void modify(const object &obj, const std::function< void(object &)> &m) override
Definition: api.cpp:56
#define elog(FORMAT,...)
Definition: logger.hpp:129
virtual const object & insert(object &&obj) override
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
An index type for objects which may be deleted.
virtual const object & create(const std::function< void(object &)> &constructor) override
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
virtual void inspect_all_objects(std::function< void(const object &)> inspector) const override
object_id_type id
Definition: object.hpp:73
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
virtual const object * find(object_id_type id) const override
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:71
const index_type & indices() const