BitShares-Core
7.0.2
BitShares blockchain node software and command-line wallet software
|
Go to the documentation of this file.
36 class object_database;
47 virtual void on_add(
const object& obj ){}
73 virtual ~index() =
default;
82 virtual const object&
load(
const std::vector<char>& data ) = 0;
87 virtual const object&
insert(
object&& obj ) = 0;
93 virtual const object&
create(
const std::function<
void(
object&)>& constructor ) = 0;
112 auto maybe_found =
find(
id );
113 FC_ASSERT( maybe_found !=
nullptr,
"Unable to find Object ${id}", (
"id",
id) );
117 virtual void modify(
const object& obj,
const std::function<
void(
object&)>& ) = 0;
118 virtual void remove(
const object& obj ) = 0;
126 template<
typename Object,
typename Lambda>
127 void modify(
const Object& obj,
const Lambda& l ) {
128 modify(
static_cast<const object&
>(obj),
129 std::function<
void(
object&)>( [&l](
object& o ){ l(
static_cast<Object&
>(o) ); } ) );
133 virtual void add_observer(
const std::shared_ptr<index_observer>& ) = 0;
163 void on_add(
const object& obj );
171 template<
typename T,
typename... Args>
174 _sindex.emplace_back( std::make_unique<T>(args...) );
175 return static_cast<T*
>(
_sindex.back().get());
181 for(
const auto& item :
_sindex )
183 const T* result =
dynamic_cast<const T*
>(item.get());
184 if( result !=
nullptr )
return *result;
191 std::vector< std::unique_ptr<secondary_index> >
_sindex;
206 template<
typename Object, u
int8_t chunkbits>
209 static_assert( chunkbits < 64,
"Do you really want arrays with more than 2^63 elements???" );
212 static const size_t MAX_HOLE = 100;
213 static const size_t _mask = ((1ULL << chunkbits) - 1);
215 std::vector< std::vector< const Object* > > content;
216 std::stack< object_id_type > ids_being_modified;
220 FC_ASSERT( (1ULL << chunkbits) > MAX_HOLE,
"Small chunkbits is inefficient." );
226 if( instance == next )
228 if( 0 == (next & _mask) )
230 content.resize((next >> chunkbits) + 1);
231 content[next >> chunkbits].resize( 1ULL << chunkbits,
nullptr );
235 else if( instance < next )
236 FC_ASSERT( !content[instance >> chunkbits][instance & _mask],
237 "Overwriting insert at {id}!", (
"id",obj.
id) );
241 "Out-of-order insert: {id} > {next}!", (
"id",obj.
id)(
"next",next) );
242 if( 0 == (next & _mask) || (next & (~_mask)) != (instance & (~_mask)) )
244 content.resize((instance >> chunkbits) + 1);
245 content[instance >> chunkbits].resize( 1ULL << chunkbits,
nullptr );
247 while( next <= instance )
249 content[next >> chunkbits][next & _mask] =
nullptr;
253 FC_ASSERT(
nullptr !=
dynamic_cast<const Object*
>(&obj),
"Wrong object type!" );
254 content[instance >> chunkbits][instance & _mask] =
static_cast<const Object*
>( &obj );
259 FC_ASSERT(
nullptr !=
dynamic_cast<const Object*
>(&obj),
"Wrong object type!" );
261 FC_ASSERT( instance < next,
"Removing out-of-range object: {id} > {next}!", (
"id",obj.
id)(
"next",next) );
262 FC_ASSERT( content[instance >> chunkbits][instance & _mask],
263 "Removing non-existent object {id}!", (
"id",obj.
id) );
264 content[instance >> chunkbits][instance & _mask] =
nullptr;
269 ids_being_modified.emplace( before.
id );
274 FC_ASSERT( ids_being_modified.top() == after.
id,
"Modification of ID is not supported!");
275 ids_being_modified.pop();
278 template<
typename object_
id >
283 if(
id.instance >= next )
return nullptr;
284 return content[
id.instance.value >> chunkbits][
id.instance.value & _mask];
287 template<
typename object_
id >
290 const Object* ptr =
find(
id );
291 FC_ASSERT( ptr !=
nullptr,
"Object not found!" );
297 FC_ASSERT(
id.space() == Object::space_id,
"Space ID mismatch!" );
298 FC_ASSERT(
id.type() == Object::type_id,
"Type_ID mismatch!" );
299 if(
id.instance() >= next )
return nullptr;
300 return content[
id.instance() >> chunkbits][
id.instance() & ((1ULL << chunkbits) - 1)];
311 template<
typename DerivedIndex, u
int8_t DirectBits = 0>
321 _direct_by_id = add_secondary_index< direct_index< object_type, DirectBits > >();
325 {
return object_type::space_id; }
328 {
return object_type::type_id; }
338 return _direct_by_id->find(
id );
339 return DerivedIndex::find(
id );
344 std::string desc =
"1.0";
359 "Incompatible Version, the serialization of objects in this index has changed" );
360 std::vector<char> tmp;
371 std::ofstream::binary | std::ofstream::out | std::ofstream::trunc );
376 this->inspect_all_objects( [&out](
const object& o ) {
379 out.write( packed_vec.data(), packed_vec.size() );
383 const object&
load(
const std::vector<char>& data )
override
385 const auto& result = DerivedIndex::insert( fc::raw::unpack<object_type>( data ) );
386 for(
const auto& item :
_sindex )
387 item->object_inserted( result );
392 const object&
create(
const std::function<
void(
object&)>& constructor )
override
394 const auto& result = DerivedIndex::create( constructor );
395 for(
const auto& item :
_sindex )
396 item->object_inserted( result );
401 const object&
insert(
object&& obj )
override
403 const auto& result = DerivedIndex::insert( std::move( obj ) );
404 for(
const auto& item :
_sindex )
405 item->object_inserted( result );
410 void remove(
const object& obj )
override
412 for(
const auto& item :
_sindex )
413 item->object_removed( obj );
418 void modify(
const object& obj,
const std::function<
void(
object&)>& m )
override
421 for(
const auto& item :
_sindex )
422 item->about_to_modify( obj );
423 DerivedIndex::modify( obj, m );
424 for(
const auto& item :
_sindex )
425 item->object_modified( obj );
const object & create(const std::function< void(object &)> &constructor) override
typename DerivedIndex::object_type object_type
static constexpr uint8_t type_id
virtual void object_default(object &obj) const =0
virtual uint8_t object_space_id() const =0
void save(const fc::path &db) override
primary_index(object_database &db)
virtual void inspect_all_objects(std::function< void(const object &)> inspector) const =0
uint8_t object_type_id() const override
T * add_secondary_index(Args... args)
Wraps a derived index to intercept calls to create, modify, and remove so that callbacks may be fired...
void object_inserted(const object &obj) override
void unpack(Stream &s, flat_set< T, A... > &value, uint32_t _max_depth)
void on_modify(const object &obj)
const T & get_secondary_index() const
virtual void on_modify(const object &obj)
virtual void add_observer(const std::shared_ptr< index_observer > &)=0
virtual const object & create(const std::function< void(object &)> &constructor)=0
void add_observer(const std::shared_ptr< index_observer > &o) override
void on_remove(const object &obj)
virtual void open(const fc::path &db)=0
const object * find(object_id_type id) const override
virtual void save(const fc::path &db)=0
A secondary index that tracks objects in vectors indexed by object id. It is meant for fully (or almo...
std::vector< std::shared_ptr< index_observer > > _observers
void use_next_id() override
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
virtual void object_modified(const object &after)
virtual ~base_primary_index()=default
static constexpr uint8_t space_id
virtual void object_from_variant(const fc::variant &var, object &obj, uint32_t max_depth) const =0
void object_from_variant(const fc::variant &var, object &obj, uint32_t max_depth) const override
void on_add(const object &obj)
const object & load(const std::vector< char > &data) override
void remove(const object &obj) override
used to get callbacks when objects change
void about_to_modify(const object &before) override
uint64_t instance() const
void object_modified(const object &after) override
bool remove(const path &p)
wraps boost::filesystem::path to provide platform independent path manipulation.
const object & get(object_id_type id) const
void set_next_id(object_id_type id) override
void modify(const object &obj, const std::function< void(object &)> &m) override
base_primary_index(object_database &db)
virtual void on_add(const object &obj)
virtual const object & insert(object &&obj)=0
void object_default(object &obj) const override
virtual const object * find(object_id_type id) const =0
virtual void object_inserted(const object &obj)
void save_undo(const object &obj)
std::string generic_string() const
uint8_t object_space_id() const override
const object & insert(object &&obj) override
virtual void on_remove(const object &obj)
maintains a set of indexed objects that can be modified with multi-level rollback support
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
const Object * find(const object_id_type &id) const
virtual object_id_type get_next_id() const =0
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
fc::sha256 get_object_version() const
const Object & get(const object_id &id) const
virtual void use_next_id()=0
uint64_t file_size(const path &p)
virtual const object & load(const std::vector< char > &data)=0
virtual ~index_observer()=default
virtual void about_to_modify(const object &before)
virtual void remove(const object &obj)=0
const Object * find(const object_id &id) const
virtual uint8_t object_type_id() const =0
void open(const fc::path &db) override
std::vector< std::unique_ptr< secondary_index > > _sindex
virtual void object_removed(const object &obj)
virtual void set_next_id(object_id_type id)=0
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
virtual void modify(const object &obj, const std::function< void(object &)> &)=0
virtual ~secondary_index()=default
abstract base class for accessing objects indexed in various ways.
void * get_address() const
object_id_type get_next_id() const override
void modify(const Object &obj, const Lambda &l)
static sha256 hash(const char *d, uint32_t dlen)
bool exists(const path &p)
void object_removed(const object &obj) override
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)