Lua 源码分析之Table

一、创建一个table(lapi.c, line:666)

LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
  Table *t;
  lua_lock(L);
  luaC_checkGC(L);
  t = luaH_new(L);
  sethvalue(L, L->top, t);
  api_incr_top(L);
  if (narray > 0 || nrec > 0)
    luaH_resize(L, t, narray, nrec);
  lua_unlock(L);
}

1.luaH_new: 创建一个table(ltable.c, line:368)
    

Table *luaH_new (lua_State *L) {
      Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
      t->metatable = NULL;
      t->flags = cast_byte(~0);
      t->array = NULL;
      t->sizearray = 0;
      setnodevector(L, t, 0);
      return t;
    }


    初始化下面几个重要属性
    1.t->array = NULL; /*数组为空*/
    2.t->sizearray = 0; /*数组长度为0*/
    3.t->node = cast(Node *, dummynode);  /* use common `dummynode' */
    4.t->lsizenode = cast_byte(lsize); /*hash 节点链表长度为0 */
    5.t->lastfree = gnode(t, size);  /* all positions are free */
    

2.luaH_resize(ltable.c, line:304): 根据narray和nrec的长度来决定是否要resize
a.resize分两部分:array和hash部分
array部分:
如果需要扩大,则在最后部分增加空节点;
如果需要减少,把超出新的总量部分的不为空的节点插入到hash部分里,再减少数量。
hash部分:
把先保存一下旧的节点列表头指针,设置hash列表部分的大小后,重新把旧的节目插入到hash部分。

注意:
调用luaM_reallocvector时,实际调用的是void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize)
frealloc是初始化是在lua_State *L = lua_newstate(l_alloc, NULL),l_alloc为frealloc最后调用分配的地方
1.会创建一个大小为nsize的数据块,而不管osize是什么。
2.如果nsize为0,则释放这个数据块
3.如果osize和nsize都为0,则什么都不做

  

 void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
      int i;
      int oldasize = t->sizearray;
      int oldhsize = t->lsizenode;
      Node *nold = t->node;  /* save old hash ... */
      if (nasize > oldasize)  /* array part must grow? */
        setarrayvector(L, t, nasize);
      /* create new hash part with appropriate size */
      setnodevector(L, t, nhsize);
      if (nasize < oldasize) {  /* array part must shrink? */
        t->sizearray = nasize;
        /* re-insert elements from vanishing 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值