MCPcopy Create free account
hub / github.com/SakuraEngine/SakuraEngine / luaH_newkey

Function luaH_newkey

xrepo/packages/l/lua/port/lua/src/ltable.c:663–717  ·  view source on GitHub ↗

** inserts a new key into a hash table; first, check whether key's main ** position is free. If not, check whether colliding node is in its main ** position or not: if it is not, move colliding node to an empty place and ** put new key in its main position; otherwise (colliding node is in its main ** position), new key goes to an empty position. */

Source from the content-addressed store, hash-verified

661** position), new key goes to an empty position.
662*/
663void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
664 Node *mp;
665 TValue aux;
666 if (l_unlikely(ttisnil(key)))
667 luaG_runerror(L, "table index is nil");
668 else if (ttisfloat(key)) {
669 lua_Number f = fltvalue(key);
670 lua_Integer k;
671 if (luaV_flttointeger(f, &k, F2Ieq)) { /* does key fit in an integer? */
672 setivalue(&aux, k);
673 key = &aux; /* insert it as an integer */
674 }
675 else if (l_unlikely(luai_numisnan(f)))
676 luaG_runerror(L, "table index is NaN");
677 }
678 if (ttisnil(value))
679 return; /* do not insert nil values */
680 mp = mainpositionTV(t, key);
681 if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */
682 Node *othern;
683 Node *f = getfreepos(t); /* get a free place */
684 if (f == NULL) { /* cannot find a free place? */
685 rehash(L, t, key); /* grow table */
686 /* whatever called 'newkey' takes care of TM cache */
687 luaH_set(L, t, key, value); /* insert key into grown table */
688 return;
689 }
690 lua_assert(!isdummy(t));
691 othern = mainpositionfromnode(t, mp);
692 if (othern != mp) { /* is colliding node out of its main position? */
693 /* yes; move colliding node into free position */
694 while (othern + gnext(othern) != mp) /* find previous */
695 othern += gnext(othern);
696 gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */
697 *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
698 if (gnext(mp) != 0) {
699 gnext(f) += cast_int(mp - f); /* correct 'next' */
700 gnext(mp) = 0; /* now 'mp' is free */
701 }
702 setempty(gval(mp));
703 }
704 else { /* colliding node is in its own main position */
705 /* new node will go into free position */
706 if (gnext(mp) != 0)
707 gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */
708 else lua_assert(gnext(f) == 0);
709 gnext(mp) = cast_int(f - mp);
710 mp = f;
711 }
712 }
713 setnodekey(L, mp, key);
714 luaC_barrierback(L, obj2gco(t), key);
715 lua_assert(isempty(gval(mp)));
716 setobj2t(L, gval(mp), value);
717}
718
719
720/*

Callers 2

luaH_finishsetFunction · 0.70
luaH_setintFunction · 0.70

Calls 8

luaG_runerrorFunction · 0.85
luaV_flttointegerFunction · 0.85
mainpositionTVFunction · 0.85
mainpositionfromnodeFunction · 0.85
luaC_barrierbackFunction · 0.85
getfreeposFunction · 0.70
rehashFunction · 0.70
luaH_setFunction · 0.70

Tested by

no test coverage detected