bool hashtable_insert(struct HashTable *self, const T *value) { // Calculate the hash of the value size_t hash = self->hash_function(value); // Calculate the index in the table where the value should be inserted size_t index = hash % self->size; // Check if the key already exists in the table for (struct HashTableNode *node = self->table[index]; node != NULL; node = node->next) { if (self->compare(node->value, value) == 0) { // Key already exists in the table, do not insert return false; } } // Key does not exist in the table, insert the value struct HashTableNode *new_node = malloc(sizeof(struct HashTableNode)); new_node->value = value; new_node->next = self->table[index]; self->table[index] = new_node; // Increment the number of elements in the table self->num_elements++; // Check if the table needs to be resized if (self->num_elements > self->max_load_factor * self->size) { hashtable_resize(self, 2.0); } return true; }