// 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; }
// 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 **) ¤t); 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; }
// 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; }
int HTIteratorGet(HTIter iter, HTKeyValue *keyvalue) { if (!iter->is_valid || iter->ht->num_elements == 0) return 0; HTKeyValuePtr payload; LLIteratorGetPayload(iter->bucket_it, (void**) &payload); *keyvalue = *payload; return 1; }
// This prints the searchresult from list static void printResult(DocTable table, LinkedList list) { LLIter it = LLMakeIterator(list, 0); SearchResultPtr searchResult; do { LLIteratorGetPayload(it, (LLPayload_t*)&searchResult); printf(" %s (%d)\n", DTLookupDocID(table, searchResult->docid), searchResult->rank); } while (LLIteratorNext(it)); LLIteratorFree(it); FreeLinkedList(list, free); }
int HTIteratorGet(HTIter iter, HTKeyValue *keyvalue) { Verify333(iter != NULL); // Step 6 -- implement HTIteratorGet. if (HTIteratorPastEnd(iter)) { // The iterator is past the end or it is invalid. return 0; } HTKeyValuePtr getpayload = NULL; LLIteratorGetPayload(iter->bucket_it, (void **) &getpayload); *keyvalue = *getpayload; return 1; }
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; }
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 char input[1024]; char *token; char *saveptr; DocTable doctable; MemIndex index; LinkedList searchresult; LLIter llit; SearchResult *rs; printf("Indexing \'%s\'\n", argv[1]); // crawl from directory argv[1] if (CrawlFileTree(argv[1], &doctable, &index) == 0) { // terminate the program if crawl failed Usage(); } Assert333(doctable != NULL); Assert333(index != NULL); while (1) { // ask for user input printf("enter query:\n"); if (fgets(input, 1024, stdin) != NULL) { // malloc space in order to store tokens // split from user input char **query = (char **) malloc(512 * sizeof(char *)); Assert333(query != NULL); uint8_t qlen = 0; char *str = input; // whenever we see the space in the input, split it // and store it into array while (1) { token = strtok_r(str, " ", &saveptr); // jump out of loop if there are no more tokens if (token == NULL) break; query[qlen] = token; qlen++; str = NULL; } // replace last token's '\n' by '\0' since fgets // also read '\n' into input char *p = strchr(query[qlen - 1], '\n'); if (p) *p = '\0'; // search for the documents that contains // all the words in the query searchresult = MIProcessQuery(index, query, qlen); if (searchresult != NULL) { llit = LLMakeIterator(searchresult, 0); Assert333(llit != NULL); // print out all the matching documents under // the directory argv[1] and the rank for the query do { LLIteratorGetPayload(llit, (void **) &rs); printf(" %s (%u)\n", DTLookupDocID(doctable, rs->docid), rs->rank); } while (LLIteratorNext(llit)); LLIteratorFree(llit); } free(query); } } FreeDocTable(doctable); FreeMemIndex(index); return EXIT_SUCCESS; }