From 7f4b40f57d7e6f308a1185f498918fbd66ae032c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 9 Dec 2015 13:53:01 -0500 Subject: [PATCH] Improve index on account operation history - operations are now indexed by account and sequence for effecient traversal and query --- .../include/graphene/chain/account_object.hpp | 2 ++ .../chain/operation_history_object.hpp | 7 +++- .../account_history_plugin.cpp | 34 ++++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index 5067292d..9f0df9c8 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -47,6 +47,7 @@ namespace graphene { namespace chain { * Keep the most recent operation as a root pointer to a linked list of the transaction history. */ account_transaction_history_id_type most_recent_op; + uint32_t total_ops = 0; /** * When calculating votes it is necessary to know how much is stored in orders (and thus unavailable for @@ -342,6 +343,7 @@ FC_REFLECT_DERIVED( graphene::chain::account_statistics_object, (graphene::chain::object), (owner) (most_recent_op) + (total_ops) (total_core_in_orders) (lifetime_fees_paid) (pending_fees)(pending_vested_fees) diff --git a/libraries/chain/include/graphene/chain/operation_history_object.hpp b/libraries/chain/include/graphene/chain/operation_history_object.hpp index b1e9d834..4bf6b527 100644 --- a/libraries/chain/include/graphene/chain/operation_history_object.hpp +++ b/libraries/chain/include/graphene/chain/operation_history_object.hpp @@ -86,8 +86,13 @@ namespace graphene { namespace chain { public: static const uint8_t space_id = implementation_ids; static const uint8_t type_id = impl_account_transaction_history_object_type; + account_id_type account; /// the account this operation applies to operation_history_id_type operation_id; + uint32_t sequence = 0; /// the operation position within the given account account_transaction_history_id_type next; + + std::pair account_op()const { return std::tie( account, operation_id ); } + std::pair account_seq()const { return std::tie( account, sequence ); } }; } } // graphene::chain @@ -95,4 +100,4 @@ FC_REFLECT_DERIVED( graphene::chain::operation_history_object, (graphene::chain: (op)(result)(block_num)(trx_in_block)(op_in_trx)(virtual_op) ) FC_REFLECT_DERIVED( graphene::chain::account_transaction_history_object, (graphene::chain::object), - (operation_id)(next) ) + (account)(operation_id)(sequence)(next) ) diff --git a/libraries/plugins/account_history/account_history_plugin.cpp b/libraries/plugins/account_history/account_history_plugin.cpp index f45610fb..58d4293e 100644 --- a/libraries/plugins/account_history/account_history_plugin.cpp +++ b/libraries/plugins/account_history/account_history_plugin.cpp @@ -105,10 +105,13 @@ void account_history_plugin_impl::update_account_histories( const signed_block& const auto& stats_obj = account_id(db).statistics(db); const auto& ath = db.create( [&]( account_transaction_history_object& obj ){ obj.operation_id = oho.id; + obj.account = account_id; + obj.sequence = stats_obj.total_ops+1; obj.next = stats_obj.most_recent_op; }); db.modify( stats_obj, [&]( account_statistics_object& obj ){ obj.most_recent_op = ath.id; + obj.total_ops = ath.sequence; }); } } @@ -134,6 +137,35 @@ void account_history_plugin_impl::update_account_histories( const signed_block& } } // end namespace detail + +struct by_id; +struct by_seq; +struct by_op; +typedef multi_index_container< + account_transaction_history_object, + indexed_by< + ordered_unique< tag, + member< object, object_id_type, &object::id > >, + ordered_unique< tag, + composite_key< account_transaction_history_object, + member< account_transaction_history_object, account_id_type, &account_transaction_history_object::account>, + member< account_transaction_history_object, uint32_t, &account_transaction_history_object::sequence> + > + >, + ordered_unique< tag, + composite_key< account_transaction_history_object, + member< account_transaction_history_object, account_id_type, &account_transaction_history_object::account>, + member< account_transaction_history_object, operation_history_id_type, &account_transaction_history_object::operation_id> + > + > + > +> account_transaction_history_multi_index_type; + +typedef generic_index account_transaction_history_index; + + + + account_history_plugin::account_history_plugin() : my( new detail::account_history_plugin_impl(*this) ) { @@ -163,7 +195,7 @@ void account_history_plugin::plugin_initialize(const boost::program_options::var { database().applied_block.connect( [&]( const signed_block& b){ my->update_account_histories(b); } ); database().add_index< primary_index< simple_index< operation_history_object > > >(); - database().add_index< primary_index< simple_index< account_transaction_history_object > > >(); + database().add_index< primary_index< account_transaction_history_index > >(); LOAD_VALUE_SET(options, "tracked-accounts", my->_tracked_accounts, graphene::chain::account_id_type); }