-
Notifications
You must be signed in to change notification settings - Fork 75
Performance #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Performance #30
Changes from 3 commits
9550b87
711cb5b
8c9b02b
5f04cbe
890a947
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -224,14 +224,14 @@ namespace chainbase { | |
| } | ||
|
|
||
| template<typename Modifier> | ||
| 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 ) ); | ||
| } | ||
|
|
||
|
|
@@ -504,7 +504,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(); | ||
|
|
@@ -516,10 +516,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<value_type&>(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(); | ||
|
|
@@ -538,7 +542,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<value_type&>(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 ) { | ||
|
|
@@ -933,19 +941,19 @@ namespace chainbase { | |
| } | ||
|
|
||
| template<typename ObjectType, typename Modifier> | ||
| 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<ObjectType>::type index_type; | ||
| get_mutable_index<index_type>().modify( obj, m ); | ||
| get_mutable_index<index_type>().modify( obj, m, move_old_value); | ||
| } | ||
|
|
||
| template<typename ObjectType> | ||
| void remove( const ObjectType& obj ) | ||
| void remove( const ObjectType& obj, bool move_old_value = false ) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is always correct to Instead of making There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same goes for the other
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found that some other functions like squash or undo already assume the value_type is move constructible. I've updated the code to use std::move on the value in on_remove(). |
||
| { | ||
| CHAINBASE_REQUIRE_WRITE_LOCK("remove", ObjectType); | ||
| typedef typename get_index_type<ObjectType>::type index_type; | ||
| return get_mutable_index<index_type>().remove( obj ); | ||
| return get_mutable_index<index_type>().remove( obj, move_old_value ); | ||
| } | ||
|
|
||
| template<typename ObjectType, typename Constructor> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I like the readability of overloading
::modifyto do potentially destructive things before the modifier is invoked based on a boolean flag.What do you think about leaving
::modifyas it was (makes a copy for the backup always) and adding a method::replacewhich will move intohead.old_valuesalways.The expected
::replacemethod could take a "Replacer" lambda with the signaturevoid (value_type& value_to_replace, const value_type& old_value). Likeemplaceit would construct the new value and pass it to the lambda which can fully initialize the replacement using the immutable old value if needed. Boost provides https://www.boost.org/doc/libs/1_67_0/libs/multi_index/doc/reference/ord_indices.html#replace which has an overload to take a rvalue. I assume this allows us tomovethe newly constructed replacement into the multi-index container.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace() added, modify() is now the original behavior.