EOS source code analysis 2-Delete data from the Multi-Index table, explain the erase function in detail

erase

Use the primary key to delete existing objects from the table (two forms)

const_iterator erase( const_iterator itr )

void erase( const object_type& obj )
  • parameter

itr: iterator pointing to the object to be deleted;

obj: the reference of the object to be deleted.

  • ​Return value

When using itr to find an object, it returns the pointer of the object after the deleted object.

Note: Return the next object pointer of the currently deleted object

 E.g:

    //我们在这里定义一张表		

     //@abi table vec i64 
 struct vec{
		account_name      player; 
		uint64_t primary_key() const { return player; }
		EOSLIB_SERIALIZE( vec, (player));
  };
  typedef eosio::multi_index< N(vec), vec> vec_index;
	  
  vec_index vecs;
		                                                                                                                                                            
  typedef eosio::multi_index< N(vec), vec> vec_index;
	  		                                                                                                                            
  vec_index vecs;

1):插入表两条数据
   //插入数据张三
  vecs.emplace(_self, [&](auto& r){
       r.player = N(zhangsan1111);
  });
  //插入数据李四
  vecs.emplace(_self, [&](auto& r){
       r.player = N(lisi11111111);
  });

2):查询数据(张三)
  auto itr = vecs.find(zhangsan1111);

3):删除张三这条数据
   itr = vecs.erase(itr);

我们现在来看itr指针指向的是那条数据?
  print( itr->player  );
  此时输出(李四) >>   lisi11111111

 

  • Operation result

The object is deleted from the table, and the related storage is recycled;

The secondary index related to the table is updated;

Refund the storage fee and related fees paid by the payer of the deleted object.

  • abnormal

When the object to be deleted does not exist, the Action does not have the right to modify the table data, or the given iterator is invalid, an exception is thrown.

 

Use of erase

Here is an example from the previous article:

//删除联系人
//@abi action
void remove(const account_name account) {
    获取授权,如果没有授权,Action调用会中止,事务会回滚
    require_auth(account);
    
    //address_index是自己定义的eosio::multi_index
    //实例化address数据表(multi_index),参数用于建立对表的访问权限
    address_index addresses(_self, _self);

    auto itr = addresses.find(account);
    eosio_assert(itr != addresses.end(), "Address for account not found");

    //删除数据
    addresses.erase(itr);
}

 

erase source code

The source code of the erase function is  similar to the emplace function mentioned in the previous article, so I won’t post it. Its key code is in this sentence:

db_remove_i64( objitem.__primary_itr );

 

It is a function defined in eosiolib/db.h :

void db_remove_i64(int32_t iterator);

 

In wasm_interface.cpp of database_api class implementation:

void db_remove_i64( int itr ) {
    context.db_remove_i64( itr );
}

 

The apply_context::db_remove_i64 function is called :

void apply_context::db_remove_i64( int iterator ) {
    const key_value_object& obj = keyval_cache.get( iterator );

    const auto& table_obj = keyval_cache.get_table( obj.t_id );
    FC_ASSERT( table_obj.code == receiver, "db access violation" );

    update_db_usage( obj.payer,  -(obj.value.size() + config::billable_size_v<key_value_object>) );

    db.modify( table_obj, [&]( auto& t ) {
        --t.count;
    });
    db.remove( obj );

    if (table_obj.count == 0) {
        remove_table(table_obj);
    }

    keyval_cache.remove( iterator );
}

 

Among them, db is a reference to a chainbase::database object, and its modify and remove methods are called to operate the database.

Special thanks to @松果 for your support

Guess you like

Origin blog.csdn.net/weixin_39842528/article/details/90608762