Exemplo n.º 1
0
// 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;
}
Exemplo n.º 2
0
void FreeHashTable(HashTable table,
                   ValueFreeFnPtr value_free_function) {
  HWSize_t i;

  Verify333(table != NULL);  // be defensive

  // loop through and free the chains on each bucket
  for (i = 0; i < table->num_buckets; i++) {
    LinkedList  bl = table->buckets[i];
    HTKeyValue *nextKV;

    // pop elements off the the chain list, then free the list
    while (NumElementsInLinkedList(bl) > 0) {
      Verify333(PopLinkedList(bl, (LLPayload_t*)&nextKV));
      value_free_function(nextKV->value);
      free(nextKV);
    }
    // the chain list is empty, so we can pass in the
    // null free function to FreeLinkedList.
    FreeLinkedList(bl, LLNullFree);
  }

  // free the bucket array within the table record,
  // then free the table record itself.
  free(table->buckets);
  free(table);
}
Exemplo n.º 3
0
int HTIteratorNext(HTIter iter) {
  Verify333(iter != NULL);

  // Step 4 -- implement HTIteratorNext.
  if (iter->bucket_it != NULL && LLIteratorNext(iter->bucket_it)) {
    // Best case that we can just move on the iterator.
    return 1;
  }

  // Search the next bucket to iterate.
  int currentbucket = iter->bucket_num + 1;
  while (currentbucket < iter->ht->num_buckets &&
          NumElementsInLinkedList(iter->ht->buckets[currentbucket]) == 0) {
    currentbucket++;
  }

  if (currentbucket < iter->ht->num_buckets) {
    // A valid bucket is found, free old iterator and make a new one.
    LLIteratorFree(iter->bucket_it);
    iter->bucket_num = currentbucket;
    iter->bucket_it = LLMakeIterator(iter->ht->buckets[iter->bucket_num], 0);

    if (iter->bucket_it == NULL) {
      // Error occurs (e.g., out of memory).
      return 0;
    }
    return 1;
  }

  // The iterator (after moving it forward) is past the
  //   end of the table.
  iter->is_valid = false;

  return 0;
}
Exemplo n.º 4
0
// Search in the list, find if there already exist the given key.
//
// Arguments:
//
// - list: The list we will search the key in.
//
// - key: The key that we will search in the list.
//
// - oldkeyvalue: If such a key is already exist in the list,
//                 then the old key/value is returned via this return
//                  parameter to the caller.
//
// - operation: Delete the found exist old key/value and
//                   free the payload (value) if operation == 1.
//              Remains the same if operation == 0.
//
// Returns:
//
// - 0 on failure (e.g., out of memory).
//
// - +1 if a key is NOT found exist in the list.
//
// - +2 if a key is found exist in the list.
static int SearchKey(LinkedList list, HTKey_t key,
                        HTKeyValue *oldkeyvalue, int operation) {
  if (NumElementsInLinkedList(list) == 0) {
    // The given list is empty.
    return 1;
  }

  LLIter iter = LLMakeIterator(list, 0);
  if (iter == NULL) {
    // Fail to make an iterator (e.g., out of memory).
    return 0;
  }
  int status = 1;
  HTKeyValuePtr current = NULL;
  do {
    LLIteratorGetPayload(iter, (void **) &current);
    if (current->key == key) {
      // Found such key is exist in the list.
      *oldkeyvalue = *current;
      if (operation == 1) {
        // Delete the Node and free the payload.
        LLIteratorDelete(iter, &LLNullFree);
        free(current);
      }
      status = 2;
      break;
    }
  } while (LLIteratorNext(iter));
  LLIteratorFree(iter);
  // Not found, return 1.
  return status;
}
Exemplo n.º 5
0
LLIter LLMakeIterator(LinkedList list, int pos) {
  // defensive programming
  Verify333(list != NULL);
  Verify333((pos == 0) || (pos == 1));

  // if the list is empty, return failure.
  if (NumElementsInLinkedList(list) == 0U)
    return NULL;

  // OK, let's manufacture an iterator.
  LLIter li = (LLIter) malloc(sizeof(LLIterSt));
  if (li == NULL) {
    // out of memory!
    return NULL;
  }

  // set up the iterator.
  li->list = list;
  if (pos == 0) {
    li->node = list->head;
  } else {
    li->node = list->tail;
  }

  // return the new iterator
  return li;
}
Exemplo n.º 6
0
void FreeHashTable(HashTable table,
                   ValueFreeFnPtr value_free_function) {
  uint32_t i;

  // loop through and free the chains on each bucket
  for (i = 0; i < table->num_buckets; i++) {
    LinkedList  bl = table->buckets[i];
    HTKeyValue *nextKV;

    PopLinkedList(bl, (void **) &nextKV);
    // pop elements off the the chain list, then free the list
    while (NumElementsInLinkedList(bl) > 0) {
      value_free_function(nextKV->value);
      free(nextKV);
    }
    // the chain list is empty, so we can pass in the
    // null free function to FreeLinkedList.
    FreeLinkedList(bl, NullFree);
  }

  // free the bucket array within the table record,
  // then free the table record itself.
  free(table->buckets);
  free(table);
}
Exemplo n.º 7
0
int HTIteratorNext(HTIter iter) {
  if (!iter->is_valid)
    return 0;

  // progress to next element in ll if possible
  if (iter != NULL && LLIteratorHasNext(iter->bucket_it))
    return LLIteratorNext(iter->bucket_it);

  // search until finds non-empty chain or invalid bucket
  LLIter oldListIter = iter->bucket_it;
  LinkedList nextChain;
  do {
    iter->bucket_num++;
    if (iter->bucket_num >= iter->ht->num_buckets) {
      iter->is_valid = false;
      return 0;
    }
    nextChain = iter->ht->buckets[iter->bucket_num];
  } while (NumElementsInLinkedList(nextChain) == 0);

  // reset list iterator
  LLIteratorFree(oldListIter);
  iter->bucket_it = LLMakeIterator(nextChain, 0UL);
  return 1;
}
Exemplo n.º 8
0
// Searches for an HTKeyValue pair stored in 'list' with a key equal to
// 'targetkey'. If 'remove' is true, the element will be removed from the list,
// the HTKeyValue freed, and the dereferenced value of 'found' set to the value
// of the found HTKeyValue. Otherwise, the dereferenced value of 'foundPtr' is
// set to the found HTKeyValue in memory, and list is left unmodified.
// Returns 1 if found, 0 if not found, -1 if memory error.
static int find(LinkedList list, uint64_t targetKey, bool remove,
                HTKeyValuePtr found, HTKeyValuePtr* foundPtr) {
  LLIter iter = LLMakeIterator(list, 0);
  if (iter == NULL && NumElementsInLinkedList(list) > 0)
    return -1;  // memory error
  if (iter == NULL)
    return 0;  // empty list

  bool next = true;
  while (next) {
    HTKeyValuePtr payload;
    LLIteratorGetPayload(iter, (void**) &payload);
    if ((payload->key == targetKey)) {
      // target found in list
      if (found != NULL)
        *found = *payload;
      if (remove) {
        free(payload);
        LLIteratorDelete(iter, NullFree);
      }
      LLIteratorFree(iter);
      if (foundPtr != NULL)
        *foundPtr = payload;
      return 1;
    }
    next = LLIteratorNext(iter);
  }
  // target not found in list
  LLIteratorFree(iter);
  return 0;
}
Exemplo n.º 9
0
HTIter HashTableMakeIterator(HashTable table) {
  HTIterRecord *iter;
  HWSize_t      i;

  Verify333(table != NULL);  // be defensive

  // malloc the iterator
  iter = (HTIterRecord *) malloc(sizeof(HTIterRecord));
  if (iter == NULL) {
    return NULL;
  }

  // if the hash table is empty, the iterator is immediately invalid,
  // since it can't point to anything.
  if (table->num_elements == 0) {
    iter->is_valid = false;
    iter->ht = table;
    iter->bucket_it = NULL;
    return iter;
  }

  // initialize the iterator.  there is at least one element in the
  // table, so find the first element and point the iterator at it.
  iter->is_valid = true;
  iter->ht = table;
  for (i = 0; i < table->num_buckets; i++) {
    if (NumElementsInLinkedList(table->buckets[i]) > 0) {
      iter->bucket_num = i;
      break;
    }
  }
  Verify333(i < table->num_buckets);  // make sure we found it.
  iter->bucket_it = LLMakeIterator(table->buckets[iter->bucket_num], 0UL);
  if (iter->bucket_it == NULL) {
    // out of memory!
    free(iter);
    return NULL;
  }
  return iter;
}
Exemplo n.º 10
0
int main(int argc, char **argv) {
  if (argc != 2)
    Usage();

// Implement searchshell!  We're giving you very few hints
// on how to do it, so you'll need to figure out an appropriate
// decomposition into functions as well as implementing the
// functions.  There are several major tasks you need to build:
//
//  - crawl from a directory provided by argv[1] to produce and index
//  - prompt the user for a query and read the query from stdin, in a loop
//  - split a query into words (check out strtok_r)
//  - process a query against the index and print out the results
//
// When searchshell detects end-of-file on stdin (cntrl-D from the
// keyboard), searchshell should free all dynamically allocated
// memory and any other allocated resources and then exit.

  DocTable doctable;
  MemIndex index;
  int qlen, res;
  char *query[128];
  char *input = (char*) malloc(128);
  char *token;
  char *check;
  char *saveptr;
  LinkedList retlist;
  LLIter llit;
  SearchResult *sres;
  char *name;


  // crawls the directory
  printf("Indexing '%s'\n", argv[1]);
  // gets the doctable and inverted index table
  res = CrawlFileTree(argv[1], &doctable, &index);
  if (res == 0) {  // encounters error
    Usage();
  }

  while (1) {
    printf("enter query:\n");
    // when the user types control-D
    if (fgets(input, 128, stdin) == NULL) {
      printf("shutting down...\n");
      break;
    }
    qlen = 0;

    // gets the first token
    token = strtok_r(input, " ", &saveptr);
    // stores the token in the array
    while (token != NULL) {
      query[qlen] = token;
      qlen++;
      token = strtok_r(NULL, " ", &saveptr);
    }
    // changes \n to \0
    check = strchr(query[qlen - 1], '\n');
    if (check != NULL) {
      *check = '\0';
    }

    // gets the result linkedlist
    retlist = MIProcessQuery(index, query, qlen);
    if (retlist != NULL && NumElementsInLinkedList(retlist) != 0) {
      // iterates through the list and print
      llit = LLMakeIterator(retlist, 0);
      Verify333(llit != NULL);
      do {
        // prints the result from the iterator
        LLIteratorGetPayload(llit, (void **)&sres);
        name = DTLookupDocID(doctable, sres->docid);
        printf("  %s  (%d)\n", name, sres->rank);
      } while (LLIteratorNext(llit));

      LLIteratorFree(llit);  // free the iterator
      FreeLinkedList(retlist, free);  // free the linked list
    }
  }

  free(input);
  FreeDocTable(doctable);
  FreeMemIndex(index);
  return EXIT_SUCCESS;
}