static void table_expand(Table *t) { int capacity = t->capacity; TableNode *node = t->node; t->capacity = t->capacity * 2; t->node = (TableNode*)calloc(t->capacity, sizeof(TableNode)); int i; for(i=0; i<t->capacity; i++) { initnode(t->node + i); } t->lastfree = t->node + (t->capacity - 1); for(i=0; i< capacity; i++) { TableNode *old = node + i; if(tisnil(old)) { continue; } TableNode *new_node = table_newkey(t, old->key); new_node->flag = old->flag; new_node->value = old->value; } // free old node free(node); }
/* ** 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 TableNode* table_insert(Table *t, uint32_t key) { TableNode *node = table_get(t, key); if(node) { return node; } return table_newkey(t, key); }
Tvalue *kp_table_set(ktap_State *ks, Table *t, const Tvalue *key) { const Tvalue *p = kp_table_get(t, key); if (p != ktap_nilobject) return (Tvalue *)p; else return table_newkey(ks, t, key); }
void kp_table_setint(ktap_State *ks, Table *t, int key, Tvalue *v) { const Tvalue *p = kp_table_getint(t, key); Tvalue *cell; if (p != ktap_nilobject) cell = (Tvalue *)p; else { Tvalue k; setnvalue(&k, key); cell = table_newkey(ks, t, &k); } setobj(ks, cell, v); }