/** * Function to add a key - value pair to the hash table, use HT_ADD macro * @param table hash table to add element to * @param key pointer to the key for the hash table * @param key_len length of the key in bytes * @param value pointer to the value to be added against the key * @param value_len length of the value in bytes * @returns 0 on sucess * @returns -1 when no memory */ int hash_table_add(hash_table_t * table, void * key, size_t key_len, void * value, size_t value_len) { size_t hash = HASH(key, key_len); hash_table_element_t * element = hash_table_element_new(); if (!element) { INFO("Cannot allocate memory for element"); return -1; // No Memory } if (table->mode == MODE_COPY) { LOG("Adding a key-value pair to the hash table with hash -> %d, in COPY MODE", (int)hash); element->key = malloc(key_len); element->value = malloc(value_len); if (element->key && element->value) { memcpy(element->key, key, key_len); memcpy(element->value, value, value_len); } else { if (element->key) { free(element->key); INFO("Cannot allocate memory for value"); } if (element->value) { free(element->value); INFO("Cannot allocate memory for key"); } free(element); return -1; //No Memory } } else if (table->mode == MODE_VALUEREF) { LOG("Adding a key-value pair to the hash table with hash -> %d, in VALUEREF MODE", (int)hash); element->key = malloc(key_len); if (element->key) { memcpy(element->key, key, key_len); } else { INFO("Cannot allocate memory for key"); free(element); return -1; //No Memory } element->value = value; } element->key_len = key_len; element->value_len = value_len; element->next = NULL; // find the key position for chaining if (!table->store_house[hash]) { LOG("No Conflicts adding the first element at %d", (int)hash); table->store_house[hash] = element; table->key_count++; } else { LOG("Conflicts adding element at %d", (int)hash); hash_table_element_t * temp = table->store_house[hash]; while(temp->next) { while(temp->next && temp->next->key_len!=key_len) { temp = temp->next; } if(temp->next) { if (!memcmp(temp->next->key, key, key_len)) { LOG("Found Key at hash -> %d", (int)hash); hash_table_element_t *to_delete = temp->next; temp->next = element; element->next = to_delete->next; hash_table_element_delete(table, to_delete); // since we are replacing values no need to change key_count return 0; } else { temp = temp->next; } } } temp->next = element; table->key_count++; } return 0; }
/** * Function to add a key - value pair to the hash table, use HT_ADD macro * @param table hash table to add element to * @param key pointer to the key for the hash table * @param key_len length of the key in bytes * @param value pointer to the value to be added against the key * @param value_len length of the value in bytes * @returns 0 on sucess * @returns -1 when no memory */ int _cdecl hash_table_add(hash_table_t * table, void * key, size_t key_len, void * value, size_t value_len) { size_t hash; hash_table_element_t * element; if ((table->key_count / table->key_num) >= table->key_ratio) { print_info("Ratio(%d) reached the set limit %d\nExpanding hash_table\n", (table->key_count / table->key_num), table->key_ratio); hash_table_resize(table, table->key_num*2); //exit(0); } hash = HASH(key, key_len); element = hash_table_element_new(); if (!element) { print_info("Cannot allocate memory for element\n"); return -1; // No Memory } if (table->mode == MODE_COPY) { print_info("Adding a key-value pair to the hash table with hash -> %d, in COPY MODE\n", (int)hash); element->key = malloc(key_len); element->value = malloc(value_len); if (element->key && element->value) { memcpy(element->key, key, key_len); memcpy(element->value, value, value_len); } else { if (element->key) { free(element->key); print_info("Cannot allocate memory for value\n"); } if (element->value) { free(element->value); print_info("Cannot allocate memory for key\n"); } free(element); return -1; //No Memory } } else if (table->mode == MODE_VALUEREF) { print_info("Adding a key-value pair to the hash table with hash -> %d, in VALUEREF MODE\n", (int)hash); element->key = malloc(key_len); if (element->key) { memcpy(element->key, key, key_len); } else { print_info("Cannot allocate memory for key\n"); free(element); return -1; //No Memory } element->value = value; } else if (table->mode == MODE_ALLREF) { print_info("Adding a key-value pair to the hash table with hash -> %d, in ALLREF MODE\n", (int)hash); element->key = key; element->value = value; } element->key_len = key_len; element->value_len = value_len; element->next = NULL; // find the key position for chaining if (!table->store_house[hash]) { print_info("No Conflicts adding the first element at %d\n", (int)hash); table->store_house[hash] = element; table->key_count++; } else { hash_table_element_t * temp = table->store_house[hash]; print_info("Conflicts adding element at %d\n", (int)hash); while(temp->next) { while(temp->next && temp->next->key_len!=key_len) { temp = temp->next; } if(temp->next) { if (!memcmp(temp->next->key, key, key_len)) { hash_table_element_t *to_delete = temp->next; print_info("Found Key at hash -> %d\n", (int)hash); temp->next = element; element->next = to_delete->next; hash_table_element_delete(table, to_delete); // since we are replacing values no need to change key_count return 0; } else { temp = temp->next; } } } temp->next = element; table->key_count++; } return 0; }