Skip to content
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

1952 unique index2 #2228

Merged
merged 16 commits into from
Apr 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,17 @@ void database::adjust_total_payout( const comment_object& cur, const asset& sbd_
*/
share_type database::pay_curators( const comment_object& c, share_type& max_rewards )
{
struct cmp
{
bool operator()( const comment_vote_object* obj, const comment_vote_object* obj2 ) const
{
if( obj->weight == obj2->weight )
return obj->voter < obj2->voter;
else
return obj->weight > obj2->weight;
}
};

try
{
uint128_t total_weight( c.total_vote_weight );
Expand All @@ -1608,16 +1619,24 @@ share_type database::pay_curators( const comment_object& c, share_type& max_rewa
}
else if( c.total_vote_weight > 0 )
{
const auto& cvidx = get_index<comment_vote_index>().indices().get<by_comment_weight_voter>();
const auto& cvidx = get_index<comment_vote_index>().indices().get<by_comment_voter>();
auto itr = cvidx.lower_bound( c.id );

std::set< const comment_vote_object*, cmp > proxy_set;
while( itr != cvidx.end() && itr->comment == c.id )
{
uint128_t weight( itr->weight );
proxy_set.insert( &( *itr ) );
++itr;
}

for( auto& item : proxy_set )
{
uint128_t weight( item->weight );
auto claim = ( ( max_rewards.value * weight ) / total_weight ).to_uint64();
if( claim > 0 ) // min_amt is non-zero satoshis
{
unclaimed_rewards -= claim;
const auto& voter = get(itr->voter);
const auto& voter = get( item->voter );
auto reward = create_vesting( voter, asset( claim, STEEM_SYMBOL ), has_hardfork( STEEM_HARDFORK_0_17__659 ) );

push_virtual_operation( curation_reward_operation( voter.name, reward, c.author, to_string( c.permlink ) ) );
Expand All @@ -1629,7 +1648,6 @@ share_type database::pay_curators( const comment_object& c, share_type& max_rewa
});
#endif
}
++itr;
}
}
max_rewards -= unclaimed_rewards;
Expand Down
18 changes: 0 additions & 18 deletions libraries/chain/include/steem/chain/comment_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,6 @@ namespace steem { namespace chain {

struct by_comment_voter;
struct by_voter_comment;
struct by_comment_weight_voter;
struct by_voter_last_update;
typedef multi_index_container<
comment_vote_object,
indexed_by<
Expand All @@ -167,22 +165,6 @@ namespace steem { namespace chain {
member< comment_vote_object, account_id_type, &comment_vote_object::voter>,
member< comment_vote_object, comment_id_type, &comment_vote_object::comment>
>
>,
ordered_unique< tag< by_voter_last_update >,
composite_key< comment_vote_object,
member< comment_vote_object, account_id_type, &comment_vote_object::voter>,
member< comment_vote_object, time_point_sec, &comment_vote_object::last_update>,
member< comment_vote_object, comment_id_type, &comment_vote_object::comment>
>,
composite_key_compare< std::less< account_id_type >, std::greater< time_point_sec >, std::less< comment_id_type > >
>,
ordered_unique< tag< by_comment_weight_voter >,
composite_key< comment_vote_object,
member< comment_vote_object, comment_id_type, &comment_vote_object::comment>,
member< comment_vote_object, uint64_t, &comment_vote_object::weight>,
member< comment_vote_object, account_id_type, &comment_vote_object::voter>
>,
composite_key_compare< std::less< comment_id_type >, std::greater< uint64_t >, std::less< account_id_type > >
>
>,
allocator< comment_vote_object >
Expand Down
10 changes: 1 addition & 9 deletions libraries/chain/include/steem/chain/history_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,7 @@ namespace steem { namespace chain {
operation_object,
indexed_by<
ordered_unique< tag< by_id >, member< operation_object, operation_id_type, &operation_object::id > >,
ordered_unique< tag< by_location >,
composite_key< operation_object,
member< operation_object, uint32_t, &operation_object::block>,
member< operation_object, uint32_t, &operation_object::trx_in_block>,
member< operation_object, uint16_t, &operation_object::op_in_trx>,
member< operation_object, uint64_t, &operation_object::virtual_op>,
member< operation_object, operation_id_type, &operation_object::id>
>
>
ordered_non_unique< tag< by_location >, member< operation_object, uint32_t, &operation_object::block > >
#ifndef SKIP_BY_TX_ID
,
ordered_unique< tag< by_transaction_id >,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ DEFINE_API_IMPL( account_history_api_chainbase_impl, get_ops_in_block )
{
const auto& idx = _db.get_index< chain::operation_index, chain::by_location >();
auto itr = idx.lower_bound( args.block_num );

get_ops_in_block_return result;

while( itr != idx.end() && itr->block == args.block_num )
{
api_operation_object temp = *itr;
if( !args.only_virtual || is_virtual_operation( temp.op ) )
result.ops.push_back( temp );
result.ops.emplace( std::move( temp ) );
++itr;
}

return result;
});
}
Expand Down Expand Up @@ -132,7 +135,7 @@ DEFINE_API_IMPL( account_history_api_rocksdb_impl, get_ops_in_block )
{
api_operation_object temp(op);
if( !args.only_virtual || is_virtual_operation( temp.op ) )
result.ops.emplace_back(std::move(temp));
result.ops.emplace(std::move(temp));
}
);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ struct api_operation_object
uint64_t virtual_op = 0;
fc::time_point_sec timestamp;
steem::protocol::operation op;

bool operator<( const api_operation_object& obj ) const
{
return std::tie( block, trx_in_block, op_in_trx, virtual_op ) < std::tie( obj.block, obj.trx_in_block, obj.op_in_trx, obj.virtual_op );
}
};


Expand All @@ -48,7 +53,7 @@ struct get_ops_in_block_args

struct get_ops_in_block_return
{
vector< api_operation_object > ops;
std::multiset< api_operation_object > ops;
};


Expand Down
191 changes: 71 additions & 120 deletions libraries/plugins/apis/database_api/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1077,148 +1077,99 @@ DEFINE_API_IMPL( database_api_impl, find_comments )
return result;
}

//====================================================last_votes_misc====================================================

/* Votes */

DEFINE_API_IMPL( database_api_impl, list_votes )
namespace last_votes_misc
{
FC_ASSERT( args.limit <= DATABASE_API_SINGLE_QUERY_LIMIT );

list_votes_return result;
result.votes.reserve( args.limit );

switch( args.order )
//====================================================votes_impl====================================================
template< sort_order_type SORTORDERTYPE >
void votes_impl( database_api_impl& _impl, vector< api_comment_vote_object >& c, size_t nr_args, uint32_t limit, vector< fc::variant >& key, fc::time_point_sec& timestamp, uint64_t weight )
{
case( by_comment_voter ):
{
auto key = args.start.as< vector< fc::variant > >();
FC_ASSERT( key.size() == 3, "by_comment_voter start requires 3 values. (account_name_type, string, account_name_type)" );

auto author = key[0].as< account_name_type >();
auto permlink = key[1].as< string >();
comment_id_type comment_id;

if( author != account_name_type() || permlink.size() )
{
auto comment = _db.find< chain::comment_object, chain::by_permlink >( boost::make_tuple( author, permlink ) );
FC_ASSERT( comment != nullptr, "Could not find comment ${a}/${p}.", ("a", author)("p", permlink) );
comment_id = comment->id;
}
if( SORTORDERTYPE == by_comment_voter )
FC_ASSERT( key.size() == nr_args, "by_comment_voter start requires ${nr_args} values. (account_name_type, string, account_name_type)", ("nr_args", nr_args ) );
else
FC_ASSERT( key.size() == nr_args, "by_comment_voter start requires ${nr_args} values. (account_name_type, ${desc}account_name_type, string)", ("nr_args", nr_args )("desc",( nr_args == 4 )?"time_point_sec, ":"" ) );

auto voter = key[2].as< account_name_type >();
account_id_type voter_id;
account_name_type voter;
account_name_type author;
string permlink;

if( voter != account_name_type() )
{
auto account = _db.find< chain::account_object, chain::by_name >( voter );
FC_ASSERT( account != nullptr, "Could not find voter ${v}.", ("v", voter ) );
voter_id = account->id;
}
account_id_type voter_id;
comment_id_type comment_id;

iterate_results< chain::comment_vote_index, chain::by_comment_voter >(
boost::make_tuple( comment_id, voter_id ),
result.votes,
args.limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); } );
break;
if( SORTORDERTYPE == by_comment_voter )
{
author = key[0].as< account_name_type >();
permlink = key[1].as< string >();
voter = key[ 2 ].as< account_name_type >();
}
case( by_voter_comment ):
else
{
auto key = args.start.as< vector< fc::variant > >();
FC_ASSERT( key.size() == 3, "by_comment_voter start requires 3 values. (account_name_type, account_name_type, string)" );

auto voter = key[0].as< account_name_type >();
account_id_type voter_id;

if( voter != account_name_type() )
{
auto account = _db.find< chain::account_object, chain::by_name >( voter );
FC_ASSERT( account != nullptr, "Could not find voter ${v}.", ("v", voter ) );
voter_id = account->id;
}
author = key[ nr_args - 2 ].as< account_name_type >();
permlink = key[ nr_args - 1 ].as< string >();
voter = key[0].as< account_name_type >();
}

auto author = key[1].as< account_name_type >();
auto permlink = key[2].as< string >();
comment_id_type comment_id;
if( voter != account_name_type() )
{
auto account = _impl._db.find< chain::account_object, chain::by_name >( voter );
FC_ASSERT( account != nullptr, "Could not find voter ${v}.", ("v", voter ) );
voter_id = account->id;
}

if( author != account_name_type() || permlink.size() )
{
auto comment = _db.find< chain::comment_object, chain::by_permlink >( boost::make_tuple( author, permlink ) );
FC_ASSERT( comment != nullptr, "Could not find comment ${a}/${p}.", ("a", author)("p", permlink) );
comment_id = comment->id;
}
if( author != account_name_type() || permlink.size() )
{
auto comment = _impl._db.find< chain::comment_object, chain::by_permlink >( boost::make_tuple( author, permlink ) );
FC_ASSERT( comment != nullptr, "Could not find comment ${a}/${p}.", ("a", author)("p", permlink) );
comment_id = comment->id;
}

iterate_results< chain::comment_vote_index, chain::by_voter_comment >(
boost::make_tuple( voter_id, comment_id ),
result.votes,
args.limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); } );
break;
if( SORTORDERTYPE == by_comment_voter )
{
_impl.iterate_results< chain::comment_vote_index, chain::by_comment_voter >(
boost::make_tuple( comment_id, voter_id ),
c,
limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); } );
}
case( by_voter_last_update ):
else if( SORTORDERTYPE == by_voter_comment )
{
auto key = args.start.as< vector< fc::variant > >();
FC_ASSERT( key.size() == 4, "by_comment_voter start requires 4 values. (account_name_type, time_point_sec, account_name_type, string)" );
_impl.iterate_results< chain::comment_vote_index, chain::by_voter_comment >(
boost::make_tuple( voter_id, comment_id ),
c,
limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); } );
}
}

auto voter = key[0].as< account_name_type >();
account_id_type voter_id;
}//namespace last_votes_misc

if( voter != account_name_type() )
{
auto account = _db.find< chain::account_object, chain::by_name >( voter );
FC_ASSERT( account != nullptr, "Could not find voter ${v}.", ("v", voter ) );
voter_id = account->id;
}
//====================================================last_votes_misc====================================================

auto author = key[2].as< account_name_type >();
auto permlink = key[3].as< string >();
comment_id_type comment_id;
/* Votes */

if( author != account_name_type() || permlink.size() )
{
auto comment = _db.find< chain::comment_object, chain::by_permlink >( boost::make_tuple( author, permlink ) );
FC_ASSERT( comment != nullptr, "Could not find comment ${a}/${p}.", ("a", author)("p", permlink) );
comment_id = comment->id;
}
DEFINE_API_IMPL( database_api_impl, list_votes )
{
FC_ASSERT( args.limit <= DATABASE_API_SINGLE_QUERY_LIMIT );

iterate_results< chain::comment_vote_index, chain::by_voter_last_update >(
boost::make_tuple( voter_id, key[1].as< fc::time_point_sec >(), comment_id ),
result.votes,
args.limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); } );
auto key = args.start.as< vector< fc::variant > >();

list_votes_return result;
result.votes.reserve( args.limit );

switch( args.order )
{
case( by_comment_voter ):
{
static fc::time_point_sec t( -1 );
last_votes_misc::votes_impl< by_comment_voter >( *this, result.votes, 3/*nr_args*/, args.limit, key, t, 0 );
break;
}
case( by_comment_weight_voter ):
case( by_voter_comment ):
{
auto key = args.start.as< vector< fc::variant > >();
FC_ASSERT( key.size() == 4, "by_comment_voter start requires 4 values. (account_name_type, string, uint64_t, account_name_type)" );

auto author = key[0].as< account_name_type >();
auto permlink = key[1].as< string >();
comment_id_type comment_id;

if( author != account_name_type() || permlink.size() )
{
auto comment = _db.find< chain::comment_object, chain::by_permlink >( boost::make_tuple( author, permlink ) );
FC_ASSERT( comment != nullptr, "Could not find comment ${a}/${p}.", ("a", author)("p", permlink) );
comment_id = comment->id;
}

auto voter = key[3].as< account_name_type >();
account_id_type voter_id;

if( voter != account_name_type() )
{
auto account = _db.find< chain::account_object, chain::by_name >( voter );
FC_ASSERT( account != nullptr, "Could not find voter ${v}.", ("v", voter ) );
voter_id = account->id;
}

iterate_results< chain::comment_vote_index, chain::by_comment_weight_voter >(
boost::make_tuple( comment_id, key[2].as< uint64_t >(), voter_id ),
result.votes,
args.limit,
[&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); } );
static fc::time_point_sec t( -1 );
last_votes_misc::votes_impl< by_voter_comment >( *this, result.votes, 3/*nr_args*/, args.limit, key, t, 0 );
break;
}
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ enum sort_order_type
by_author_last_update,
by_comment_voter,
by_voter_comment,
by_voter_last_update,
by_comment_weight_voter,
by_price
};

Expand Down Expand Up @@ -597,8 +595,6 @@ FC_REFLECT_ENUM( steem::plugins::database_api::sort_order_type,
(by_author_last_update)
(by_comment_voter)
(by_voter_comment)
(by_voter_last_update)
(by_comment_weight_voter)
(by_price) )

FC_REFLECT( steem::plugins::database_api::get_reward_funds_return,
Expand Down
2 changes: 1 addition & 1 deletion tests/smoketest/votes/test_group.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ REF_STEEMD_PID=$STEEMD_NODE_PID
#echo TEST_STEEMD_PID: $TEST_STEEMD_PID REF_STEEMD_PID: $REF_STEEMD_PID
if [ $TEST_STEEMD_PID -ne -1 ] && [ $REF_STEEMD_PID -ne -1 ]; then
run_test "test_list_votes.py"
run_test "test_list_votes2.py"
#run_test "test_list_votes2.py" Obsolete
else
EXIT_CODE=-1
fi
Expand Down