/* ** 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. */ static TableNode* table_newkey(Table *t, uint32_t key) { TableNode *mp = mainposition(t, key); if(!tisnil(mp)) { TableNode *n = getfreenode(t); if(n == NULL) { table_expand(t); return table_newkey(t, key); } TableNode *othern = mainposition(t, mp->key); if (othern != mp) { int mindex = tindex(t, mp); while(othern->next != mindex) { othern = tnode(t, othern->next); } othern->next = tindex(t, n); *n = *mp; initnode(mp); } else { n->next = mp->next; mp->next = tindex(t, n); mp = n; } } mp->key = key; mp->flag = 'n'; return mp; }
static Tvalue *table_newkey(ktap_State *ks, Table *t, const Tvalue *key) { Node *mp; mp = mainposition(t, key); if (!isnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ if (n == NULL) { /* cannot find a free place? */ rehash(ks, t, key); /* grow table */ /* whatever called 'newkey' take care of TM cache and GC barrier */ return kp_table_set(ks, t, key); /* insert key into grown table */ } othern = mainposition(t, gkey(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ gnext(mp) = NULL; /* now `mp' is free */ setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ gnext(n) = gnext(mp); /* chain new position */ gnext(mp) = n; mp = n; } } setobj(ks, gkey(mp), key); return gval(mp); }
int luaH_findindex (lua_State *L, Table *t, StkId key) { #else static int findindex (lua_State *L, Table *t, StkId key) { #endif /* LUAPLUS_EXTENSIONS */ int i; if (ttisnil(key)) return -1; /* first iteration */ i = arrayindex(key); if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ else { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ if (luaO_rawequalObj(key2tval(n), key) || (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && gcvalue(gkey(n)) == gcvalue(key))) { i = cast_int(n - gnode(t, 0)); /* key index in hash table */ /* hash elements are numbered after array ones */ return i + t->sizearray; } else n = gnext(n); } while (n); luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ return 0; /* to avoid warnings */ } }
/* * main search function */ const Tvalue *kp_table_get(Table *t, const Tvalue *key) { switch (ttype(key)) { case KTAP_TNIL: return ktap_nilobject; case KTAP_TSHRSTR: return kp_table_getstr(t, rawtsvalue(key)); case KTAP_TNUMBER: { ktap_Number n = nvalue(key); int k = (int)n; if ((ktap_Number)k == nvalue(key)) /* index is int? */ return kp_table_getint(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ if (rawequalobj(gkey(n), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); return ktap_nilobject; } } }
/* * returns the index of a `key' for table traversals. First goes all * elements in the array part, then elements in the hash part. The * beginning of a traversal is signaled by -1. */ static int findindex(ktap_State *ks, Table *t, StkId key) { int i; if (ttisnil(key)) return -1; /* first iteration */ i = arrayindex(key); if (i > 0 && i <= t->sizearray) /* is `key' inside array part? */ return i - 1; /* yes; that's the index (corrected to C) */ else { Node *n = mainposition(t, key); for (;;) { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ if (kp_equalobjv(ks, gkey(n), key)) { i = n - gnode(t, 0); /* key index in hash table */ /* hash elements are numbered after array ones */ return i + t->sizearray; } else n = gnext(n); if (n == NULL) /* key not found */ kp_runerror(ks, "invalid key to next"); } } }
static void map_insert(struct aoi_space * space , struct map * m, uint32_t id , struct object *obj) { struct map_slot *s = mainposition(m,id); if (s->id == INVALID_ID) { s->id = id; s->obj = obj; return; } if (mainposition(m, s->id) != s) { struct map_slot * last = mainposition(m,s->id); while (last->next != s - m->slot) { assert(last->next >= 0); last = &m->slot[last->next]; } uint32_t temp_id = s->id; struct object * temp_obj = s->obj; last->next = s->next; s->id = id; s->obj = obj; s->next = -1; if (temp_obj) { map_insert(space, m, temp_id, temp_obj); } return; } while (m->lastfree >= 0) { struct map_slot * temp = &m->slot[m->lastfree--]; if (temp->id == INVALID_ID) { temp->id = id; temp->obj = obj; temp->next = s->next; s->next = (int)(temp - m->slot); return; } } rehash(space,m); map_insert(space, m, id , obj); }
static TableNode* table_get(Table *t, uint32_t key) { TableNode *n = mainposition(t, key); while(!tisnil(n)) { if(n->key == key) { return n; } if(n->next < 0) { break; } n = tnode(t, n->next); } return NULL; }
static struct object * map_query(struct aoi_space *space, struct map * m, uint32_t id) { struct map_slot *s = mainposition(m, id); for (;;) { if (s->id == id) { if (s->obj == NULL) { s->obj = new_object(space, id); } return s->obj; } if (s->next < 0) { break; } s=&m->slot[s->next]; } struct object * obj = new_object(space, id); map_insert(space, m , id , obj); return obj; }
static qdict_node_t* find_strkey(qdict_t *dict, const char *key, int *idx) { int hash; qlist_t *list, *pos; qdict_node_t *node; hash = mainposition(dict, key); if (idx != NULL) { *idx = hash; } list = &(dict->buckets[hash]); qlist_for_each(pos, list) { node = qlist_entry(pos, qdict_node_t, entry); if (!qvalue_isstring(&(node->key))) { continue; } if (qstring_compare(node->key.data.str, key, strlen(key)) == 0) { return node; } }
static Node *mainpositionTV (const Table *t, const TValue *key) { return mainposition(t, rawtt(key), valraw(key)); }