当前位置:   article > 正文

erlang数据类型的c源码解析(4)-map_otp map是什么

otp map是什么

1、前言

本文是基于已经看过以下的宝宝

在erl_map.h中有结构体的定义,代码如下:

typedef struct map_s {
   
    Eterm thing_word;
    Uint  size;
    Eterm keys;      /* tuple */
} map_t;
/* map node
 *
 * Keys是一个tuple,存储着所有的Key
 * 紧跟结构体后面的一块连续内存用于存储对应的Val
 * -----------
 * Eterm   THING	
 * Uint    size
 * Eterm   Keys -> {K1, K2, K3, ..., Kn} where n = size
 * ----
 * Eterm   V1
 * ...
 * Eterm   Vn, where n = size
 * -----------
 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

2、宏定义(erl_term.h)

// make_map会打上boxed的标签
#define make_map(x)		make_boxed((Eterm*)(x))
#define make_boxed(x)		_ET_APPLY(make_boxed,(x))
#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)

// 判断map,首先是个boxed,然后再判断map_header
#define is_map(x)		(is_boxed((x)) && is_map_header(*boxed_val((x))))
// 低6位是否等于111100B
#define is_map_header(x)	(((x) & (_TAG_HEADER_MASK)) == _TAG_HEADER_MAP)

// MAP_HEADER 实际是111100B
#define MAP_HEADER             _make_header(1,_TAG_HEADER_MAP)
#define _TAG_HEADER_MAP	       (TAG_PRIMARY_HEADER|MAP_SUBTAG)
#define _make_header(sz,tag)   ((Uint)(((sz) << _HEADER_ARITY_OFFS) + (tag)))


#define map_get_values(x)      (((Eterm *)(x)) + 3)
#define map_get_keys(x)        (((Eterm *)tuple_val(((map_t *)(x))->keys)) + 1)
#define map_get_size(x)        (((map_t*)(x))->size)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3、代码解析

1. maps:new/0

新建一个map

BIF_RETTYPE maps_new_0(BIF_ALIST_0) {
   
    Eterm* hp;
    Eterm tup;
    map_t *mp;
    
    // 在堆上分配空间,分配大小为(结构体map_t占用的空间)+1
    // 多加的1用于存储tuple
    hp    = HAlloc(BIF_P, (MAP_HEADER_SIZE + 1));
    
    // 上面分配的+1的空间,用于新建一个size=0的tuple
    tup   = make_tuple(hp);
    *hp++ = make_arityval(0);
    
    // 剩余的空间用于存储map_t
    mp    = (map_t*)hp;
    
    // thing_word为111100B,用于表明是个map
    mp->thing_word = MAP_HEADER;
    mp->size = 0;
    mp->keys = tup;

    BIF_RET(make_map(mp));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2. maps:put/3

BIF_RETTYPE maps_put_3(BIF_ALIST_3) {
   
    if 
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/261874
推荐阅读
相关标签
  

闽ICP备14008679号