Skip to content

Commit

Permalink
Issue #1952 - review unique index.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariusz-Trela committed Jan 5, 2018
1 parent 3d934b8 commit b8e3ac0
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 79 deletions.
11 changes: 1 addition & 10 deletions libraries/chain/include/steem/chain/comment_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,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 @@ -157,20 +156,12 @@ namespace steem { namespace chain {
member< comment_vote_object, account_id_type, &comment_vote_object::voter>
>
>,
ordered_unique< tag< by_voter_comment >,
ordered_non_unique< tag< by_voter_comment >,
composite_key< comment_vote_object,
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>,
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 @@ -42,15 +42,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
21 changes: 18 additions & 3 deletions libraries/plugins/apis/account_history_api/account_history_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace steem { namespace plugins { namespace account_history {

using boost::container::flat_set;

namespace detail {

class account_history_api_impl
Expand All @@ -23,15 +25,28 @@ DEFINE_API_IMPL( account_history_api_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;

flat_set< api_operation_object > tmp_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 );
tmp_result.insert( temp );
++itr;
}
return result;

if( !tmp_result.empty() )
{
get_ops_in_block_return result;

result.ops.resize( tmp_result.size() );
std::copy( tmp_result.begin(), tmp_result.end(), result.ops.begin() );

return result;
}

return get_ops_in_block_return();
}

DEFINE_API_IMPL( account_history_api_impl, get_transaction )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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 Down
114 changes: 57 additions & 57 deletions libraries/plugins/apis/database_api/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,28 @@ class database_api_impl
template< typename ResultType >
static ResultType on_push_default( const ResultType& r ) { return r; }

template< typename IndexType, typename OrderType, typename ValueType, typename ResultType, typename OnPush >
void iterate_results( ValueType start, vector< ResultType >& result, uint32_t limit, OnPush&& on_push = &database_api_impl::on_push_default< ResultType > )
template< typename ValueType >
void add( flat_set< ValueType >& c, const ValueType& val )
{
c.insert( val );
}

template< typename ValueType >
void add( std::vector< ValueType >& c, const ValueType& val )
{
c.push_back( val );
}

template< typename IndexType, typename OrderType, template< typename... > typename Collection, typename ValueType, typename ResultType, typename OnPush >
void iterate_results( ValueType start, Collection< ResultType >& result, uint32_t limit, OnPush&& on_push = &database_api_impl::on_push_default< ResultType > )
{
const auto& idx = _db.get_index< IndexType, OrderType >();
auto itr = idx.lower_bound( start );
auto end = idx.end();

while( result.size() < limit && itr != end )
{
result.push_back( on_push( *itr ) );
add( result, on_push( *itr ) );
++itr;
}
}
Expand Down Expand Up @@ -1077,9 +1089,40 @@ DEFINE_API_IMPL( database_api_impl, find_comments )
return result;
}

template< template< typename... > typename Collection, typename ResultType >
void votes_impl( database_api_impl& _impl, Collection< ResultType >& c, size_t nr_args, uint32_t limit, vector< fc::variant >& key )
{
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, ":"" ) );

/* Votes */
auto voter = key[0].as< account_name_type >();
account_id_type voter_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;
}

auto author = key[ nr_args - 2 ].as< account_name_type >();
auto permlink = key[ nr_args - 1 ].as< string >();
comment_id_type 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;
}

_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 ); } );
}

/* Votes */
DEFINE_API_IMPL( database_api_impl, list_votes )
{
FC_ASSERT( args.limit <= DATABASE_API_SINGLE_QUERY_LIMIT );
Expand Down Expand Up @@ -1125,67 +1168,24 @@ DEFINE_API_IMPL( database_api_impl, list_votes )
case( by_voter_comment ):
{
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[1].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;
}

auto author = key[1].as< account_name_type >();
auto permlink = key[2].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;
}

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 ); } );
votes_impl( *this, result.votes, 3/*nr_args*/, args.limit, key );
break;
}
case( by_voter_last_update ):
{
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)" );

auto voter = key[1].as< account_name_type >();
account_id_type voter_id;
flat_set< api_comment_vote_object > tmp_votes;

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;
}
auto key = args.start.as< vector< fc::variant > >();
votes_impl( *this, tmp_votes, 4/*nr_args*/, std::numeric_limits<int>::max(), key );

auto author = key[2].as< account_name_type >();
auto permlink = key[3].as< string >();
comment_id_type comment_id;
auto itr = tmp_votes.lower_bound( api_comment_vote_object( key[1].as< fc::time_point_sec >() ) );
decltype( tmp_votes.rend() ) ritr( itr );

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;
}
size_t idx = 0;
votes_impl( *this, result.votes, 3/*nr_args*/, args.limit, key );
while( idx++ < args.limit && ritr < tmp_votes.rend() )
result.votes.push_back( *ritr );

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 ); } );
break;
}
case( by_comment_weight_voter ):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ struct api_comment_object

struct api_comment_vote_object
{
api_comment_vote_object( const time_point_sec& _last_update ) : last_update( _last_update )
{

}

api_comment_vote_object( const comment_vote_object& cv, const database& db ) :
id( cv.id ),
weight( cv.weight ),
Expand All @@ -156,6 +161,11 @@ struct api_comment_vote_object
int16_t vote_percent = 0;
time_point_sec last_update;
int8_t num_changes = 0;

bool operator<( const api_comment_vote_object& obj ) const
{
return last_update < obj.last_update;
}
};

struct api_account_object
Expand Down

0 comments on commit b8e3ac0

Please sign in to comment.