From 9550b87ec7a8a7deb68f309964afa857687b59b4 Mon Sep 17 00:00:00 2001 From: Kayan Date: Wed, 28 Nov 2018 18:03:50 +0800 Subject: [PATCH 1/4] performance improve by move old buffer to backup instead of allocating backup buffer --- include/chainbase/chainbase.hpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/include/chainbase/chainbase.hpp b/include/chainbase/chainbase.hpp index 41ec1db..badd6ff 100644 --- a/include/chainbase/chainbase.hpp +++ b/include/chainbase/chainbase.hpp @@ -224,14 +224,14 @@ namespace chainbase { } template - void modify( const value_type& obj, Modifier&& m ) { - on_modify( obj ); + void modify( const value_type& obj, Modifier&& m, bool move_old_value = false) { + on_modify( obj, move_old_value ); auto ok = _indices.modify( _indices.iterator_to( obj ), m ); if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not modify object, most likely a uniqueness constraint was violated" ) ); } - void remove( const value_type& obj ) { - on_remove( obj ); + void remove( const value_type& obj, bool move_old_value = false ) { + on_remove( obj, move_old_value ); _indices.erase( _indices.iterator_to( obj ) ); } @@ -480,7 +480,7 @@ namespace chainbase { private: bool enabled()const { return _stack.size(); } - void on_modify( const value_type& v ) { + void on_modify( const value_type& v, bool move_old_value ) { if( !enabled() ) return; auto& head = _stack.back(); @@ -492,10 +492,14 @@ namespace chainbase { if( itr != head.old_values.end() ) return; - head.old_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); + if (move_old_value) { + head.old_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); + } else { + head.old_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); + } } - void on_remove( const value_type& v ) { + void on_remove( const value_type& v, bool move_old_value ) { if( !enabled() ) return; auto& head = _stack.back(); @@ -514,7 +518,11 @@ namespace chainbase { if( head.removed_values.count( v.id ) ) return; - head.removed_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); + if (move_old_value) { + head.removed_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); + } else { + head.removed_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); + } } void on_create( const value_type& v ) { @@ -863,19 +871,19 @@ namespace chainbase { } template - void modify( const ObjectType& obj, Modifier&& m ) + void modify( const ObjectType& obj, Modifier&& m, bool move_old_value = false ) { CHAINBASE_REQUIRE_WRITE_LOCK("modify", ObjectType); typedef typename get_index_type::type index_type; - get_mutable_index().modify( obj, m ); + get_mutable_index().modify( obj, m, move_old_value); } template - void remove( const ObjectType& obj ) + void remove( const ObjectType& obj, bool move_old_value = false ) { CHAINBASE_REQUIRE_WRITE_LOCK("remove", ObjectType); typedef typename get_index_type::type index_type; - return get_mutable_index().remove( obj ); + return get_mutable_index().remove( obj, move_old_value ); } template From 711cb5bc5a52ad5885bbfdd1929b46ea707e9c17 Mon Sep 17 00:00:00 2001 From: Kayan Date: Thu, 29 Nov 2018 09:58:54 +0800 Subject: [PATCH 2/4] fix compile error --- include/chainbase/chainbase.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/chainbase/chainbase.hpp b/include/chainbase/chainbase.hpp index badd6ff..8c84e7c 100644 --- a/include/chainbase/chainbase.hpp +++ b/include/chainbase/chainbase.hpp @@ -790,6 +790,10 @@ namespace chainbase { return _segment->get_segment_manager(); } + auto get_segment_manager()const -> std::add_const_t< decltype( ((bip::managed_mapped_file*)nullptr)->get_segment_manager() ) > { + return _segment->get_segment_manager(); + } + size_t get_free_memory()const { return _segment->get_segment_manager()->get_free_memory(); @@ -946,7 +950,7 @@ namespace chainbase { return callback(); } - database_index_row_count_multiset row_count_per_index() { + database_index_row_count_multiset row_count_per_index()const { database_index_row_count_multiset ret; for(const auto& ai_ptr : _index_map) { if(!ai_ptr) From 5f04cbeff005ca6c03e6ac61fc0aaf169fa19bff Mon Sep 17 00:00:00 2001 From: Kayan Date: Fri, 30 Nov 2018 17:40:53 +0800 Subject: [PATCH 3/4] fix modify, add replace, use move-copy as possibble --- include/chainbase/chainbase.hpp | 68 ++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/include/chainbase/chainbase.hpp b/include/chainbase/chainbase.hpp index 56e157a..45c48ac 100644 --- a/include/chainbase/chainbase.hpp +++ b/include/chainbase/chainbase.hpp @@ -224,14 +224,21 @@ namespace chainbase { } template - void modify( const value_type& obj, Modifier&& m, bool move_old_value = false) { - on_modify( obj, move_old_value ); + void modify( const value_type& obj, Modifier&& m ) { + on_modify( obj ); auto ok = _indices.modify( _indices.iterator_to( obj ), m ); if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not modify object, most likely a uniqueness constraint was violated" ) ); } - void remove( const value_type& obj, bool move_old_value = false ) { - on_remove( obj, move_old_value ); + template + void replace( const value_type& obj, Modifier&& m ) { + on_replace( obj ); + auto ok = _indices.modify( _indices.iterator_to( obj ), m ); + if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not replace object, most likely a uniqueness constraint was violated" ) ); + } + + void remove( const value_type& obj ) { + on_remove( obj ); _indices.erase( _indices.iterator_to( obj ) ); } @@ -320,7 +327,7 @@ namespace chainbase { for( auto& item : head.old_values ) { auto ok = _indices.modify( _indices.find( item.second.id ), [&]( value_type& v ) { - v = std::move( item.second ); + v = std::move( const_cast& >(item.second) ); }); if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not modify object, most likely a uniqueness constraint was violated" ) ); } @@ -332,7 +339,7 @@ namespace chainbase { _next_id = head.old_next_id; for( auto& item : head.removed_values ) { - bool ok = _indices.emplace( std::move( item.second ) ).second; + bool ok = _indices.emplace( std::move(const_cast& >(item.second) ) ).second; if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not restore object, most likely a uniqueness constraint was violated" ) ); } @@ -400,7 +407,7 @@ namespace chainbase { // We can only be outside type A/AB (the nop path) if B is not nop, so it suffices to iterate through B's three containers. - for( const auto& item : state.old_values ) + for( auto& item : state.old_values ) { if( prev_state.new_ids.find( item.second.id ) != prev_state.new_ids.end() ) { @@ -504,7 +511,7 @@ namespace chainbase { private: bool enabled()const { return _stack.size(); } - void on_modify( const value_type& v, bool move_old_value ) { + void on_modify( const value_type& v ) { if( !enabled() ) return; auto& head = _stack.back(); @@ -516,14 +523,25 @@ namespace chainbase { if( itr != head.old_values.end() ) return; - if (move_old_value) { - head.old_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); - } else { - head.old_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); - } + head.old_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); + } + + void on_replace( const value_type& v ) { + if( !enabled() ) return; + + auto& head = _stack.back(); + + if( head.new_ids.find( v.id ) != head.new_ids.end() ) + return; + + auto itr = head.old_values.find( v.id ); + if( itr != head.old_values.end() ) + return; + + head.old_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); } - void on_remove( const value_type& v, bool move_old_value ) { + void on_remove( const value_type& v ) { if( !enabled() ) return; auto& head = _stack.back(); @@ -542,11 +560,7 @@ namespace chainbase { if( head.removed_values.count( v.id ) ) return; - if (move_old_value) { - head.removed_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); - } else { - head.removed_values.emplace( std::pair< typename value_type::id_type, const value_type& >( v.id, v ) ); - } + head.removed_values.emplace( std::pair< typename value_type::id_type, value_type >( v.id, std::move(const_cast(v)))); } void on_create( const value_type& v ) { @@ -941,19 +955,27 @@ namespace chainbase { } template - void modify( const ObjectType& obj, Modifier&& m, bool move_old_value = false ) + void modify( const ObjectType& obj, Modifier&& m) { CHAINBASE_REQUIRE_WRITE_LOCK("modify", ObjectType); typedef typename get_index_type::type index_type; - get_mutable_index().modify( obj, m, move_old_value); + get_mutable_index().modify( obj, m ); + } + + template + void replace( const ObjectType& obj, Modifier&& m) + { + CHAINBASE_REQUIRE_WRITE_LOCK("replace", ObjectType); + typedef typename get_index_type::type index_type; + get_mutable_index().replace( obj, m ); } template - void remove( const ObjectType& obj, bool move_old_value = false ) + void remove( const ObjectType& obj ) { CHAINBASE_REQUIRE_WRITE_LOCK("remove", ObjectType); typedef typename get_index_type::type index_type; - return get_mutable_index().remove( obj, move_old_value ); + return get_mutable_index().remove( obj ); } template From 890a9472c2416de743b27366cc250de4db9d00aa Mon Sep 17 00:00:00 2001 From: Kayan Date: Mon, 3 Dec 2018 15:23:31 +0800 Subject: [PATCH 4/4] fix replace --- include/chainbase/chainbase.hpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/chainbase/chainbase.hpp b/include/chainbase/chainbase.hpp index 45c48ac..10dc7c9 100644 --- a/include/chainbase/chainbase.hpp +++ b/include/chainbase/chainbase.hpp @@ -230,10 +230,15 @@ namespace chainbase { if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not modify object, most likely a uniqueness constraint was violated" ) ); } - template - void replace( const value_type& obj, Modifier&& m ) { + template + void replace( const value_type& obj, Replacer&& r ) { + auto id = obj.id; + value_type temp(r, _indices.get_allocator()); on_replace( obj ); - auto ok = _indices.modify( _indices.iterator_to( obj ), m ); + auto ok = _indices.modify( _indices.iterator_to( obj ), [&]( value_type& v ) { + v = std::move(temp); + v.id = id; + }); if( !ok ) BOOST_THROW_EXCEPTION( std::logic_error( "Could not replace object, most likely a uniqueness constraint was violated" ) ); } @@ -962,12 +967,12 @@ namespace chainbase { get_mutable_index().modify( obj, m ); } - template - void replace( const ObjectType& obj, Modifier&& m) + template + void replace( const ObjectType& obj, Replacer&& r) { CHAINBASE_REQUIRE_WRITE_LOCK("replace", ObjectType); typedef typename get_index_type::type index_type; - get_mutable_index().replace( obj, m ); + get_mutable_index().replace( obj, r ); } template