lua 5.2.3 source lstring.c function luaS_resize

时间:2015-06-10 14:22:11

标签: c lua

void luaS_resize (lua_State *L, int newsize) {
  int i;
  stringtable *tb = &G(L)->strt;
  /* cannot resize while GC is traversing strings */
  luaC_runtilstate(L, ~bitmask(GCSsweepstring));
  if (newsize > tb->size) {
    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
    for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
  }
  /* rehash */
  for (i=0; i<tb->size; i++) {
    GCObject *p = tb->hash[i];
    tb->hash[i] = NULL;
    while (p) {  /* for each node in the list */
      GCObject *next = gch(p)->next;  /* save next */
      unsigned int h = lmod(gco2ts(p)->hash, newsize);  /* new position */
      gch(p)->next = tb->hash[h];  /* chain it */
      tb->hash[h] = p;
      resetoldbit(p);  /* see MOVE OLD rule */
      p = next;
    }
  }
  if (newsize < tb->size) {
    /* shrinking slice must be empty */
    lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
    luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
  }
  tb->size = newsize;
}

当桌子长大时,它会重新出现。但是当表缩小时,它只是重新分配半大小而没有重新散列。我无法理解。它怎么样?

1 个答案:

答案 0 :(得分:0)

好。我自己回答这个问题。此代码运行良好,因为rehash操作不在第一个if(newsize&gt; tb-&gt; size)中。它适用于两者(newsize&gt; tb-&gt; size)和(newsize&lt; tb-&gt; size)。下次,我会更仔细地阅读代码。