MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / luaH_newkey

Function luaH_newkey

lib/lua/src/ltable.c:665–720  ·  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

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

Callers 2

luaH_finishsetFunction · 0.85
luaH_setintFunction · 0.85

Calls 7

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

Tested by

no test coverage detected