赞
踩
本文是基于已经看过以下的宝宝
在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 * ----------- */
// 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)
新建一个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)); }
BIF_RETTYPE maps_put_3(BIF_ALIST_3) {
if
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。