CHAINBASE_SET_INDEX_TYPE(uosio::chain::resource_limits::resource_limits_object, uosio::chain::resource_limits::resource_limits_index)
define CHAINBASE_SET_INDEX_TYPE( OBJECT_TYPE, INDEX_TYPE ) \
namespace chainbase { template<> struct get_index_type<OBJECT_TYPE> { typedef INDEX_TYPE type; }; }
所以:
get_index_type<uosio::chain::resource_limits::resource_limits_object>::type == uosio::chain::resource_limits::resource_limits_index
所以:
const ObjectType& create( Constructor&& con )
{
CHAINBASE_REQUIRE_WRITE_LOCK("create", ObjectType);
typedef typename get_index_type<ObjectType>::type index_type;
return get_mutable_index<index_type>().emplace( std::forward<Constructor>(con) );
}
等效于:
get_mutable_index< uosio::chain::resource_limits::resource_limits_index >().emplace( std::forward<Constructor>(con) );
generic_index<MultiIndexType>& get_mutable_index()
{
CHAINBASE_REQUIRE_WRITE_LOCK("get_mutable_index", typename MultiIndexType::value_type);
typedef generic_index<MultiIndexType> index_type;
typedef index_type* index_type_ptr;
assert( _index_map.size() > index_type::value_type::type_id );
assert( _index_map[index_type::value_type::type_id] );
return *index_type_ptr( _index_map[index_type::value_type::type_id]->get() );
}
generic_index<MultiIndexType> index_type;
所以
index_type
等效于:
generic_index<uosio::chain::resource_limits::resource_limits_index>
因为:
typedef typename index_type::value_type value_type;
所以:
index_type::value_type::type_id
等效于:
uosio::chain::resource_limits::resource_limits_index::value_type::type_id
value_type::type_id是boost库生成的。。。
函数void add_indices() 添加系统表:resource_limits.add_indices(); --》resource_index_set::add_indices(_db);
using resource_index_set = index_set<
resource_limits_index,
resource_usage_index,
resource_limits_state_index,
resource_limits_config_index
;
最后还是到了db.add_index<Index>();
等效于:db.add_index<resource_limits_index>();
在controller.cpp的push_transaction中,初始化transaction_context的时候:
undo_session = c.mutable_db().start_undo_session(true);
database::session database::start_undo_session( bool enabled )
{
if( enabled ) {
vector< std::unique_ptr<abstract_session> > _sub_sessions;
_sub_sessions.reserve( _index_list.size() );
for( auto& item : _index_list ) {
_sub_sessions.push_back( item->start_undo_session( enabled ) );
}
return session( std::move( _sub_sessions ) );
} else {
return session();
}
}
auto& item : _index_list 这个list在前面db.add_index<Index>();中加入:
auto new_index = new index<index_type>( *idx_ptr );
_index_map[ type_id ].reset( new_index );
_index_list.push_back( new_index );
typedef generic_index<MultiIndexType> index_type;
index_type 为 generic_index<uosio::chain::resource_limits::resource_limits_index>
所以:
item->start_undo_session( enabled ) 《=》
generic_index<uosio::chain::resource_limits::resource_limits_index> ->start_undo_session( enabled )
session start_undo_session( bool enabled ) {
if( enabled ) {
_stack.emplace_back( _indices.get_allocator() );
_stack.back().old_next_id = _next_id;
_stack.back().revision = ++_revision;
return session( *this, _revision );
} else {
return session( *this, -1 );
}
}
session( generic_index& idx, int64_t revision )
:_index(idx),_revision(revision) {
if( revision == -1 )
_apply = false;
}
所以generic_index<uosio::chain::resource_limits::resource_limits_index> 这个对象相当于一个表栈,每个transaction执行的时候都会在不同的表栈上复制栈顶,然后压入这个复制的栈顶,在新栈顶上操作。
struct elastic_limit_parameters {
uint64_t target; // the desired usage
uint64_t max; // the maximum usage
uint32_t periods; // the number of aggregation periods that contribute to the average usage
uint32_t max_multiplier; // the multiplier by which virtual space can oversell usage when uncongested
ratio contract_rate; // the rate at which a congested resource contracts its limit
ratio expand_rate; // the rate at which an uncongested resource expands its limits
void validate()const; // throws if the parameters do not satisfy basic sanity checks
};
网友评论