int InsertHashTable(HashTable table, HTKeyValue newkeyvalue, HTKeyValue *oldkeyvalue) { uint32_t insertBucket; LinkedList insertChain; int ret = 0; //Lock for writing! sem_wait(&table->wrt); ResizeHashtable(table); // calculate which bucket we're inserting into, // grab its linked list chain insertBucket = HashKeyToBucketNum(table, newkeyvalue.key); insertChain = table->buckets[insertBucket]; HTKeyValuePtr found; int success = find(insertChain, newkeyvalue.key, false, NULL, &found); if (success == -1) { // out of memory ret = 0; goto cleanup; } if (success == 0) { // inserting this key for the first time table->num_elements++; HTKeyValuePtr newEntry = (HTKeyValuePtr) malloc(sizeof(HTKeyValue)); if (newEntry == NULL) { // out of memory ret = 0; goto cleanup; } *newEntry = newkeyvalue; ret = PushLinkedList(insertChain, newEntry); goto cleanup; } else { // replace value for keyvalue already in HT *oldkeyvalue = *found; found->value = newkeyvalue.value; ret = 2; goto cleanup; } cleanup: sem_post(&table->wrt); return ret; }
int InsertHashTable(HashTable table, HTKeyValue newkeyvalue, HTKeyValue *oldkeyvalue) { HWSize_t insertbucket; LinkedList insertchain; Verify333(table != NULL); ResizeHashtable(table); // calculate which bucket we're inserting into, // grab its linked list chain insertbucket = HashKeyToBucketNum(table, newkeyvalue.key); insertchain = table->buckets[insertbucket]; // Step 1 -- finish the implementation of InsertHashTable. // This is a fairly complex task, so you might decide you want // to define/implement a helper function that helps you find // and optionally remove a key within a chain, rather than putting // all that logic inside here. You might also find that your helper // can be reused in steps 2 and 3. HTKeyValue *newnode = (HTKeyValue *) malloc(sizeof(HTKeyValue)); if (newnode == NULL) { // Error, out of memory. return 0; } *newnode = newkeyvalue; int searchresult = SearchKey(insertchain, newnode->key, oldkeyvalue, 1); if (searchresult != 0 && PushLinkedList(insertchain, newnode)) { // Successfully inserted. if (searchresult == 1) { // The key is not in the list yet. table->num_elements++; } // If the key has a duplication in the list, nothing to do, // since return value is searchresult = 2 // and "oldkeyvalue" is updated by SearchKey. return searchresult; } // Insertion failed. free(newnode); return 0; }