Example #1
0
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;
}
Example #3
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;
}
Example #4
0
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;
}