BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
simple_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 
27 namespace graphene { namespace db {
28 
37  template<typename T>
38  class simple_index : public index
39  {
40  public:
41  typedef T object_type;
42 
43  virtual const object& create( const std::function<void(object&)>& constructor ) override
44  {
45  auto id = get_next_id();
46  auto instance = id.instance();
47  if( instance >= _objects.size() ) _objects.resize( instance + 1 );
48  _objects[instance].reset(new T);
49  _objects[instance]->id = id;
50  constructor( *_objects[instance] );
51  _objects[instance]->id = id; // just in case it changed
52  use_next_id();
53  return *_objects[instance];
54  }
55 
56  virtual void modify( const object& obj, const std::function<void(object&)>& modify_callback ) override
57  {
58  assert( obj.id.instance() < _objects.size() );
59  modify_callback( *_objects[obj.id.instance()] );
60  }
61 
62  virtual const object& insert( object&& obj )override
63  {
64  auto instance = obj.id.instance();
65  assert( nullptr != dynamic_cast<T*>(&obj) );
66  if( _objects.size() <= instance ) _objects.resize( instance+1 );
67  assert( !_objects[instance] );
68  _objects[instance].reset( new T( std::move( static_cast<T&>(obj) ) ) );
69  return *_objects[instance];
70  }
71 
72  virtual void remove( const object& obj ) override
73  {
74  assert( nullptr != dynamic_cast<const T*>(&obj) );
75  const auto instance = obj.id.instance();
76  _objects[instance].reset();
77  while( (_objects.size() > 0) && (_objects.back() == nullptr) )
78  _objects.pop_back();
79  }
80 
81  virtual const object* find( object_id_type id )const override
82  {
83  assert( id.space() == T::space_id );
84  assert( id.type() == T::type_id );
85 
86  const auto instance = id.instance();
87  if( instance >= _objects.size() ) return nullptr;
88  return _objects[instance].get();
89  }
90 
91  virtual void inspect_all_objects(std::function<void (const object&)> inspector)const override
92  {
93  try {
94  for( const auto& ptr : _objects )
95  {
96  if( ptr.get() )
97  inspector(*ptr);
98  }
100  }
101 
103  {
104  public:
105  const_iterator( const vector<unique_ptr<object>>& objects ):_objects(objects) {}
107  const vector<unique_ptr<object>>& objects,
108  const vector<unique_ptr<object>>::const_iterator& a ):_itr(a),_objects(objects){}
109  friend bool operator==( const const_iterator& a, const const_iterator& b ) { return a._itr == b._itr; }
110  friend bool operator!=( const const_iterator& a, const const_iterator& b ) { return a._itr != b._itr; }
111  const T& operator*()const { return static_cast<const T&>(*_itr->get()); }
112  const_iterator operator++(int) // postfix
113  {
114  const_iterator result( *this );
115  ++(*this);
116  return result;
117  }
119  {
120  ++_itr;
121  while( (_itr != _objects.end()) && ( (*_itr) == nullptr ) )
122  ++_itr;
123  return *this;
124  }
125  typedef std::forward_iterator_tag iterator_category;
126  typedef vector<unique_ptr<object> >::value_type value_type;
127  typedef vector<unique_ptr<object> >::difference_type difference_type;
128  typedef vector<unique_ptr<object> >::pointer pointer;
129  typedef vector<unique_ptr<object> >::reference reference;
130  private:
131  vector<unique_ptr<object>>::const_iterator _itr;
132  const vector<unique_ptr<object>>& _objects;
133  };
134  const_iterator begin()const { return const_iterator(_objects, _objects.begin()); }
135  const_iterator end()const { return const_iterator(_objects, _objects.end()); }
136 
137  size_t size()const { return _objects.size(); }
138  private:
139  vector< unique_ptr<object> > _objects;
140  };
141 
142 } } // graphene::db
const_iterator end() const
virtual void modify(const object &obj, const std::function< void(object &)> &modify_callback) override
virtual void inspect_all_objects(std::function< void(const object &)> inspector) const override
const_iterator begin() const
A simple index uses a vector<unique_ptr<T>> to store data.
Definition: api.cpp:56
vector< unique_ptr< object > >::reference reference
virtual const object * find(object_id_type id) const override
uint64_t instance() const
Definition: object_id.hpp:50
object_id_type id
Definition: object.hpp:69
const_iterator(const vector< unique_ptr< object >> &objects)
virtual const object & create(const std::function< void(object &)> &constructor) override
virtual object_id_type get_next_id() const =0
std::forward_iterator_tag iterator_category
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
friend bool operator==(const const_iterator &a, const const_iterator &b)
virtual const object & insert(object &&obj) override
virtual void use_next_id()=0
const_iterator(const vector< unique_ptr< object >> &objects, const vector< unique_ptr< object >>::const_iterator &a)
vector< unique_ptr< object > >::pointer pointer
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:71
vector< unique_ptr< object > >::difference_type difference_type
vector< unique_ptr< object > >::value_type value_type
friend bool operator!=(const const_iterator &a, const const_iterator &b)