void _HashMapReHash(HashMapData* data) { unsigned num_slot_new; /* Consume the next prime for slot array extension. */ if (likely(data->idx_prime_ < (num_prime - 1))) { ++(data->idx_prime_); num_slot_new = magic_primes[data->idx_prime_]; } /* If the prime list is completely consumed, we simply extend the slot array with treble capacity.*/ else { data->idx_prime_ = num_prime; num_slot_new = data->num_slot_ * 3; } /* Try to allocate the new slot array. The rehashing should be canceled due to insufficient memory space. */ SlotNode** arr_slot_new = (SlotNode**)malloc(sizeof(SlotNode*) * num_slot_new); if (unlikely(!arr_slot_new)) { if (data->idx_prime_ < num_prime) --(data->idx_prime_); return; } unsigned i; for (i = 0 ; i < num_slot_new ; ++i) arr_slot_new[i] = NULL; HashMapHash func_hash = data->func_hash_; SlotNode** arr_slot = data->arr_slot_; unsigned num_slot = data->num_slot_; for (i = 0 ; i < num_slot ; ++i) { SlotNode* pred; SlotNode* curr = arr_slot[i]; while (curr) { pred = curr; curr = curr->next_; /* Migrate each key value pair to the new slot. */ unsigned hash = func_hash(pred->pair_.key); hash = hash % num_slot_new; if (!arr_slot_new[hash]) { pred->next_ = NULL; arr_slot_new[hash] = pred; } else { pred->next_ = arr_slot_new[hash]; arr_slot_new[hash] = pred; } } } free(arr_slot); data->arr_slot_ = arr_slot_new; data->num_slot_ = num_slot_new; data->curr_limit_ = (unsigned)((double)num_slot_new * load_factor); return; }
void hash_set(hash_table_t *table, node_t *key, node_t *value) { //*key is function name. *value is arguments of function. int bucket = 0; //value of func_hash /*entry に 関数名key と関数の引数リストvalueを代入。*/ hash_entry_t *entry = (hash_entry_t*) malloc (sizeof (hash_entry_t)); entry->key = (const char*) malloc (sizeof (strlen (key->car->character))+1); strcpy ((char*)entry->key, key->car->character); // 関数名を entry の key にコピーする。 entry->value = copy_node ( value ); // ( x y ) (+ x y)引数のリストをコピーする。 bucket = func_hash ( entry->key ); //table の bucket番目のentryに入れる。 table->entry[bucket] = entry; //stack. table->entry[bucket]->next = top[bucket]; top[bucket] = table->entry[bucket]; }
opline_t *hash_search_vm(hash_table_t *table, node_t *node) { //tableの中のentryに連結されているのを探索する。(keyが違うのにvalueが等しい場合があるのでそれを防止する) int bucket = 0; hash_entry_t *p; bucket = func_hash (node->character); //対応するものを見つけたらそのkey(関数名)に対応するvalue(引数)を返す。 for (p = table->entry[bucket]; p != NULL; p = p->next) { if (strcmp (node->character, p->key) == 0){ return p->vm_code; } } return NULL; //対応するものが見つからなかったらNULLを返す }
void hash_set_args (hash_table_t *table, node_t *key, int index ) { int bucket = 0; //value of func_hash /*entry に 関数の引数key とindexを代入。*/ hash_entry_t *entry = (hash_entry_t*) malloc ( sizeof (hash_entry_t) ); entry->key = (const char*) malloc (sizeof (strlen (key->car->character))+1); entry->vm_code = (opline_t*) malloc (sizeof (opline_t) ); strcpy ((char*)entry->key, key->car->character); // 関数名を entry の key にコピーする。 entry->vm_code->type = PUSH_V; entry->vm_code->op = index; entry->vm_code->next = NULL; bucket = func_hash ( entry->key ); //table の bucket番目のentryに入れる。 table->entry[bucket] = entry; //stack. table->entry[bucket]->next = top[bucket]; top[bucket] = table->entry[bucket]; }
void hash_set_vm (hash_table_t *table, node_t *key, opline_t *function ) { int bucket = 0; //value of func_hash /*entry に 関数の引数key とindexを代入。*/ hash_entry_t *entry = (hash_entry_t*) malloc ( sizeof (hash_entry_t) ); entry->key = (const char*) malloc (sizeof (strlen (key->car->character))+1); strcpy ((char*)entry->key, key->car->character); // 関数名を entry の key にコピーする。 entry->vm_code = (opline_t*) malloc (sizeof (opline_t) ); entry->vm_code->type =function->type; entry->vm_code->op = function->op; entry->vm_code->next = function->next; // entry->vm_code = function; bucket = func_hash ( entry->key ); //table の bucket番目のentryに入れる。 table->entry[bucket] = entry; //stack. table->entry[bucket]->next = top[bucket]; top[bucket] = table->entry[bucket]; printf("table->entry[%d]->key = %s\n",bucket,table->entry[bucket]->key); }