MCPcopy Create free account
hub / github.com/DFHack/dfhack / luaH_newkey

Function luaH_newkey

depends/lua/src/ltable.c:461–510  ·  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

459** position), new key goes to an empty position.
460*/
461TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
462 Node *mp;
463 TValue aux;
464 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
465 else if (ttisfloat(key)) {
466 lua_Integer k;
467 if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */
468 setivalue(&aux, k);
469 key = &aux; /* insert it as an integer */
470 }
471 else if (luai_numisnan(fltvalue(key)))
472 luaG_runerror(L, "table index is NaN");
473 }
474 mp = mainposition(t, key);
475 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
476 Node *othern;
477 Node *f = getfreepos(t); /* get a free place */
478 if (f == NULL) { /* cannot find a free place? */
479 rehash(L, t, key); /* grow table */
480 /* whatever called 'newkey' takes care of TM cache */
481 return luaH_set(L, t, key); /* insert key into grown table */
482 }
483 lua_assert(!isdummy(t));
484 othern = mainposition(t, gkey(mp));
485 if (othern != mp) { /* is colliding node out of its main position? */
486 /* yes; move colliding node into free position */
487 while (othern + gnext(othern) != mp) /* find previous */
488 othern += gnext(othern);
489 gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */
490 *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
491 if (gnext(mp) != 0) {
492 gnext(f) += cast_int(mp - f); /* correct 'next' */
493 gnext(mp) = 0; /* now 'mp' is free */
494 }
495 setnilvalue(gval(mp));
496 }
497 else { /* colliding node is in its own main position */
498 /* new node will go into free position */
499 if (gnext(mp) != 0)
500 gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */
501 else lua_assert(gnext(f) == 0);
502 gnext(mp) = cast_int(f - mp);
503 mp = f;
504 }
505 }
506 setnodekey(L, &mp->i_key, key);
507 luaC_barrierback(L, t, key);
508 lua_assert(ttisnil(gval(mp)));
509 return gval(mp);
510}
511
512
513/*

Callers 3

luaV_finishsetFunction · 0.85
luaH_setFunction · 0.85
luaH_setintFunction · 0.85

Calls 6

luaG_runerrorFunction · 0.85
luaV_tointegerFunction · 0.85
mainpositionFunction · 0.85
getfreeposFunction · 0.85
rehashFunction · 0.85
luaH_setFunction · 0.85

Tested by

no test coverage detected