Lua设计与实现:字符串的实现-strt散列数组的重新散列—luaS_resize

Lua设计与实现:字符串的实现-strt散列数组的重新散列—luaS_resize

详细如图所示

void luaS_resize (lua_State *L, int newsize) {
  GCObject **newhash; // newhash 为一个数组,里面存放的是GCObject*的类型数据
  stringtable *tb;    //获取在lua_State环境中维护的stringTable散列数组
  int i;
  if (G(L)->gcstate == GCSsweepstring)
    return;  /* cannot resize during GC traverse */
  newhash = luaM_newvector(L, newsize, GCObject *); //重新分配一个内存空间
  tb = &G(L)->strt;   //获取
  for (i=0; i<newsize; i++) newhash[i] = NULL;  //进行初始化
  /* rehash */
  for (i=0; i<tb->size; i++) {
    GCObject *p = tb->hash[i];   //如图所示,获得第一个数组中第一个元素即GCObject*(它也代表了自身链表的第一个元素的位置)
    while (p) {  /* for each node in the list */  // p 表示的是
      GCObject *next = p->gch.next;  /* save next */   //保存该元素后面的链表地址
      unsigned int h = gco2ts(p)->hash;     

     // gco2ts(p)->hash 可以写作:if(p.gch.tt == LUA_TSTRING) return p->ts->  tsv


      int h1 = lmod(h, newsize);  /* new position */
      lua_assert(cast_int(h%newsize) == lmod(h, newsize));


      p->gch.next = newhash[h1];  /* chain it */ //一句话采用头插法进行链接链表

      newhash[h1] = p;
      p = next;
    }
  }
  luaM_freearray(L, tb->hash, tb->size, TString *);
  tb->size = newsize;
  tb->hash = newhash;
}