static void rehash (lua_State *L, Hash *t) { int oldsize = t->size; Node *nold = t->node; int nelems = numuse(t); int i; LUA_ASSERT(nelems<=oldsize, "wrong count"); if (nelems >= oldsize-oldsize/4) /* using more than 3/4? */ setnodevector(L, t, (lint32)oldsize*2); else if (nelems <= oldsize/4 && /* less than 1/4? */ oldsize > MINPOWER2) setnodevector(L, t, oldsize/2); else setnodevector(L, t, oldsize); for (i=0; i<oldsize; i++) { Node *old = nold+i; if (ttype(&old->val) != LUA_TNIL) *luaH_set(L, t, &old->key) = old->val; } luaM_free(L, nold); /* free old array */ }
Table *kp_table_new(ktap_State *ks) { Table *t = &kp_newobject(ks, KTAP_TTABLE, sizeof(Table), NULL)->h; t->flags = (u8)(~0); t->array = NULL; t->sizearray = 0; t->node = (Node *)dummynode; setnodevector(ks, t, 0); return t; }
Hash *luaH_new (lua_State *L, int size) { Hash *t = luaM_new(L, Hash); t->htag = TagDefault; t->next = L->roottable; L->roottable = t; t->mark = t; t->size = 0; L->nblocks += gcsize(L, 0); t->node = NULL; setnodevector(L, t, luaO_power2(size)); return t; }
void kp_table_resize(ktap_State *ks, 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(ks, t, nasize); /* create new hash part with appropriate size */ setnodevector(ks, t, nhsize); if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */ for (i=nasize; i<oldasize; i++) { if (!ttisnil(&t->array[i])) kp_table_setint(ks, t, i + 1, &t->array[i]); } /* shrink array */ kp_realloc(ks, t->array, oldasize, nasize, Tvalue); } /* re-insert elements from hash part */ for (i = twoto(oldhsize) - 1; i >= 0; i--) { Node *old = nold+i; if (!ttisnil(gval(old))) { /* doesn't need barrier/invalidate cache, as entry was * already present in the table */ setobj(ks, kp_table_set(ks, t, gkey(old)), gval(old)); } } if (!isdummy(nold)) kp_free(ks, nold); /* free old array */ }