@nationalpark昨天给出了贴子Trending和Hot的区别,今天有时间来看下Tag的trending排序机制,和贴子的算法类似,也是用的reddit算法摘录,。tag plugin源代码可在这里查看,和trending想关的核心算法在这里,重点用**作了标注:
void add_stats( const tag_object& tag, const tag_stats_object& stats )const
{
_db.modify( stats, [&]( tag_stats_object& s )
{
if( tag.parent == comment_id_type() )
{
s.top_posts;
}
else
{
s.comments;
}
** s.total_trending += static_cast<uint32_t>(tag.trending); **
** s.net_votes += tag.net_votes; **
});
}
void update_tag( const tag_object& current, const comment_object& comment, double hot, double trending )const
{
const auto& stats = get_stats( current.tag );
remove_stats( current, stats );
if( comment.cashout_time != fc::time_point_sec::maximum() ) {
** _db.modify( current, [&]( tag_object& obj ) ** {
obj.active = comment.active;
obj.cashout = _db.calculate_discussion_payout_time( comment );
obj.children = comment.children;
** obj.net_rshares = comment.net_rshares.value; **
** obj.net_votes = comment.net_votes; **
obj.hot = hot;
** obj.trending = trending; **
if( obj.cashout == fc::time_point_sec() )
obj.promoted_balance = 0;
});
add_stats( current, stats );
} else {
_db.remove( current );
}
}
/** finds tags that have been added or removed or updated */
void update_tags( const comment_object& c, bool parse_tags = false )const
{
try {
** auto hot = calculate_hot( c.net_rshares, c.created ); **
** auto trending = calculate_trending( c.net_rshares, c.created ); **
const auto& comment_idx = _db.get_index< tag_index >().indices().get< by_comment >();
if( parse_tags )
{
auto meta = filter_tags( c );
auto citr = comment_idx.lower_bound( c.id );
map< string, const tag_object* > existing_tags;
vector< const tag_object* > remove_queue;
while( citr != comment_idx.end() && citr->comment == c.id )
{
const tag_object* tag = &*citr;
++citr;
if( meta.tags.find( tag->tag ) == meta.tags.end() )
{
remove_queue.push_back(tag);
}
else
{
existing_tags[tag->tag] = tag;
}
}
** for( const auto& tag : meta.tags ) **
{
auto existing = existing_tags.find(tag);
if( existing == existing_tags.end() )
{
create_tag( tag, c, hot, trending );
}
else
{
** update_tag( *existing->second, c, hot, trending ); **
}
}
for( const auto& item : remove_queue )
remove_tag(*item);
}
else
{
auto citr = comment_idx.lower_bound( c.id );
while( citr != comment_idx.end() && citr->comment == c.id )
{
update_tag( *citr, c, hot, trending );
++citr;
}
}
if( c.parent_author.size() )
{
update_tags( _db.get_comment( c.parent_author, c.parent_permlink ) );
}
} FC_CAPTURE_LOG_AND_RETHROW( (c) )
}
** share_type net_rshares; // reward is proportional to rshares^2, this is the sum of all votes (positive and negative)**
share_type abs_rshares; /// this is used to track the total abs(weight) of votes for the purpose of calculating cashout_time
share_type vote_rshares; /// Total positive rshares from all votes. Used to calculate delta weights. Needed to handle vote changing and removal.
总结:
最后上个图看看,KR比CN整整多分发了一倍的SBD哦