bool LLIteratorInsertBefore(LLIter iter, LLPayload_t payload) { // defensive programming Verify333(iter != NULL); Verify333(iter->list != NULL); Verify333(iter->node != NULL); // If the cursor is pointing at the head, use our // PushLinkedList function. if (iter->node == iter->list->head) { return PushLinkedList(iter->list, payload); } // General case: we have to do some splicing. LinkedListNodePtr newnode = (LinkedListNodePtr) malloc(sizeof(LinkedListNode)); if (newnode == NULL) return false; // out of memory newnode->payload = payload; newnode->next = iter->node; newnode->prev = iter->node->prev; newnode->prev->next = newnode; newnode->next->prev = newnode; iter->list->num_elements += 1; return true; }
// our main function; here, we demonstrate how to use some // of the linked list functions. int main(int argc, char **argv) { ExamplePayloadPtr payload; LinkedListPtr list; LLIterPtr iter; int i; // allocate a list list = AllocateLinkedList(); assert(list != NULL); // insert 100 elements for (i = 0; i < 100; i++) { payload = (ExamplePayloadPtr) malloc(sizeof(ExamplePayload)); assert(payload != NULL); payload->num = i; assert(PushLinkedList(list, (void *) payload) == 1); // make sure our list total is correct assert(NumElementsInLinkedList(list) == i+1); } // sort the list in descending order SortLinkedList(list, 0, &ExamplePayloadComparator); // pop off the first element assert(PopLinkedList(list, (void **) &payload) == 1); assert(payload->num == 99); assert(NumElementsInLinkedList(list) == 99); free(payload); // slice off the last element assert(SliceLinkedList(list, (void **) &payload) == 1); assert(payload->num == 0); assert(NumElementsInLinkedList(list) == 98); free(payload); // make an iterator from the head iter = LLMakeIterator(list, 0); assert(iter != NULL); // peek at the current iterator payload LLIteratorGetPayload(iter, (void **) &payload); assert(payload->num == 98); // move the iterator, peek at next payload assert(LLIteratorNext(iter) == 1); LLIteratorGetPayload(iter, (void **) &payload); assert(payload->num == 97); // free the iterator LLIteratorFree(iter); // free the linked list FreeLinkedList(list, &ExamplePayloadFree); return 0; }
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; }