** 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. */
| 9637 | ** position), new key goes to an empty position. |
| 9638 | */ |
| 9639 | static TValue *newkey (lua_State *L, Table *t, const TValue *key) { |
| 9640 | Node *mp = mainposition(t, key); |
| 9641 | if (!ttisnil(gval(mp)) || mp == dummynode) { |
| 9642 | Node *othern; |
| 9643 | Node *n = getfreepos(t); /* get a free place */ |
| 9644 | if (n == NULL) { /* cannot find a free place? */ |
| 9645 | rehash(L, t, key); /* grow table */ |
| 9646 | return luaH_set(L, t, key); /* re-insert key into grown table */ |
| 9647 | } |
| 9648 | lua_assert(n != dummynode); |
| 9649 | othern = mainposition(t, key2tval(mp)); |
| 9650 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 9651 | /* yes; move colliding node into free position */ |
| 9652 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ |
| 9653 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ |
| 9654 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ |
| 9655 | gnext(mp) = NULL; /* now `mp' is free */ |
| 9656 | setnilvalue(gval(mp)); |
| 9657 | } |
| 9658 | else { /* colliding node is in its own main position */ |
| 9659 | /* new node will go into free position */ |
| 9660 | gnext(n) = gnext(mp); /* chain new position */ |
| 9661 | gnext(mp) = n; |
| 9662 | mp = n; |
| 9663 | } |
| 9664 | } |
| 9665 | gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; |
| 9666 | luaC_barriert(L, t, key); |
| 9667 | lua_assert(ttisnil(gval(mp))); |
| 9668 | return gval(mp); |
| 9669 | } |
| 9670 | |
| 9671 | |
| 9672 | /* |
no test coverage detected