Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "index.h"
- struct index
- {
- map_t *map;
- };
- /*
- * Creates a new, empty index.
- */
- index_t *index_create()
- {
- index_t *index = malloc(sizeof(index_t));
- if (index == NULL)
- fatal_error("out of memory");
- index->map = map_create(compare_strings, hash_string);
- return index;
- }
- /*
- * Destroys the given index. Subsequently accessing the index will
- * lead to undefined behavior.
- */
- void index_destroy(index_t *index)
- {
- map_destroy(index->map, NULL, NULL);
- free(index);
- }
- /*
- * Adds the given path to the given index, and index the given
- * list of words under that path.
- * NOTE: It is the responsibility of index_addpath() to deallocate (free)
- * 'path' and the contents of the 'words' list.
- */
- void index_addpath(index_t *index, char *path, list_t *words)
- {
- list_iter_t *iter = list_createiter(words);
- while(list_hasnext(iter))
- {
- char *setwords = list_next(iter);
- if (!map_haskey(index->map, setwords))
- {
- set_t *new = set_create(compare_strings);
- set_add(new, path);
- map_put(index->map, setwords, new);
- }
- else
- {
- set_t *new = map_get(index->map, setwords);
- set_add(new, path);
- }
- }
- list_destroyiter(iter);
- }
- typedef enum{
- ANDNOT, AND, OR, P_WORD
- }node_type;
- typedef struct parser parser_t;
- struct parser{
- node_type type;
- char *word;
- parser_t *left;
- parser_t *right;
- };
- static parser_t *newnode(node_type type, char *word, parser_t *left, parser_t *right)
- {
- parser_t *parser = malloc(sizeof(parser_t));
- if (parser == NULL)
- fatal_error("out of memory");
- parser->type = type;
- parser->word = word;
- parser->left = left;
- parser->right = right;
- return parser;
- }
- static parser_t *handle_query(list_t *query);
- static parser_t *handle_query_and(list_t *query);
- static parser_t *handle_query_or(list_t *query);
- static parser_t *handle_query_term(list_t *query);
- static parser_t *handle_query_word(list_t *query);
- /*
- static parser_t *handle_query(list_t *query)
- {
- if(list_size(query) == 0)
- return NULL;
- parser_t *b;
- parser_t *a = handle_query_and(query);
- if (list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if(!strcmp(word, "ANDNOT"))
- {
- b = handle_query(query);
- return newnode(ANDNOT, NULL, a, b);
- }
- else
- {
- printf("kjører dette? ANDNOT\n");
- list_addfirst(query, word);
- }
- }
- else
- {
- printf("returner a ANDNOT\n");
- return a;
- }
- }
- */
- static parser_t *handle_query(list_t *query)
- {
- {
- if(list_size(query) == 0)
- return NULL;
- parser_t *b, *a = handle_query_and(query);
- if(list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if (!strcmp(word, "ANDNOT"))
- {
- b = handle_query(query);
- return newnode(ANDNOT, NULL, a, b);
- }
- else
- {
- printf("kjører dette? ANDNOT\n");
- list_addfirst(query, word);
- return a;
- }
- }
- else
- {
- printf("returner a ANDNOT\n");
- return a;
- }
- }
- }
- /*
- static parser_t *handle_query_and(list_t *query)
- {
- if(list_size(query) == 0)
- return NULL;
- parser_t *b;
- parser_t *a = handle_query_or(query);
- if(list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if (!strcmp(word, "AND"))
- {
- b = handle_query_and(query);
- printf("Inne i AND\n");
- if (a == NULL)
- printf("a failet\n");
- if (b == NULL)
- printf("b failet\n");
- if (a == b)
- printf("a og b er det samme\n");
- return newnode(AND, NULL, a, b);
- }
- else{
- printf("kjører dette? AND\n");
- list_addfirst(query, word);
- }
- }
- else
- {
- printf("returner a AND\n");
- return a;
- }
- }
- */
- static parser_t *handle_query_and(list_t *query)
- {
- {
- if(list_size(query) == 0)
- return NULL;
- parser_t *b, *a = handle_query_or(query);
- if(list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if (!strcmp(word, "AND"))
- {
- b = handle_query_and(query);
- return newnode(AND, NULL, a, b);
- }
- else
- {
- printf("kjører dette? AND\n");
- list_addfirst(query, word);
- return a;
- }
- }
- else
- {
- printf("returner a AND\n");
- return a;
- }
- }
- }
- static parser_t *handle_query_or(list_t *query)
- {
- if(list_size(query) == 0)
- return NULL;
- parser_t *b, *a = handle_query_term(query);
- if(list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if (!strcmp(word, "OR"))
- {
- b = handle_query_or(query);
- return newnode(OR, NULL, a, b);
- }
- else
- {
- printf("kjører dette? OR\n");
- list_addfirst(query, word);
- return a;
- }
- }
- else
- {
- printf("returner a OR\n");
- return a;
- }
- }
- static parser_t *handle_query_term(list_t *query)
- {
- if (list_size(query) == 0)
- return NULL;
- parser_t *a;
- if(list_size(query) > 0)
- {
- char *word = list_popfirst(query);
- if(!strcmp(word, "("))
- {
- a = handle_query(query);
- if(!strcmp(word, ")"))
- a = handle_query(query);
- else
- fatal_error("missing )");
- }
- else
- {
- printf("kjører dette? TERM\n");
- list_addfirst(query, word);
- return handle_query_word(query);
- }
- }
- else
- {
- printf("returener word\n");
- return handle_query_word(query);
- }
- }
- static parser_t *handle_query_word(list_t *query)
- {
- if(list_size(query) == 0)
- return NULL;
- if (list_size(query) > 0)
- {
- printf("Kjører WORD\n");
- char *word = list_popfirst(query);
- return newnode(P_WORD, word, NULL, NULL);
- }
- }
- static set_t *evaluate(parser_t *node, index_t *index)
- {
- set_t *left;
- set_t *right;
- switch(node->type)
- {
- case ANDNOT:
- left = map_get(index->map, node->left->word);
- right = map_get(index->map, node->right->word);
- return set_difference(left, right);
- case AND:
- left = map_get(index->map, node->left->word);
- right = map_get(index->map, node->right->word);
- return set_intersection(left, right);
- case OR:
- left = map_get(index->map, node->left->word);
- right = map_get(index->map, node->right->word);
- return set_union(left, right);
- case P_WORD:
- left = map_get(index->map, node->word);
- return left;
- }
- fatal_error("Unknown node type");
- return NULL;
- }
- /*
- * Performs the given query on the given index. If the query
- * succeeds, the return value will be a list of paths. If there
- * is an error (e.g. a syntax error in the query), an error message
- * is assigned to the given errmsg pointer and the return value
- * will be NULL.
- */
- list_t *index_query(index_t *index, list_t *query, char **errmsg)
- {
- list_t *new = list_create(compare_strings);
- query_result_t *final_result;
- parser_t *result = handle_query(query);
- set_t *set = evaluate(result, index);
- set_iter_t *set_iter = set_createiter(set);
- while (set_hasnext(set_iter))
- {
- final_result = malloc(sizeof(query_result_t));
- if (final_result == NULL)
- fatal_error("out of memory");
- final_result->path = set_next(set_iter);
- final_result->score = 0;
- list_addlast(new, final_result);
- }
- return new;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement