Implemented additional index + API call for call list_historic_referral_rewards

This commit is contained in:
Peter Conrad 2018-04-26 16:03:02 +02:00 committed by Fabian Schuh
parent 8903a5a3af
commit f81b064597
No known key found for this signature in database
GPG key ID: F2538A4B282D6238
5 changed files with 112 additions and 14 deletions

View file

@ -81,6 +81,17 @@ class account_history_plugin : public graphene::app::plugin
std::unique_ptr<detail::account_history_plugin_impl> my;
};
class affiliate_reward_index : public secondary_index
{
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_removed( const object& obj ) override;
virtual void about_to_modify( const object& before ) override{};
virtual void object_modified( const object& after ) override{};
map<account_id_type, set<operation_history_id_type> > _history_by_account;
};
} } //graphene::account_history
/*struct by_id;

View file

@ -38,6 +38,8 @@
#include <graphene/affiliate_stats/affiliate_stats_api.hpp>
#include <graphene/account_history/account_history_plugin.hpp>
namespace graphene { namespace affiliate_stats {
namespace detail {
@ -52,9 +54,9 @@ class affiliate_stats_api_impl
std::vector<top_referred_account> result;
result.reserve( limit );
auto& idx = app.chain_database()->get_index_type<referral_reward_index>().indices().get<by_asset>();
auto itr = idx.find( asset );
auto itr = idx.lower_bound( boost::make_tuple( asset, share_type(GRAPHENE_MAX_SHARE_SUPPLY) ) );
while( itr != idx.end() && itr->get_asset_id() == asset && limit-- > 0 )
result.push_back( *itr );
result.push_back( *itr++ );
return result;
}
@ -63,9 +65,22 @@ class affiliate_stats_api_impl
std::vector<top_app> result;
result.reserve( limit );
auto& idx = app.chain_database()->get_index_type<app_reward_index>().indices().get<by_asset>();
auto itr = idx.find( asset );
auto itr = idx.lower_bound( boost::make_tuple( asset, share_type(GRAPHENE_MAX_SHARE_SUPPLY) ) );
while( itr != idx.end() && itr->get_asset_id() == asset && limit-- > 0 )
result.push_back( *itr );
result.push_back( *itr++ );
return result;
}
std::vector<referral_payment> list_historic_referral_rewards( account_id_type affiliate, operation_history_id_type start, uint16_t limit )const
{
shared_ptr<const affiliate_stats_plugin> plugin = app.get_plugin<const affiliate_stats_plugin>( "affiliate_stats" );
std::vector<referral_payment> result;
const auto& list = plugin->get_reward_history( affiliate );
result.reserve( limit );
auto inner = list.lower_bound( start );
while( inner != list.end() && result.size() < limit )
result.push_back( referral_payment( (*inner++)(*app.chain_database()) ) );
return result;
}
@ -87,6 +102,7 @@ top_app::top_app() {}
top_app::top_app( const app_reward_object& aro )
: app( aro.app ), total_payout( aro.total_payout ) {}
affiliate_stats_api::affiliate_stats_api(graphene::app::application& app)
: my(std::make_shared<detail::affiliate_stats_api_impl>(app)) {}
@ -102,11 +118,19 @@ std::vector<top_app> affiliate_stats_api::list_top_rewards_per_app( asset_id_typ
return my->list_top_rewards_per_app( asset, limit );
}
std::vector<referral_payment> affiliate_stats_api::list_historic_referral_rewards( account_id_type affiliate )const
std::vector<referral_payment> affiliate_stats_api::list_historic_referral_rewards( account_id_type affiliate, operation_history_id_type start, uint16_t limit )const
{
FC_ASSERT( false, "Not implemented!" );
FC_ASSERT( limit <= 100 );
return my->list_historic_referral_rewards( affiliate, start, limit );
}
referral_payment::referral_payment() {}
referral_payment::referral_payment( const operation_history_object& oho )
: id(oho.id), block_num(oho.block_num), tag(oho.op.get<affiliate_payout_operation>().tag),
payout(oho.op.get<affiliate_payout_operation>().payout) {}
} } // graphene::affiliate_stats

View file

@ -42,6 +42,19 @@ namespace graphene { namespace affiliate_stats {
namespace detail {
class affiliate_reward_index : public graphene::db::index_observer
{
public:
affiliate_reward_index( graphene::chain::database& _db ) : db(_db) {}
virtual void on_add( const graphene::db::object& obj ) override;
virtual void on_remove( const graphene::db::object& obj ) override;
virtual void on_modify( const graphene::db::object& before ) override{};
std::map<graphene::chain::account_id_type, std::set<graphene::chain::operation_history_id_type> > _history_by_account;
private:
graphene::chain::database& db;
};
class affiliate_stats_plugin_impl
{
public:
@ -59,10 +72,13 @@ class affiliate_stats_plugin_impl
return _self.database();
}
const std::set<graphene::chain::operation_history_id_type>& get_reward_history( account_id_type& affiliate )const;
typedef void result_type;
template<typename Operation>
void operator()( const Operation& op ) {}
shared_ptr<affiliate_reward_index> _fr_index;
affiliate_stats_plugin& _self;
app_reward_index* _ar_index;
referral_reward_index* _rr_index;
@ -123,9 +139,42 @@ void affiliate_stats_plugin_impl::update_affiliate_stats( const signed_block& b
}
}
} // end namespace detail
static const std::set<graphene::chain::operation_history_id_type> EMPTY;
const std::set<graphene::chain::operation_history_id_type>& affiliate_stats_plugin_impl::get_reward_history( account_id_type& affiliate )const
{
auto itr = _fr_index->_history_by_account.find( affiliate );
if( itr == _fr_index->_history_by_account.end() )
return EMPTY;
return itr->second;
}
static optional<std::pair<account_id_type, operation_history_id_type>> get_account( const database& db, const object& obj )
{
FC_ASSERT( dynamic_cast<const account_transaction_history_object*>(&obj) );
const account_transaction_history_object& ath = static_cast<const account_transaction_history_object&>(obj);
const operation_history_object& oho = db.get<operation_history_object>( ath.operation_id );
if( oho.op.which() == operation::tag<affiliate_payout_operation>::value )
return std::make_pair( ath.account, ath.operation_id );
return optional<std::pair<account_id_type, operation_history_id_type>>();
}
void affiliate_reward_index::on_add( const object& obj )
{
optional<std::pair<account_id_type, operation_history_id_type>> acct_ath = get_account( db, obj );
if( !acct_ath.valid() ) return;
_history_by_account[acct_ath->first].insert( acct_ath->second );
}
void affiliate_reward_index::on_remove( const object& obj )
{
optional<std::pair<account_id_type, operation_history_id_type>> acct_ath = get_account( db, obj );
if( !acct_ath.valid() ) return;
_history_by_account[acct_ath->first].erase( acct_ath->second );
}
} // end namespace detail
affiliate_stats_plugin::affiliate_stats_plugin()
: my( new detail::affiliate_stats_plugin_impl(*this) ) {}
@ -150,11 +199,17 @@ void affiliate_stats_plugin::plugin_initialize(const boost::program_options::var
{
database().applied_block.connect( [this]( const signed_block& b){ my->update_affiliate_stats(b); } );
// my->_oho_index = database().add_index< primary_index< simple_index< operation_history_object > > >();
my->_ar_index = database().add_index< primary_index< app_reward_index > >();
my->_rr_index = database().add_index< primary_index< referral_reward_index > >();
my->_fr_index = shared_ptr<detail::affiliate_reward_index>( new detail::affiliate_reward_index( database() ) );
const_cast<primary_index<account_transaction_history_index>&>(database().get_index_type<primary_index<account_transaction_history_index>>()).add_observer( my->_fr_index );
}
void affiliate_stats_plugin::plugin_startup() {}
const std::set<graphene::chain::operation_history_id_type>& affiliate_stats_plugin::get_reward_history( account_id_type& affiliate )const
{
return my->get_reward_history( affiliate );
}
} } // graphene::affiliate_stats

View file

@ -30,6 +30,7 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/affiliate_stats/affiliate_stats_objects.hpp>
@ -47,7 +48,12 @@ namespace detail {
class referral_payment {
public:
referral_payment();
referral_payment( const operation_history_object& oho );
operation_history_id_type id;
uint32_t block_num;
app_tag tag;
asset payout;
};
class top_referred_account {
@ -73,7 +79,7 @@ class affiliate_stats_api
public:
affiliate_stats_api(graphene::app::application& app);
std::vector<referral_payment> list_historic_referral_rewards( account_id_type affiliate )const;
std::vector<referral_payment> list_historic_referral_rewards( account_id_type affiliate, operation_history_id_type start, uint16_t limit = 100 )const;
// get_pending_referral_reward() - not implemented because we have continuous payouts
// get_previous_referral_reward() - not implemented because we have continuous payouts
std::vector<top_referred_account> list_top_referred_accounts( asset_id_type asset, uint16_t limit = 100 )const;
@ -84,7 +90,7 @@ class affiliate_stats_api
} } // graphene::affiliate_stats
FC_REFLECT(graphene::affiliate_stats::referral_payment, )
FC_REFLECT(graphene::affiliate_stats::referral_payment, (id)(block_num)(tag)(payout) )
FC_REFLECT(graphene::affiliate_stats::top_referred_account, (referral)(total_payout) )
FC_REFLECT(graphene::affiliate_stats::top_app, (app)(total_payout) )

View file

@ -63,6 +63,8 @@ class affiliate_stats_plugin : public graphene::app::plugin
virtual void plugin_initialize(const boost::program_options::variables_map& options) override;
virtual void plugin_startup() override;
const std::set<graphene::chain::operation_history_id_type>& get_reward_history( account_id_type& affiliate )const;
friend class detail::affiliate_stats_plugin_impl;
std::unique_ptr<detail::affiliate_stats_plugin_impl> my;
};